diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5d317d0bb2..06ca3317b7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,7 +26,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - go: ['1.23', '1.24'] + go: ['1.23', '1.24.9'] steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 @@ -274,6 +274,20 @@ jobs: --health-interval 10s --health-timeout 5s --health-retries 5 + ydb: + image: ydbplatform/local-ydb:trunk + env: + GRPC_TLS_PORT: 2135 + GRPC_PORT: 2136 + MON_PORT: 8765 + ports: + - 2136:2136 + - 8765:8765 + options: >- + --hostname localhost + --platform linux/amd64 + --health-cmd "true" + --health-start-period 30s steps: - uses: actions/checkout@v4 - uses: actions/setup-go@v5 @@ -476,6 +490,20 @@ jobs: --health-interval 10s --health-timeout 5s --health-retries 5 + ydb: + image: ydbplatform/local-ydb:trunk + env: + GRPC_TLS_PORT: 2135 + GRPC_PORT: 2136 + MON_PORT: 8765 + ports: + - 2136:2136 + - 8765:8765 + options: >- + --hostname localhost + --platform linux/amd64 + --health-cmd "true" + --health-start-period 30s steps: - uses: actions/checkout@v4 with: diff --git a/dialect/dialect.go b/dialect/dialect.go index 3378463480..270b0cfe33 100644 --- a/dialect/dialect.go +++ b/dialect/dialect.go @@ -20,6 +20,7 @@ const ( SQLite = "sqlite3" Postgres = "postgres" Gremlin = "gremlin" + YDB = "ydb" ) // ExecQuerier wraps the 2 database operations. @@ -87,6 +88,11 @@ func DebugWithContext(d Driver, logger func(context.Context, ...any)) Driver { return drv } +// Log returns the log function used by this DebugDriver. +func (d *DebugDriver) Log() func(context.Context, ...any) { + return d.log +} + // Exec logs its params and calls the underlying driver Exec method. func (d *DebugDriver) Exec(ctx context.Context, query string, args, v any) error { d.log(ctx, fmt.Sprintf("driver.Exec: query=%v args=%v", query, args)) diff --git a/dialect/entsql/annotation.go b/dialect/entsql/annotation.go index aae8a420ee..b0db7fbaf0 100644 --- a/dialect/entsql/annotation.go +++ b/dialect/entsql/annotation.go @@ -550,15 +550,19 @@ type IndexAnnotation struct { DescColumns map[string]bool // IncludeColumns defines the INCLUDE clause for the index. - // Works only in Postgres and its definition is as follows: + // Works only in Postgres and YDB. Its definition is as follows: // // index.Fields("c1"). // Annotation( // entsql.IncludeColumns("c2"), // ) // + // Postgres: // CREATE INDEX "table_column" ON "table"("c1") INCLUDE ("c2") // + // YDB: + // ALTER TABLE `table` ADD INDEX `table_column` GLOBAL SYNC ON (`c1`) COVER (`c2`) + // IncludeColumns []string // Type defines the type of the index. diff --git a/dialect/sql/builder.go b/dialect/sql/builder.go index 576ba19470..29b514e310 100644 --- a/dialect/sql/builder.go +++ b/dialect/sql/builder.go @@ -16,10 +16,13 @@ import ( "database/sql/driver" "errors" "fmt" + "reflect" "strconv" "strings" "entgo.io/ent/dialect" + + "github.com/google/uuid" ) // Querier wraps the basic Query method that is implemented @@ -131,6 +134,12 @@ func (v *ViewBuilder) Query() (string, []any) { if len(v.columns) > 0 { v.Pad().Wrap(func(b *Builder) { b.JoinComma(v.columns...) }) } + + // YDB-specific: WITH (security_invoker = TRUE) is mandatory + if v.ydb() { + v.WriteString(" WITH (security_invoker = TRUE)") + } + v.WriteString(" AS ") v.Join(v.as) return v.String(), v.args @@ -146,6 +155,9 @@ type InsertBuilder struct { returning []string values [][]any conflict *conflict + + // YDB-specific: + isUpsert bool // use UPSERT instead of INSERT } // Insert creates a builder for the `INSERT INTO` statement. @@ -158,6 +170,21 @@ type InsertBuilder struct { // Note: Insert inserts all values in one batch. func Insert(table string) *InsertBuilder { return &InsertBuilder{table: table} } +// Upsert creates a builder for the `UPSERT INTO` statement. +// UPSERT updates or inserts rows based on primary key comparison. +// For existing rows, specified columns are updated while other columns are preserved. +// For missing rows, new rows are inserted. +// +// Upsert("users"). +// Columns("id", "name", "age"). +// Values(1, "a8m", 10). +// Values(2, "foo", 20) +// +// Note: UPSERT is only supported in YDB dialect. +func Upsert(table string) *InsertBuilder { + return &InsertBuilder{table: table, isUpsert: true} +} + // Schema sets the database name for the insert table. func (i *InsertBuilder) Schema(name string) *InsertBuilder { i.schema = name @@ -189,7 +216,11 @@ func (i *InsertBuilder) Values(values ...any) *InsertBuilder { // Default sets the default values clause based on the dialect type. func (i *InsertBuilder) Default() *InsertBuilder { - i.defaults = true + if i.ydb() { + i.AddError(fmt.Errorf("DEFAULT is not supported by %q", i.dialect)) + } else { + i.defaults = true + } return i } @@ -364,6 +395,10 @@ func ResolveWith(fn func(*UpdateSet)) ConflictOption { // sql.ResolveWithNewValues() // ) func (i *InsertBuilder) OnConflict(opts ...ConflictOption) *InsertBuilder { + if i.ydb() { + i.AddError(fmt.Errorf("ON CONFLICT is not supported by %q", i.dialect)) + return i + } if i.conflict == nil { i.conflict = &conflict{} } @@ -438,11 +473,21 @@ func (i *InsertBuilder) Query() (string, []any) { return query, args } -// QueryErr returns query representation of an `INSERT INTO` -// statement and any error occurred in building the statement. +// QueryErr returns query representation of an `INSERT INTO`, `UPSERT INTO`, +// or `REPLACE INTO` statement and any error occurred in building the statement. func (i *InsertBuilder) QueryErr() (string, []any, error) { b := i.Builder.clone() - b.WriteString("INSERT INTO ") + + if i.isUpsert { + if !b.ydb() { + b.AddError(fmt.Errorf("UPSERT INTO is not supported by %q", b.dialect)) + return "", nil, b.Err() + } + b.WriteString("UPSERT INTO ") + } else { + b.WriteString("INSERT INTO ") + } + b.writeSchema(i.schema) b.Ident(i.table).Pad() if i.defaults && len(i.columns) == 0 { @@ -604,8 +649,8 @@ func (u *UpdateBuilder) Empty() bool { // OrderBy appends the `ORDER BY` clause to the `UPDATE` statement. // Supported by SQLite and MySQL. func (u *UpdateBuilder) OrderBy(columns ...string) *UpdateBuilder { - if u.postgres() { - u.AddError(errors.New("ORDER BY is not supported by PostgreSQL")) + if u.postgres() || u.ydb() { + u.AddError(fmt.Errorf("ORDER BY is not supported by %q", u.dialect)) return u } for i := range columns { @@ -617,8 +662,8 @@ func (u *UpdateBuilder) OrderBy(columns ...string) *UpdateBuilder { // Limit appends the `LIMIT` clause to the `UPDATE` statement. // Supported by SQLite and MySQL. func (u *UpdateBuilder) Limit(limit int) *UpdateBuilder { - if u.postgres() { - u.AddError(errors.New("LIMIT is not supported by PostgreSQL")) + if u.postgres() || u.ydb() { + u.AddError(fmt.Errorf("LIMIT is not supported by %q", u.dialect)) return u } u.limit = &limit @@ -640,14 +685,23 @@ func (u *UpdateBuilder) Returning(columns ...string) *UpdateBuilder { // Query returns query representation of an `UPDATE` statement. func (u *UpdateBuilder) Query() (string, []any) { + query, args, _ := u.QueryErr() + return query, args +} + +func (u *UpdateBuilder) QueryErr() (string, []any, error) { b := u.Builder.clone() if len(u.prefix) > 0 { b.join(u.prefix, " ") b.Pad() } + b.WriteString("UPDATE ") b.writeSchema(u.schema) - b.Ident(u.table).WriteString(" SET ") + b.Ident(u.table) + + // Standard UPDATE SET pattern + b.WriteString(" SET ") u.writeSetter(&b) if u.where != nil { b.WriteString(" WHERE ") @@ -659,7 +713,7 @@ func (u *UpdateBuilder) Query() (string, []any) { b.WriteString(" LIMIT ") b.WriteString(strconv.Itoa(*u.limit)) } - return b.String(), b.args + return b.String(), b.args, nil } // writeSetter writes the "SET" clause for the UPDATE statement. @@ -690,9 +744,10 @@ func (u *UpdateBuilder) writeSetter(b *Builder) { // DeleteBuilder is a builder for `DELETE` statement. type DeleteBuilder struct { Builder - table string - schema string - where *Predicate + table string + schema string + where *Predicate + returning []string // YDB-specific } // Delete creates a builder for the `DELETE` statement. @@ -735,16 +790,37 @@ func (d *DeleteBuilder) FromSelect(s *Selector) *DeleteBuilder { return d } +// Returning adds the `RETURNING` clause to the delete statement. +// Supported by YDB. +func (d *DeleteBuilder) Returning(columns ...string) *DeleteBuilder { + if d.ydb() { + d.returning = columns + } else { + d.AddError(fmt.Errorf("DELETE RETURNING is not supported by %q", d.dialect)) + } + return d +} + // Query returns query representation of a `DELETE` statement. func (d *DeleteBuilder) Query() (string, []any) { - d.WriteString("DELETE FROM ") - d.writeSchema(d.schema) - d.Ident(d.table) + query, args, _ := d.QueryErr() + return query, args +} + +func (d *DeleteBuilder) QueryErr() (string, []any, error) { + b := d.Builder.clone() + + b.WriteString("DELETE FROM ") + b.writeSchema(d.schema) + b.Ident(d.table) + if d.where != nil { - d.WriteString(" WHERE ") - d.Join(d.where) + b.WriteString(" WHERE ") + b.Join(d.where) } - return d.String(), d.args + + joinReturning(d.returning, &b) + return b.String(), b.args, nil } // Predicate is a where predicate. @@ -1123,6 +1199,8 @@ func (p *Predicate) NotIn(col string, args ...any) *Predicate { } // Exists returns the `Exists` predicate. +// +// Note: Correlated subqueries with EXISTS are not supported by YDB func Exists(query Querier) *Predicate { return P().Exists(query) } @@ -1138,6 +1216,8 @@ func (p *Predicate) Exists(query Querier) *Predicate { } // NotExists returns the `NotExists` predicate. +// +// Note: Correlated subqueries with NOT EXISTS are not supported by YDB func NotExists(query Querier) *Predicate { return P().NotExists(query) } @@ -1165,38 +1245,64 @@ func (p *Predicate) Like(col, pattern string) *Predicate { }) } -// escape escapes w with the default escape character ('/'), +// escape escapes word with the default escape character ('\'), // to be used by the pattern matching functions below. // The second return value indicates if w was escaped or not. -func escape(w string) (string, bool) { +func escape(word string) (string, bool) { + return escapeWith(word, '\\') +} + +// escapeYDB escapes w with '#' for YDB, since YDB doesn't support '\' in ESCAPE clause. +func escapeYDB(word string) (string, bool) { + return escapeWith(word, '#') +} + +func escapeWith(word string, escChar byte) (string, bool) { var n int - for i := range w { - if c := w[i]; c == '%' || c == '_' || c == '\\' { + for i := 0; i < len(word); i++ { + if ch := word[i]; ch == '%' || ch == '_' || ch == escChar { n++ } } // No characters to escape. if n == 0 { - return w, false + return word, false } - var b strings.Builder - b.Grow(len(w) + n) - for _, c := range w { - if c == '%' || c == '_' || c == '\\' { - b.WriteByte('\\') + + var builder strings.Builder + builder.Grow(len(word) + n) + + for i := 0; i < len(word); i++ { + if ch := word[i]; ch == '%' || ch == '_' || ch == escChar { + builder.WriteByte(escChar) } - b.WriteRune(c) + builder.WriteByte(word[i]) } - return b.String(), true + return builder.String(), true } func (p *Predicate) escapedLike(col, left, right, word string) *Predicate { - return p.Append(func(b *Builder) { - w, escaped := escape(word) - b.Ident(col).WriteOp(OpLike) - b.Arg(left + w + right) - if p.dialect == dialect.SQLite && escaped { - p.WriteString(" ESCAPE ").Arg("\\") + return p.Append(func(builder *Builder) { + var escapedWord string + var escaped bool + + if p.dialect == dialect.YDB { + escapedWord, escaped = escapeYDB(word) + } else { + escapedWord, escaped = escape(word) + } + + builder.Ident(col).WriteOp(OpLike) + builder.Arg(left + escapedWord + right) + + // SQLite and YDB require explicit ESCAPE clause. + if escaped { + switch p.dialect { + case dialect.SQLite: + p.WriteString(" ESCAPE ").Arg("\\") + case dialect.YDB: + p.WriteString(" ESCAPE '#'") + } } }) } @@ -1204,17 +1310,26 @@ func (p *Predicate) escapedLike(col, left, right, word string) *Predicate { // ContainsFold is a helper predicate that applies the LIKE predicate with case-folding. func (p *Predicate) escapedLikeFold(col, left, substr, right string) *Predicate { return p.Append(func(b *Builder) { - w, escaped := escape(substr) switch b.dialect { case dialect.MySQL: + w, _ := escape(substr) // We assume the CHARACTER SET is configured to utf8mb4, // because this how it is defined in dialect/sql/schema. b.Ident(col).WriteString(" COLLATE utf8mb4_general_ci LIKE ") b.Arg(left + strings.ToLower(w) + right) case dialect.Postgres: + w, _ := escape(substr) + b.Ident(col).WriteString(" ILIKE ") + b.Arg(left + strings.ToLower(w) + right) + case dialect.YDB: + w, escaped := escapeYDB(substr) b.Ident(col).WriteString(" ILIKE ") b.Arg(left + strings.ToLower(w) + right) + if escaped { + p.WriteString(" ESCAPE '#'") + } default: // SQLite. + w, escaped := escape(substr) var f Func f.SetDialect(b.dialect) f.Lower(col) @@ -1267,8 +1382,14 @@ func (p *Predicate) ColumnsHasPrefix(col, prefixC string) *Predicate { if p.dialect == dialect.SQLite { p.WriteString(" ESCAPE ").Arg("\\") } + case dialect.YDB: + b.S("StartsWith("). + Ident(col). + S(", "). + Ident(prefixC). + S(")") default: - b.AddError(fmt.Errorf("ColumnsHasPrefix: unsupported dialect: %q", p.dialect)) + b.AddError(fmt.Errorf("ColumnsHasPrefix is not supported by %q", p.dialect)) } }) } @@ -1448,7 +1569,54 @@ func Lower(ident string) string { // Lower wraps the given ident with the LOWER function. func (f *Func) Lower(ident string) { - f.byName("LOWER", ident) + f.Append(func(b *Builder) { + if f.dialect == dialect.YDB { + f.WriteString("Unicode::ToLower(") + b.Ident(ident) + f.WriteString(")") + } else { + f.WriteString("LOWER") + f.Wrap(func(b *Builder) { + b.Ident(ident) + }) + } + }) +} + +// Upper wraps the given column with the UPPER function. +// +// P().EQ(sql.Upper("name"), "A8M") +func Upper(ident string) string { + f := &Func{} + f.Upper(ident) + return f.String() +} + +// Upper wraps the given ident with the UPPER function. +func (f *Func) Upper(ident string) { + f.Append(func(b *Builder) { + if f.dialect == dialect.YDB { + f.WriteString("Unicode::ToUpper(") + b.Ident(ident) + f.WriteString(")") + } else { + f.WriteString("UPPER") + f.Wrap(func(b *Builder) { + b.Ident(ident) + }) + } + }) +} + +// UpperExpr returns a dialect-aware UPPER expression. +func UpperExpr(ident string) Querier { + return ExprFunc(func(b *Builder) { + if b.Dialect() == dialect.YDB { + b.WriteString("Unicode::ToUpper(").Ident(ident).WriteString(")") + } else { + b.WriteString("UPPER(").Ident(ident).WriteString(")") + } + }) } // Count wraps the ident with the COUNT aggregation function. @@ -1583,6 +1751,9 @@ type SelectTable struct { name string schema string quote bool + + // YDB-specific: + isCte bool // YDB-specific: marks this as a CTE reference } // Table returns a new table selector. @@ -1643,7 +1814,25 @@ func (s *SelectTable) ref() string { } b := &Builder{dialect: s.dialect} b.writeSchema(s.schema) + + // YDB-specific: CTE references require $ prefix + // and should have alias for easy handling + if s.isCte && b.ydb() { + b.WriteString("$") + b.Ident(s.name) + + b.WriteString(" AS ") + if s.as != "" { + b.Ident(s.as) + } else { + b.Ident(s.name) + } + + return b.String() + } + b.Ident(s.name) + if s.as != "" { b.WriteString(" AS ") b.Ident(s.as) @@ -1677,7 +1866,7 @@ type Selector struct { // generated code such as alternate table schemas. ctx context.Context as string - selection []selection + selection []*selection from []TableView joins []join collected [][]*Predicate @@ -1742,17 +1931,17 @@ func SelectExpr(exprs ...Querier) *Selector { // selection represents a column or an expression selection. type selection struct { - x Querier - c string - as string + expr Querier + column string + alias string } // Select changes the columns selection of the SELECT statement. // Empty selection means all columns *. func (s *Selector) Select(columns ...string) *Selector { - s.selection = make([]selection, len(columns)) + s.selection = make([]*selection, len(columns)) for i := range columns { - s.selection[i] = selection{c: columns[i]} + s.selection[i] = &selection{column: columns[i]} } return s } @@ -1765,23 +1954,23 @@ func (s *Selector) SelectDistinct(columns ...string) *Selector { // AppendSelect appends additional columns to the SELECT statement. func (s *Selector) AppendSelect(columns ...string) *Selector { for i := range columns { - s.selection = append(s.selection, selection{c: columns[i]}) + s.selection = append(s.selection, &selection{column: columns[i]}) } return s } // AppendSelectAs appends additional column to the SELECT statement with the given alias. func (s *Selector) AppendSelectAs(column, as string) *Selector { - s.selection = append(s.selection, selection{c: column, as: as}) + s.selection = append(s.selection, &selection{column: column, alias: as}) return s } // SelectExpr changes the columns selection of the SELECT statement // with custom list of expressions. func (s *Selector) SelectExpr(exprs ...Querier) *Selector { - s.selection = make([]selection, len(exprs)) + s.selection = make([]*selection, len(exprs)) for i := range exprs { - s.selection[i] = selection{x: exprs[i]} + s.selection[i] = &selection{expr: exprs[i]} } return s } @@ -1789,7 +1978,7 @@ func (s *Selector) SelectExpr(exprs ...Querier) *Selector { // AppendSelectExpr appends additional expressions to the SELECT statement. func (s *Selector) AppendSelectExpr(exprs ...Querier) *Selector { for i := range exprs { - s.selection = append(s.selection, selection{x: exprs[i]}) + s.selection = append(s.selection, &selection{expr: exprs[i]}) } return s } @@ -1802,9 +1991,9 @@ func (s *Selector) AppendSelectExprAs(expr Querier, as string) *Selector { b.S("(").Join(expr).S(")") }) } - s.selection = append(s.selection, selection{ - x: x, - as: as, + s.selection = append(s.selection, &selection{ + expr: x, + alias: as, }) return s } @@ -1832,16 +2021,16 @@ func (s *Selector) FindSelection(name string) (matches []string) { for _, c := range s.selection { switch { // Match aliases. - case c.as != "": - if ident := s.isIdent(c.as); !ident && c.as == name || ident && s.unquote(c.as) == name { - matches = append(matches, c.as) + case c.alias != "": + if ident := s.isIdent(c.alias); !ident && c.alias == name || ident && s.unquote(c.alias) == name { + matches = append(matches, c.alias) } // Match qualified columns. - case c.c != "" && s.isQualified(c.c) && matchC(c.c): - matches = append(matches, c.c) + case c.column != "" && s.isQualified(c.column) && matchC(c.column): + matches = append(matches, c.column) // Match unqualified columns. - case c.c != "" && (c.c == name || s.isIdent(c.c) && s.unquote(c.c) == name): - matches = append(matches, c.c) + case c.column != "" && (c.column == name || s.isIdent(c.column) && s.unquote(c.column) == name): + matches = append(matches, c.column) } } return matches @@ -1851,7 +2040,7 @@ func (s *Selector) FindSelection(name string) (matches []string) { func (s *Selector) SelectedColumns() []string { columns := make([]string, 0, len(s.selection)) for i := range s.selection { - if c := s.selection[i].c; c != "" { + if c := s.selection[i].column; c != "" { columns = append(columns, c) } } @@ -1863,7 +2052,7 @@ func (s *Selector) SelectedColumns() []string { func (s *Selector) UnqualifiedColumns() []string { columns := make([]string, 0, len(s.selection)) for i := range s.selection { - c := s.selection[i].c + c := s.selection[i].column if c == "" { continue } @@ -1888,9 +2077,13 @@ func (s *Selector) From(t TableView) *Selector { // AppendFrom appends a new TableView to the `FROM` clause. func (s *Selector) AppendFrom(t TableView) *Selector { - s.from = append(s.from, t) - if st, ok := t.(state); ok { - st.SetDialect(s.dialect) + if s.ydb() && len(s.from) != 0 { + s.AddError(fmt.Errorf("multiple tables after FROM clause is not supported by %q", s.dialect)) + } else { + s.from = append(s.from, t) + if st, ok := t.(state); ok { + st.SetDialect(s.dialect) + } } return s } @@ -2107,6 +2300,11 @@ func (s *Selector) FullJoin(t TableView) *Selector { return s.join("FULL JOIN", t) } +// CrossJoin appends a `CROSS JOIN` clause to the statement. +func (s *Selector) CrossJoin(t TableView) *Selector { + return s.join("CROSS JOIN", t) +} + // join adds a join table to the selector with the given kind. func (s *Selector) join(kind string, t TableView) *Selector { s.joins = append(s.joins, join{ @@ -2178,17 +2376,22 @@ func (s *Selector) UnionDistinct(t TableView) *Selector { // Except appends the EXCEPT clause to the query. func (s *Selector) Except(t TableView) *Selector { - s.setOps = append(s.setOps, setOp{ - Type: setOpTypeExcept, - TableView: t, - }) + if s.ydb() { + s.AddError(fmt.Errorf("EXCEPT is not supported by %q", s.dialect)) + return s + } else { + s.setOps = append(s.setOps, setOp{ + Type: setOpTypeExcept, + TableView: t, + }) + } return s } // ExceptAll appends the EXCEPT ALL clause to the query. func (s *Selector) ExceptAll(t TableView) *Selector { - if s.sqlite() { - s.AddError(errors.New("EXCEPT ALL is not supported by SQLite")) + if s.sqlite() || s.ydb() { + s.AddError(fmt.Errorf("EXCEPT ALL is not supported by %q", s.dialect)) } else { s.setOps = append(s.setOps, setOp{ Type: setOpTypeExcept, @@ -2201,17 +2404,21 @@ func (s *Selector) ExceptAll(t TableView) *Selector { // Intersect appends the INTERSECT clause to the query. func (s *Selector) Intersect(t TableView) *Selector { - s.setOps = append(s.setOps, setOp{ - Type: setOpTypeIntersect, - TableView: t, - }) + if s.ydb() { + s.AddError(fmt.Errorf("INTERSECT is not supported by %q", s.dialect)) + } else { + s.setOps = append(s.setOps, setOp{ + Type: setOpTypeIntersect, + TableView: t, + }) + } return s } // IntersectAll appends the INTERSECT ALL clause to the query. func (s *Selector) IntersectAll(t TableView) *Selector { - if s.sqlite() { - s.AddError(errors.New("INTERSECT ALL is not supported by SQLite")) + if s.sqlite() || s.ydb() { + s.AddError(fmt.Errorf("INTERSECT ALL is not supported by %q", s.dialect)) } else { s.setOps = append(s.setOps, setOp{ Type: setOpTypeIntersect, @@ -2363,8 +2570,8 @@ func WithLockClause(clause string) LockOption { // For sets the lock configuration for suffixing the `SELECT` // statement with the `FOR [SHARE | UPDATE] ...` clause. func (s *Selector) For(l LockStrength, opts ...LockOption) *Selector { - if s.Dialect() == dialect.SQLite { - s.AddError(errors.New("sql: SELECT .. FOR UPDATE/SHARE not supported in SQLite")) + if s.sqlite() || s.ydb() { + s.AddError(fmt.Errorf("SELECT .. FOR UPDATE/SHARE is not supported by %q", s.dialect)) } s.lock = &LockOptions{Strength: l} for _, opt := range opts { @@ -2410,7 +2617,7 @@ func (s *Selector) Clone() *Selector { joins: append([]join{}, joins...), group: append([]string{}, s.group...), order: append([]any{}, s.order...), - selection: append([]selection{}, s.selection...), + selection: append([]*selection{}, s.selection...), } } @@ -2494,6 +2701,10 @@ func (s *Selector) Having(p *Predicate) *Selector { // Query returns query representation of a `SELECT` statement. func (s *Selector) Query() (string, []any) { b := s.Builder.clone() + // For YDB, mark tables that reference CTEs + if b.ydb() { + s.markCteReferences() + } s.joinPrefix(&b) b.WriteString("SELECT ") if s.distinct { @@ -2568,6 +2779,9 @@ func (s *Selector) Query() (string, []any) { if len(s.setOps) > 0 { s.joinSetOps(&b) } + if b.ydb() { + s.applyAliasesToOrder() + } joinOrder(s.order, &b) if s.limit != nil { b.WriteString(" LIMIT ") @@ -2590,6 +2804,45 @@ func (s *Selector) joinPrefix(b *Builder) { } } +// markCteReferences marks SelectTable entries in from/joins as CTE references +// if they match CTE names from the prefix. Used for YDB which requires $ prefix +// when referencing named expressions (CTEs). +func (s *Selector) markCteReferences() { + cteNames := s.collectCteNames() + if len(cteNames) == 0 { + return + } + // Mark FROM tables + for _, from := range s.from { + if table, ok := from.(*SelectTable); ok { + if _, isCte := cteNames[table.name]; isCte { + table.isCte = true + } + } + } + // Mark JOIN tables + for _, join := range s.joins { + if table, ok := join.table.(*SelectTable); ok { + if _, isCte := cteNames[table.name]; isCte { + table.isCte = true + } + } + } +} + +// collectCteNames returns a set of CTE names from the selector's prefix. +func (s *Selector) collectCteNames() map[string]any { + names := make(map[string]any) + for _, prefix := range s.prefix { + if with, ok := prefix.(*WithBuilder); ok { + for _, cte := range with.ctes { + names[cte.name] = struct{}{} + } + } + } + return names +} + func (s *Selector) joinLock(b *Builder) { if s.lock == nil { return @@ -2648,7 +2901,8 @@ func joinOrder(order []any, b *Builder) { } func joinReturning(columns []string, b *Builder) { - if len(columns) == 0 || (!b.postgres() && !b.sqlite()) { + supportedByDialect := b.postgres() || b.sqlite() || b.ydb() + if len(columns) == 0 || !supportedByDialect { return } b.WriteString(" RETURNING ") @@ -2656,23 +2910,147 @@ func joinReturning(columns []string, b *Builder) { } func (s *Selector) joinSelect(b *Builder) { - for i, sc := range s.selection { + for i, selection := range s.selection { if i > 0 { b.Comma() } + + // YDB returns column names with table prefix (e.g., "users.name" instead of "name"), + // so we add aliases to ensure the scanner can match columns correctly. + if selection.alias == "" && b.ydb() { + // If the column already has an alias, extract it + upperColumnName := strings.ToUpper(selection.column) + + if idx := strings.LastIndex(upperColumnName, " AS "); idx != -1 { + originalColumn := selection.column + + selection.column = strings.TrimSpace(originalColumn[:idx]) + selection.alias = strings.Trim(originalColumn[idx+4:], " `\"") + } else if selection.column != "" && !strings.ContainsAny(selection.column, "()") { + // Qualified column name like "users.name" -> alias "name" + if idx := strings.LastIndexByte(selection.column, '.'); idx != -1 { + selection.alias = selection.column[idx+1:] + } + } else if selection.column != "" { + // Expression passed as column string like "COUNT(*)" or "SUM(users.age)" + selection.alias = exprAlias(selection.column) + } + } + switch { - case sc.c != "": - b.Ident(sc.c) - case sc.x != nil: - b.Join(sc.x) + case selection.column != "": + // YDB requires qualified asterisk (table.*) + // when mixing * with other projection items. + if b.ydb() && selection.column == "*" && len(s.selection) > 1 { + if tableName := s.firstTableName(); tableName != "" { + b.Ident(tableName).WriteByte('.').WriteString("*") + } else { + b.Ident(selection.column) + } + } else { + b.Ident(selection.column) + } + case selection.expr != nil: + b.Join(selection.expr) } - if sc.as != "" { + + if selection.alias != "" { b.WriteString(" AS ") - b.Ident(sc.as) + b.Ident(selection.alias) } } } +// firstTableName returns the name or alias of the first table in the FROM clause. +func (s *Selector) firstTableName() string { + if len(s.from) == 0 { + return "" + } + switch t := s.from[0].(type) { + case *SelectTable: + if t.as != "" { + return t.as + } + return t.name + case *WithBuilder: + return t.Name() + case *Selector: + return t.as + } + return "" +} + +// applyAliasesToOrder processes ORDER BY columns for YDB compatibility. +// - When there's a GROUP BY, use aliases +// - When there are subquery joins, use aliases +// - When there are simple table joins, keep qualified columns to avoid ambiguity +// - Otherwise, replace qualified columns with their aliases +func (s *Selector) applyAliasesToOrder() { + aliasMap := make(map[string]string) + for _, selection := range s.selection { + if selection.column == "" { + continue + } + if selection.alias != "" { + aliasMap[selection.column] = selection.alias + } + } + + if len(aliasMap) == 0 { + return + } + + hasGroupBy := len(s.group) > 0 + hasSubqueryJoin := s.hasSubqueryJoin() + hasSimpleTableJoin := len(s.joins) > 0 && !hasSubqueryJoin + + // Process ORDER BY columns + result := make([]any, len(s.order)) + for i, order := range s.order { + str, ok := order.(string) + if !ok { + result[i] = order + continue + } + // Handle "column DESC" or "column ASC" suffixes. + column, suffix := str, "" + if idx := strings.LastIndex(str, " "); idx != -1 { + upper := strings.ToUpper(str[idx+1:]) + if upper == "ASC" || upper == "DESC" { + column = str[:idx] + suffix = str[idx:] + } + } + + if alias, ok := aliasMap[column]; (hasGroupBy || hasSubqueryJoin || !hasSimpleTableJoin) && ok { + result[i] = alias + suffix + } else { + result[i] = order + } + } + s.order = result +} + +// hasSubqueryJoin returns true if any join involves a subquery (Selector). +func (s *Selector) hasSubqueryJoin() bool { + for _, join := range s.joins { + if _, ok := join.table.(*Selector); ok { + return true + } + } + return false +} + +// exprAlias extracts an alias from an aggregate expression for YDB. +// E.g., "COUNT(*)" -> "count", "SUM(users.age)" -> "sum" +func exprAlias(expr string) string { + expr = strings.ToLower(expr) + if idx := strings.IndexByte(expr, '('); idx != -1 { + return expr[:idx] + } + return "" +} + // implement the table view interface. func (*Selector) view() {} @@ -2745,6 +3123,10 @@ func (w *WithBuilder) C(column string) string { // Query returns query representation of a `WITH` clause. func (w *WithBuilder) Query() (string, []any) { + if w.ydb() { + return w.queryYDB() + } + w.WriteString("WITH ") if w.recursive { w.WriteString("RECURSIVE ") @@ -2767,6 +3149,55 @@ func (w *WithBuilder) Query() (string, []any) { return w.String(), w.args } +// YDB uses named expressions ($name = SELECT ...) instead of CTEs +func (w *WithBuilder) queryYDB() (string, []any) { + // Collect all CTE names for marking references + cteNames := make(map[string]struct{}) + for _, cte := range w.ctes { + cteNames[cte.name] = struct{}{} + } + + for i, cte := range w.ctes { + if i > 0 { + w.WriteString(" ") + } + + // Mark CTE references in the selector's FROM and JOIN tables + if cte.s != nil { + w.markCteReferencesInSelector(cte.s, cteNames) + } + + w.WriteString("$") + w.Ident(cte.name) + w.WriteString(" = ") + + w.Wrap(func(b *Builder) { + b.Join(cte.s) + }) + + w.WriteString(";") + } + return w.String(), w.args +} + +// markCteReferencesInSelector marks tables in a selector that reference CTEs. +func (w *WithBuilder) markCteReferencesInSelector(s *Selector, cteNames map[string]struct{}) { + for _, from := range s.from { + if table, ok := from.(*SelectTable); ok { + if _, isCte := cteNames[table.name]; isCte { + table.isCte = true + } + } + } + for _, join := range s.joins { + if table, ok := join.table.(*SelectTable); ok { + if _, isCte := cteNames[table.name]; isCte { + table.isCte = true + } + } + } +} + // implement the table view interface. func (*WithBuilder) view() {} @@ -3065,9 +3496,10 @@ func (b *Builder) AddError(err error) *Builder { } func (b *Builder) writeSchema(schema string) { - if schema != "" && b.dialect != dialect.SQLite { - b.Ident(schema).WriteByte('.') + if schema == "" || b.sqlite() || b.ydb() { + return } + b.Ident(schema).WriteByte('.') } // Err returns a concatenated error of all errors encountered during @@ -3177,6 +3609,9 @@ func (b *Builder) Arg(a any) *Builder { // Postgres' arguments are referenced using the syntax $n. // $1 refers to the 1st argument, $2 to the 2nd, and so on. format = "$" + strconv.Itoa(b.total+1) + } else if b.ydb() { + // YDB uses named parameters with the syntax $paramName. + format = "$p" + strconv.Itoa(b.total) } if f, ok := a.(ParamFormatter); ok { format = f.FormatParam(format, &StmtInfo{ @@ -3202,8 +3637,8 @@ func (b *Builder) Args(a ...any) *Builder { // // FormatArg("JSON(?)", b). // FormatArg("ST_GeomFromText(?)", geom) -func (b *Builder) Argf(format string, a any) *Builder { - switch a := a.(type) { +func (b *Builder) Argf(format string, arg any) *Builder { + switch a := arg.(type) { case nil: b.WriteString("NULL") return b @@ -3215,11 +3650,79 @@ func (b *Builder) Argf(format string, a any) *Builder { return b } b.total++ - b.args = append(b.args, a) + + // YDB requires named parameters with $paramName syntax. + if b.ydb() { + paramName := strings.TrimPrefix(format, "$") + b.args = append(b.args, driver.NamedValue{ + Name: paramName, + Value: b.convertValueYdb(arg), + }) + } else { + b.args = append(b.args, arg) + } + b.WriteString(format) return b } +// YDB has strong typing system +// and YDB driver can't convert type aliases to underlying Go type +// Therefore, we have to manually handle these edge cases +func (b *Builder) convertValueYdb(arg any) any { + finalValue := arg + + switch casted := arg.(type) { + case uuid.UUID: + finalValue = casted + case driver.Valuer: + if v, err := casted.Value(); err == nil { + finalValue = v + } + default: + // YDB requires exact numeric types. + // Convert named types to their base primitive type + // while preserving the exact numeric size. + typ := reflect.TypeOf(arg) + value := reflect.ValueOf(arg) + + switch typ.Kind() { + case reflect.Int: + finalValue = int(value.Int()) + case reflect.Int8: + finalValue = int8(value.Int()) // #nosec G115 + case reflect.Int16: + finalValue = int16(value.Int()) // #nosec G115 + case reflect.Int32: + finalValue = int32(value.Int()) // #nosec G115 + case reflect.Int64: + finalValue = value.Int() + case reflect.Uint: + finalValue = uint(value.Uint()) + case reflect.Uint8: + finalValue = uint8(value.Uint()) // #nosec G115 + case reflect.Uint16: + finalValue = uint16(value.Uint()) // #nosec G115 + case reflect.Uint32: + finalValue = uint32(value.Uint()) // #nosec G115 + case reflect.Uint64: + finalValue = value.Uint() + case reflect.Float32: + finalValue = float32(value.Float()) + case reflect.Float64: + finalValue = value.Float() + default: + // Convert other custom types (e.g., http.Dir -> string) + converted, err := driver.DefaultParameterConverter.ConvertValue(arg) + if err == nil { + finalValue = converted + } + } + } + + return finalValue +} + // Comma adds a comma to the query. func (b *Builder) Comma() *Builder { return b.WriteString(", ") @@ -3331,6 +3834,11 @@ func (b Builder) sqlite() bool { return b.Dialect() == dialect.SQLite } +// ydb reports if the builder dialect is YDB. +func (b Builder) ydb() bool { + return b.Dialect() == dialect.YDB +} + // fromIdent sets the builder dialect from the identifier format. func (b *Builder) fromIdent(ident string) { if strings.Contains(ident, `"`) { @@ -3388,6 +3896,11 @@ func Dialect(name string) *DialectBuilder { return &DialectBuilder{name} } +// Dialect returns the dialect name of this builder. +func (d *DialectBuilder) Dialect() string { + return d.dialect +} + // String builds a dialect-aware expression string from the given callback. func (d *DialectBuilder) String(f func(*Builder)) string { b := &Builder{} @@ -3437,6 +3950,19 @@ func (d *DialectBuilder) Insert(table string) *InsertBuilder { return b } +// Upsert creates an InsertBuilder for the UPSERT statement with the configured dialect. +// UPSERT is only supported in YDB dialect. +// +// Dialect(dialect.YDB). +// Upsert("users"). +// Columns("id", "name", "age"). +// Values(1, "a8m", 10) +func (d *DialectBuilder) Upsert(table string) *InsertBuilder { + b := Upsert(table) + b.SetDialect(d.dialect) + return b +} + // Update creates a UpdateBuilder for the configured dialect. // // Dialect(dialect.Postgres). diff --git a/dialect/sql/builder_test.go b/dialect/sql/builder_test.go index c344fc4678..839f471a1d 100644 --- a/dialect/sql/builder_test.go +++ b/dialect/sql/builder_test.go @@ -72,6 +72,11 @@ func TestBuilder(t *testing.T) { wantQuery: "INSERT INTO `users` (`age`) VALUES (?)", wantArgs: []any{1}, }, + { + input: Dialect(dialect.YDB).Insert("users").Columns("age").Values(1), + wantQuery: "INSERT INTO `users` (`age`) VALUES ($p0)", + wantArgs: []any{driver.NamedValue{Name: "p0", Value: 1}}, + }, { input: Dialect(dialect.Postgres).Insert("users").Columns("age").Values(1).Returning("id"), wantQuery: `INSERT INTO "users" ("age") VALUES ($1) RETURNING "id"`, @@ -146,6 +151,11 @@ func TestBuilder(t *testing.T) { wantQuery: "UPDATE `users` SET `name` = ?", wantArgs: []any{"foo"}, }, + { + input: Dialect(dialect.YDB).Update("users").Set("name", "foo"), + wantQuery: "UPDATE `users` SET `name` = $p0", + wantArgs: []any{driver.NamedValue{Name: "p0", Value: "foo"}}, + }, { input: Update("users").Set("name", "foo").Set("age", 10), wantQuery: "UPDATE `users` SET `name` = ?, `age` = ?", @@ -483,6 +493,14 @@ func TestBuilder(t *testing.T) { wantQuery: `SELECT * FROM "users" WHERE "name" = $1`, wantArgs: []any{"Ariel"}, }, + { + input: Dialect(dialect.YDB). + Select(). + From(Table("users")). + Where(EQ("name", "Alex")), + wantQuery: "SELECT * FROM `users` WHERE `name` = $p0", + wantArgs: []any{driver.NamedValue{Name: "p0", Value: "Alex"}}, + }, { input: Select(). From(Table("users")). @@ -533,6 +551,12 @@ func TestBuilder(t *testing.T) { Schema("mydb"), wantQuery: "DELETE FROM `users` WHERE `parent_id` IS NOT NULL", }, + { + input: Dialect(dialect.YDB). + Delete("users"). + Where(NotNull("parent_id")), + wantQuery: "DELETE FROM `users` WHERE `parent_id` IS NOT NULL", + }, { input: Dialect(dialect.Postgres). Delete("users"). @@ -712,6 +736,18 @@ func TestBuilder(t *testing.T) { }(), wantQuery: `SELECT "u"."id", "g"."name" FROM "users" AS "u" JOIN "groups" AS "g" ON "u"."id" = "g"."user_id"`, }, + { + input: func() Querier { + d := Dialect(dialect.YDB) + t1 := d.Table("users").As("u") + t2 := d.Table("groups").As("g") + return d.Select(t1.C("id"), t2.C("name")). + From(t1). + Join(t2). + On(t1.C("id"), t2.C("user_id")) + }(), + wantQuery: "SELECT `u`.`id` AS `id`, `g`.`name` AS `name` FROM `users` AS `u` JOIN `groups` AS `g` ON `u`.`id` = `g`.`user_id`", + }, { input: func() Querier { t1 := Table("users").As("u") @@ -1092,6 +1128,11 @@ func TestBuilder(t *testing.T) { Select().Count().From(Table("users")), wantQuery: `SELECT COUNT(*) FROM "users"`, }, + { + input: Dialect(dialect.YDB). + Select().Count().From(Table("users")), + wantQuery: "SELECT COUNT(*) AS `count` FROM `users`", + }, { input: Select().Count(Distinct("id")).From(Table("users")), wantQuery: "SELECT COUNT(DISTINCT `id`) FROM `users`", @@ -1159,6 +1200,13 @@ func TestBuilder(t *testing.T) { GroupBy("name"), wantQuery: `SELECT "name", COUNT(*) FROM "users" GROUP BY "name"`, }, + { + input: Dialect(dialect.YDB). + Select("name", Count("*")). + From(Table("users")). + GroupBy("name"), + wantQuery: "SELECT `name`, COUNT(*) AS `count` FROM `users` GROUP BY `name`", + }, { input: Select("name", Count("*")). From(Table("users")). @@ -1202,6 +1250,14 @@ func TestBuilder(t *testing.T) { Limit(1), wantQuery: `SELECT * FROM "users" LIMIT 1`, }, + { + input: Dialect(dialect.YDB). + Select("*"). + From(Table("users")). + OrderBy("id"). + Limit(10), + wantQuery: "SELECT * FROM `users` ORDER BY `id` LIMIT 10", + }, { input: Select("age").Distinct().From(Table("users")), wantQuery: "SELECT DISTINCT `age` FROM `users`", @@ -1475,6 +1531,273 @@ AND "users"."id1" < "users"."id2") AND "users"."id1" <= "users"."id2"`, "\n", "" From(Select("name", "age").From(Table("users"))), wantQuery: "SELECT `name` FROM (SELECT `name`, `age` FROM `users`)", }, + { + input: Dialect(dialect.YDB). + Delete("users"). + Where(EQ("id", 1)), + wantQuery: "DELETE FROM `users` WHERE `id` = $p0", + wantArgs: []any{driver.NamedValue{Name: "p0", Value: 1}}, + }, + { + input: Dialect(dialect.YDB). + Delete("users"). + Where(EQ("status", "inactive")). + Where(LT("last_login", "2024-01-01")), + wantQuery: "DELETE FROM `users` WHERE `status` = $p0 AND `last_login` < $p1", + wantArgs: []any{ + driver.NamedValue{Name: "p0", Value: "inactive"}, + driver.NamedValue{Name: "p1", Value: "2024-01-01"}, + }, + }, + { + input: Dialect(dialect.YDB). + Delete("users"). + Where(And( + EQ("status", "cancelled"), + GT("age", 18), + )), + wantQuery: "DELETE FROM `users` WHERE `status` = $p0 AND `age` > $p1", + wantArgs: []any{ + driver.NamedValue{Name: "p0", Value: "cancelled"}, + driver.NamedValue{Name: "p1", Value: 18}, + }, + }, + { + input: Dialect(dialect.YDB). + Delete("users"). + Where(Or( + EQ("status", "cancelled"), + EQ("status", "expired"), + )), + wantQuery: "DELETE FROM `users` WHERE `status` = $p0 OR `status` = $p1", + wantArgs: []any{ + driver.NamedValue{Name: "p0", Value: "cancelled"}, + driver.NamedValue{Name: "p1", Value: "expired"}, + }, + }, + { + input: Dialect(dialect.YDB). + Delete("orders"). + Where(EQ("status", "cancelled")). + Returning("*"), + wantQuery: "DELETE FROM `orders` WHERE `status` = $p0 RETURNING *", + wantArgs: []any{driver.NamedValue{Name: "p0", Value: "cancelled"}}, + }, + { + input: Dialect(dialect.YDB). + Delete("orders"). + Where(EQ("status", "cancelled")). + Returning("order_id", "order_date"), + wantQuery: "DELETE FROM `orders` WHERE `status` = $p0 RETURNING `order_id`, `order_date`", + wantArgs: []any{driver.NamedValue{Name: "p0", Value: "cancelled"}}, + }, + { + input: Dialect(dialect.YDB).Delete("users"), + wantQuery: "DELETE FROM `users`", + }, + { + input: Dialect(dialect.YDB). + Insert("users"). + Columns("name", "age"). + Values("a8m", 10), + wantQuery: "INSERT INTO `users` (`name`, `age`) VALUES ($p0, $p1)", + wantArgs: []any{ + driver.NamedValue{Name: "p0", Value: "a8m"}, + driver.NamedValue{Name: "p1", Value: 10}, + }, + }, + { + input: Dialect(dialect.YDB). + Update("users"). + Set("name", "foo"). + Where(EQ("id", 1)), + wantQuery: "UPDATE `users` SET `name` = $p0 WHERE `id` = $p1", + wantArgs: []any{ + driver.NamedValue{Name: "p0", Value: "foo"}, + driver.NamedValue{Name: "p1", Value: 1}, + }, + }, + { + input: Dialect(dialect.YDB). + Select("*"). + From(Table("users")). + Where(EQ("name", "Alex")), + wantQuery: "SELECT * FROM `users` WHERE `name` = $p0", + wantArgs: []any{driver.NamedValue{Name: "p0", Value: "Alex"}}, + }, + { + input: Dialect(dialect.YDB). + Insert("users"). + Columns("name", "age"). + Values("a8m", 10). + Returning("id"), + wantQuery: "INSERT INTO `users` (`name`, `age`) VALUES ($p0, $p1) RETURNING `id`", + wantArgs: []any{ + driver.NamedValue{Name: "p0", Value: "a8m"}, + driver.NamedValue{Name: "p1", Value: 10}, + }, + }, + { + input: Dialect(dialect.YDB). + Insert("users"). + Columns("name", "age"). + Values("a8m", 10). + Returning("*"), + wantQuery: "INSERT INTO `users` (`name`, `age`) VALUES ($p0, $p1) RETURNING *", + wantArgs: []any{ + driver.NamedValue{Name: "p0", Value: "a8m"}, + driver.NamedValue{Name: "p1", Value: 10}, + }, + }, + { + input: Dialect(dialect.YDB). + Upsert("users"). + Columns("id", "name", "age"). + Values(1, "a8m", 10), + wantQuery: "UPSERT INTO `users` (`id`, `name`, `age`) VALUES ($p0, $p1, $p2)", + wantArgs: []any{ + driver.NamedValue{Name: "p0", Value: 1}, + driver.NamedValue{Name: "p1", Value: "a8m"}, + driver.NamedValue{Name: "p2", Value: 10}, + }, + }, + { + input: Dialect(dialect.YDB). + Upsert("users"). + Columns("id", "name", "age"). + Values(1, "a8m", 10). + Values(2, "foo", 20), + wantQuery: "UPSERT INTO `users` (`id`, `name`, `age`) VALUES ($p0, $p1, $p2), ($p3, $p4, $p5)", + wantArgs: []any{ + driver.NamedValue{Name: "p0", Value: 1}, + driver.NamedValue{Name: "p1", Value: "a8m"}, + driver.NamedValue{Name: "p2", Value: 10}, + driver.NamedValue{Name: "p3", Value: 2}, + driver.NamedValue{Name: "p4", Value: "foo"}, + driver.NamedValue{Name: "p5", Value: 20}, + }, + }, + { + input: Dialect(dialect.YDB). + Upsert("orders"). + Columns("order_id", "status", "amount"). + Values(1001, "shipped", 500). + Returning("*"), + wantQuery: "UPSERT INTO `orders` (`order_id`, `status`, `amount`) VALUES ($p0, $p1, $p2) RETURNING *", + wantArgs: []any{ + driver.NamedValue{Name: "p0", Value: 1001}, + driver.NamedValue{Name: "p1", Value: "shipped"}, + driver.NamedValue{Name: "p2", Value: 500}, + }, + }, + { + input: Dialect(dialect.YDB). + Upsert("users"). + Columns("user_id", "name", "email"). + Values(42, "John Doe", "john@example.com"). + Returning("user_id", "email"), + wantQuery: "UPSERT INTO `users` (`user_id`, `name`, `email`) VALUES ($p0, $p1, $p2) RETURNING `user_id`, `email`", + wantArgs: []any{ + driver.NamedValue{Name: "p0", Value: 42}, + driver.NamedValue{Name: "p1", Value: "John Doe"}, + driver.NamedValue{Name: "p2", Value: "john@example.com"}, + }, + }, + { + input: Dialect(dialect.YDB). + Update("users"). + Set("name", "foo"). + Where(EQ("id", 1)). + Returning("*"), + wantQuery: "UPDATE `users` SET `name` = $p0 WHERE `id` = $p1 RETURNING *", + wantArgs: []any{ + driver.NamedValue{Name: "p0", Value: "foo"}, + driver.NamedValue{Name: "p1", Value: 1}, + }, + }, + { + input: Dialect(dialect.YDB). + Update("orders"). + Set("status", "shipped"). + Where(LT("order_date", "2023-01-01")). + Returning("order_id", "status"), + wantQuery: "UPDATE `orders` SET `status` = $p0 WHERE `order_date` < $p1 RETURNING `order_id`, `status`", + wantArgs: []any{ + driver.NamedValue{Name: "p0", Value: "shipped"}, + driver.NamedValue{Name: "p1", Value: "2023-01-01"}, + }, + }, + { + input: func() Querier { + t1 := Table("users").As("u") + t2 := Table("groups").As("g") + return Select(t1.C("id"), t2.C("name")). + From(t1). + CrossJoin(t2) + }(), + wantQuery: "SELECT `u`.`id`, `g`.`name` FROM `users` AS `u` CROSS JOIN `groups` AS `g`", + }, + { + input: func() Querier { + d := Dialect(dialect.YDB) + t1 := d.Table("a_table").As("a") + t2 := d.Table("b_table").As("b") + t3 := d.Table("c_table").As("c") + return d.Select(t1.C("value"), t2.C("value"), t3.C("column2")). + From(t1). + CrossJoin(t2). + LeftJoin(t3). + OnP(And(EQ(t3.C("ref"), Expr(t1.C("key"))), EQ(t3.C("column1"), Expr(t2.C("value"))))) + }(), + wantQuery: "SELECT `a`.`value` AS `value`, `b`.`value` AS `value`, `c`.`column2` AS `column2` FROM `a_table` AS `a` CROSS JOIN `b_table` AS `b` LEFT JOIN `c_table` AS `c` ON `c`.`ref` = `a`.`key` AND `c`.`column1` = `b`.`value`", + }, + { + input: Dialect(dialect.YDB). + Select("value"). + From(Table("my_table")). + Distinct(), + wantQuery: "SELECT DISTINCT `value` FROM `my_table`", + }, + { + input: Dialect(dialect.YDB). + Select("*"). + From(Table("users")). + Distinct(), + wantQuery: "SELECT DISTINCT * FROM `users`", + }, + { + input: Dialect(dialect.YDB). + Select("status", "type"). + From(Table("orders")). + Distinct(). + Where(GT("created_at", "2024-01-01")), + wantQuery: "SELECT DISTINCT `status`, `type` FROM `orders` WHERE `created_at` > $p0", + wantArgs: []any{driver.NamedValue{Name: "p0", Value: "2024-01-01"}}, + }, + { + input: Dialect(dialect.YDB). + Select("category"). + From(Table("products")). + Distinct(). + OrderBy("category"). + Limit(10), + wantQuery: "SELECT DISTINCT `category` FROM `products` ORDER BY `category` LIMIT 10", + }, + { + input: Dialect(dialect.YDB). + Select("name", "age"). + From(Table("users")). + Distinct(), + wantQuery: "SELECT DISTINCT `name`, `age` FROM `users`", + }, + { + input: Dialect(dialect.YDB). + Select("email"). + From(Table("subscribers")). + Where(EQ("active", true)). + Distinct(), + wantQuery: "SELECT DISTINCT `email` FROM `subscribers` WHERE `active`", + }, } for i, tt := range tests { t.Run(strconv.Itoa(i), func(t *testing.T) { @@ -1598,6 +1921,62 @@ func TestSelector_Union(t *testing.T) { Query() require.Equal(t, `SELECT * FROM "users" WHERE "active" UNION SELECT * FROM "old_users1" WHERE "is_active" AND "age" > $1 UNION ALL SELECT * FROM "old_users2" WHERE "is_active" = $2 AND "age" < $3`, query) require.Equal(t, []any{20, "true", 18}, args) + + query, args = Dialect(dialect.YDB). + Select("key"). + From(Table("T1")). + Union( + Dialect(dialect.YDB). + Select("key"). + From(Table("T2")), + ). + Query() + require.Equal(t, "SELECT `key` FROM `T1` UNION SELECT `key` FROM `T2`", query) + require.Empty(t, args) + + query, args = Dialect(dialect.YDB). + Select("id", "name"). + From(Table("users")). + Where(EQ("status", "active")). + Union( + Dialect(dialect.YDB). + Select("id", "name"). + From(Table("users")). + Where(EQ("status", "inactive")), + ). + Query() + require.Equal(t, "SELECT `id`, `name` FROM `users` WHERE `status` = $p0 UNION SELECT `id`, `name` FROM `users` WHERE `status` = $p1", query) + require.Equal(t, []any{ + driver.NamedValue{Name: "p0", Value: "active"}, + driver.NamedValue{Name: "p1", Value: "inactive"}, + }, args) + + query, args = Dialect(dialect.YDB). + Select("x"). + UnionAll(Dialect(dialect.YDB).Select("y")). + UnionAll(Dialect(dialect.YDB).Select("z")). + Query() + require.Equal(t, "SELECT `x` UNION ALL SELECT `y` UNION ALL SELECT `z`", query) + require.Empty(t, args) + + query, args = Dialect(dialect.YDB). + Select("id"). + From(Table("orders")). + Where(EQ("status", "pending")). + Union( + Dialect(dialect.YDB). + Select("id"). + From(Table("orders")). + Where(EQ("status", "processing")), + ). + OrderBy("id"). + Limit(100). + Query() + require.Equal(t, "SELECT `id` FROM `orders` WHERE `status` = $p0 UNION SELECT `id` FROM `orders` WHERE `status` = $p1 ORDER BY `id` LIMIT 100", query) + require.Equal(t, []any{ + driver.NamedValue{Name: "p0", Value: "pending"}, + driver.NamedValue{Name: "p1", Value: "processing"}, + }, args) } func TestSelector_Except(t *testing.T) { @@ -1660,6 +2039,34 @@ func TestSelector_Intersect(t *testing.T) { require.Equal(t, []any{20, "true", 18}, args) } +func TestCreateView_YDB(t *testing.T) { + t.Run("Basic view with security_invoker", func(t *testing.T) { + d := Dialect(dialect.YDB) + query, args := d.CreateView("recent_series"). + As( + d.Select("*"). + From(Table("db")). + Where(GT("release_date", "2020-01-01")), + ). + Query() + + require.Contains(t, query, "CREATE VIEW `recent_series` WITH (security_invoker = TRUE) AS SELECT * FROM `db`") + require.Contains(t, query, "WHERE `release_date` > $p0") + require.Equal(t, []any{driver.NamedValue{Name: "p0", Value: "2020-01-01"}}, args) + }) + + t.Run("Non-YDB dialect should not generate WITH clause", func(t *testing.T) { + query, _ := Dialect(dialect.Postgres). + CreateView("my_view"). + As(Select("*").From(Table("users"))). + Query() + + // Postgres should not have the WITH clause + require.NotContains(t, query, "WITH (security_invoker") + require.Contains(t, query, `CREATE VIEW "my_view" AS SELECT * FROM "users"`) + }) +} + func TestSelector_SetOperatorWithRecursive(t *testing.T) { t1, t2, t3 := Table("files"), Table("files"), Table("path") n := Queries{ @@ -1779,7 +2186,7 @@ func TestSelectWithLock(t *testing.T) { Where(EQ("id", 1)). ForUpdate() s.Query() - require.EqualError(t, s.Err(), "sql: SELECT .. FOR UPDATE/SHARE not supported in SQLite") + require.Contains(t, s.Err().Error(), "SELECT .. FOR UPDATE/SHARE is not supported") } func TestSelector_UnionOrderBy(t *testing.T) { diff --git a/dialect/sql/driver.go b/dialect/sql/driver.go index 1c4c9bd417..42193b5752 100644 --- a/dialect/sql/driver.go +++ b/dialect/sql/driver.go @@ -14,31 +14,75 @@ import ( "strings" "entgo.io/ent/dialect" + "github.com/ydb-platform/ydb-go-sdk/v3" ) // Driver is a dialect.Driver implementation for SQL based databases. type Driver struct { Conn - dialect string + dialect string + retryExecutor RetryExecutor } // NewDriver creates a new Driver with the given Conn and dialect. -func NewDriver(dialect string, c Conn) *Driver { - return &Driver{dialect: dialect, Conn: c} +func NewDriver( + dialect string, + c Conn, + retryExecutor RetryExecutor, +) *Driver { + return &Driver{ + Conn: c, + dialect: dialect, + retryExecutor: retryExecutor, + } } // Open wraps the database/sql.Open method and returns a dialect.Driver that implements the an ent/dialect.Driver interface. -func Open(dialect, source string) (*Driver, error) { - db, err := sql.Open(dialect, source) +func Open(sqlDialect, dsn string) (*Driver, error) { + var ( + db *sql.DB + err error + ) + + if sqlDialect == dialect.YDB { + nativeDriver, err := ydb.Open(context.Background(), dsn) + if err != nil { + return nil, err + } + + conn, err := ydb.Connector( + nativeDriver, + ydb.WithAutoDeclare(), + ydb.WithTablePathPrefix(nativeDriver.Name()), + ydb.WithQueryService(true), + ) + if err != nil { + return nil, err + } + + db = sql.OpenDB(conn) + } else { + db, err = sql.Open(sqlDialect, dsn) + } + if err != nil { return nil, err } - return NewDriver(dialect, Conn{db, dialect}), nil + + return NewDriver( + sqlDialect, + Conn{db, sqlDialect}, + NewRetryExecutor(sqlDialect, db), + ), nil } // OpenDB wraps the given database/sql.DB method with a Driver. -func OpenDB(dialect string, db *sql.DB) *Driver { - return NewDriver(dialect, Conn{db, dialect}) +func OpenDB(sqlDialect string, db *sql.DB) *Driver { + return NewDriver( + sqlDialect, + Conn{db, sqlDialect}, + NewRetryExecutor(sqlDialect, db), + ) } // DB returns the underlying *sql.DB instance. @@ -74,6 +118,10 @@ func (d *Driver) BeginTx(ctx context.Context, opts *TxOptions) (dialect.Tx, erro }, nil } +func (d *Driver) RetryExecutor() RetryExecutor { + return d.retryExecutor +} + // Close closes the underlying connection. func (d *Driver) Close() error { return d.DB().Close() } diff --git a/dialect/sql/retry.go b/dialect/sql/retry.go new file mode 100644 index 0000000000..22fe7ece75 --- /dev/null +++ b/dialect/sql/retry.go @@ -0,0 +1,95 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +package sql + +import ( + "context" + "database/sql" + + "entgo.io/ent/dialect" +) + +// RetryExecutor is an interface for database operations with automatic retries. +type RetryExecutor interface { + // Do executes the given function within a retry loop without a transaction. + // The function receives a dialect.Driver that wraps the connection. + // opts are driver-specific retry options (e.g., ydb retry.Option). + Do( + ctx context.Context, + fn func(ctx context.Context, drv dialect.Driver) error, + opts ...any, + ) error + + // DoTx executes the given function within a retry loop with a transaction. + // The function receives a dialect.Driver that wraps the database/sql.Tx transaction. + // opts are driver-specific retry options (e.g., ydb retry.Option). + DoTx( + ctx context.Context, + fn func(ctx context.Context, drv dialect.Driver) error, + opts ...any, + ) error +} + +// NewRetryExecutor creates a new RetryExecutor with the given database connection +func NewRetryExecutor( + sqlDialect string, + db *sql.DB, +) RetryExecutor { + if sqlDialect == dialect.YDB && db != nil { + return &YDBRetryExecutor{db: db} + } else { + return nil + } +} + +// RetryExecutorGetter is an optional interface that drivers can implement to provide +// a RetryExecutor for automatic retry handling. +// If a driver implements this interface, +// sqlgraph operations will use the RetryExecutor for database operations. +type RetryExecutorGetter interface { + // RetryExecutor returns the RetryExecutor for this driver. + // If nil is returned, no retry handling will be applied. + RetryExecutor() RetryExecutor +} + +// GetRetryExecutor returns the RetryExecutor for the given driver if available. +// If the driver is wrapped with a DebugDriver, the returned executor will preserve +// debug logging by wrapping the driver passed to callback functions. +func GetRetryExecutor(drv dialect.Driver) RetryExecutor { + drv, logFn := unwrapDebugDriver(drv) + + getter, ok := drv.(RetryExecutorGetter) + if !ok { + return nil + } + + executor := getter.RetryExecutor() + if executor == nil { + return nil + } + + if logFn != nil { + return &debugRetryExecutor{ + RetryExecutor: executor, + log: logFn, + } + } + return executor +} + +// unwrapDebugDriver extracts the underlying driver and log function from a DebugDriver. +func unwrapDebugDriver(drv dialect.Driver) (dialect.Driver, func(context.Context, ...any)) { + if debugDriver, ok := drv.(*dialect.DebugDriver); ok { + return debugDriver.Driver, debugDriver.Log() + } + return drv, nil +} + +// RetryConfig holds retry configuration for sqlgraph operations. +// This is used to pass retry options to the RetryExecutor. +type RetryConfig struct { + // Options are driver-specific retry options. + Options []any +} diff --git a/dialect/sql/retry_debug.go b/dialect/sql/retry_debug.go new file mode 100644 index 0000000000..3c7ba4e51e --- /dev/null +++ b/dialect/sql/retry_debug.go @@ -0,0 +1,47 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +package sql + +import ( + "context" + + "entgo.io/ent/dialect" +) + +// debugRetryExecutor wraps a RetryExecutor to preserve debug logging. +type debugRetryExecutor struct { + RetryExecutor + log func(context.Context, ...any) +} + +// Do executes the operation with debug logging preserved. +func (d *debugRetryExecutor) Do( + ctx context.Context, + fn func(ctx context.Context, drv dialect.Driver) error, + opts ...any, +) error { + return d.RetryExecutor.Do( + ctx, + func(ctx context.Context, drv dialect.Driver) error { + return fn(ctx, dialect.DebugWithContext(drv, d.log)) + }, + opts..., + ) +} + +// DoTx executes the operation within a transaction with debug logging preserved. +func (d *debugRetryExecutor) DoTx( + ctx context.Context, + fn func(ctx context.Context, drv dialect.Driver) error, + opts ...any, +) error { + return d.RetryExecutor.DoTx( + ctx, + func(ctx context.Context, drv dialect.Driver) error { + return fn(ctx, dialect.DebugWithContext(drv, d.log)) + }, + opts..., + ) +} diff --git a/dialect/sql/retry_ydb.go b/dialect/sql/retry_ydb.go new file mode 100644 index 0000000000..c2a58b3a0b --- /dev/null +++ b/dialect/sql/retry_ydb.go @@ -0,0 +1,104 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +package sql + +import ( + "context" + "database/sql" + + "entgo.io/ent/dialect" + "github.com/ydb-platform/ydb-go-sdk/v3/retry" +) + +// YDBRetryExecutor implements sqlgraph.YDBRetryExecutor for YDB +type YDBRetryExecutor struct { + db *sql.DB +} + +// Do executes a read-only operation with retry support. +// It uses ydb-go-sdk's retry.Do which handles YDB-specific retryable errors. +// Options should be created using retry.WithIdempotent(), retry.WithLabel(), etc. +func (r *YDBRetryExecutor) Do( + ctx context.Context, + fn func(ctx context.Context, drv dialect.Driver) error, + opts ...any, +) error { + return retry.Do( + ctx, + r.db, + func(ctx context.Context, conn *sql.Conn) error { + return fn(ctx, newConnRetryDriver(conn)) + }, + retry.WithDoRetryOptions(toRetryOptions(opts)...), + ) +} + +// DoTx executes the operation within a transaction with retry support. +// It uses ydb-go-sdk's retry.DoTx which handles YDB-specific retryable errors. +// Options should be created using retry.WithIdempotent(), retry.WithLabel(), etc. +func (r *YDBRetryExecutor) DoTx( + ctx context.Context, + fn func(ctx context.Context, drv dialect.Driver) error, + opts ...any, +) error { + return retry.DoTx( + ctx, + r.db, + func(ctx context.Context, tx *sql.Tx) error { + return fn(ctx, newTxRetryDriver(tx)) + }, + retry.WithDoTxRetryOptions(toRetryOptions(opts)...), + ) +} + +// toRetryOptions converts a slice of any options to retry.Option slice +func toRetryOptions(opts []any) []retry.Option { + retryOpts := make([]retry.Option, 0, len(opts)) + for _, opt := range opts { + if ro, ok := opt.(retry.Option); ok { + retryOpts = append(retryOpts, ro) + } + } + return retryOpts +} + +// ydbRetryDriver is designed for use only in sqlgraph, +// specifically - in retry.DoTx callbacks +type ydbRetryDriver struct { + Conn +} + +var _ dialect.Driver = (*ydbRetryDriver)(nil) + +// newConnRetryDriver creates a new RetryDriver from a database connection. +func newConnRetryDriver(conn *sql.Conn) *ydbRetryDriver { + return &ydbRetryDriver{ + Conn: Conn{ExecQuerier: conn}, + } +} + +// newTxRetryDriver creates a new RetryDriver from a transaction. +func newTxRetryDriver(tx *sql.Tx) *ydbRetryDriver { + return &ydbRetryDriver{ + Conn: Conn{ExecQuerier: tx}, + } +} + +// sqlgraph creates nested transactions in several methods. +// But YDB doesnt support nested transactions. +// Therefore, this methods returns no-op tx +func (d *ydbRetryDriver) Tx(ctx context.Context) (dialect.Tx, error) { + return dialect.NopTx(d), nil +} + +// Close is a no-op for RetryDriver since retry.DoTx manages the transaction lifecycle. +func (d *ydbRetryDriver) Close() error { + return nil +} + +// Dialect returns the YDB dialect name. +func (d *ydbRetryDriver) Dialect() string { + return dialect.YDB +} diff --git a/dialect/sql/schema/atlas.go b/dialect/sql/schema/atlas.go index d1704ca192..c4145161b7 100644 --- a/dialect/sql/schema/atlas.go +++ b/dialect/sql/schema/atlas.go @@ -626,35 +626,73 @@ func (a *Atlas) create(ctx context.Context, tables ...*Table) (err error) { if len(plan.Changes) == 0 { return nil } - // Open a transaction for backwards compatibility, - // even if the migration is not transactional. - tx, err := a.sqlDialect.Tx(ctx) - if err != nil { - return err - } - a.atDriver, err = a.sqlDialect.atOpen(tx) - if err != nil { - return err - } - // Apply plan (changes). - var applier Applier = ApplyFunc(func(ctx context.Context, tx dialect.ExecQuerier, plan *migrate.Plan) error { - for _, c := range plan.Changes { - if err := tx.Exec(ctx, c.Cmd, c.Args, nil); err != nil { - if c.Comment != "" { - err = fmt.Errorf("%s: %w", c.Comment, err) + + // YDB requires DDL operations to be executed outside of transactions. + if a.sqlDialect.Dialect() == dialect.YDB { + applier := ApplyFunc(func(ctx context.Context, conn dialect.ExecQuerier, plan *migrate.Plan) error { + for _, change := range plan.Changes { + err := conn.Exec( + ctx, + change.Cmd, + change.Args, + nil, + ) + if err != nil { + return wrapChangeError(change, err) } - return err } + return nil + }) + if err := a.applyWithHooks(ctx, a.sqlDialect, plan, applier); err != nil { + return fmt.Errorf("sql/schema: %w", err) } return nil - }) + } else { + // Open a transaction for backwards compatibility, + // even if the migration is not transactional. + tx, err := a.sqlDialect.Tx(ctx) + if err != nil { + return err + } + a.atDriver, err = a.sqlDialect.atOpen(tx) + if err != nil { + return err + } + applier := ApplyFunc(func(ctx context.Context, conn dialect.ExecQuerier, plan *migrate.Plan) error { + for _, change := range plan.Changes { + if err := conn.Exec(ctx, change.Cmd, change.Args, nil); err != nil { + return wrapChangeError(change, err) + } + } + return nil + }) + if err := a.applyWithHooks(ctx, tx, plan, applier); err != nil { + return errors.Join(fmt.Errorf("sql/schema: %w", err), tx.Rollback()) + } + return tx.Commit() + } +} + +// applyWithHooks wraps the given applier with the configured apply hooks and executes it. +func (a *Atlas) applyWithHooks( + ctx context.Context, + conn dialect.ExecQuerier, + plan *migrate.Plan, + base Applier, +) error { + applier := base for i := len(a.applyHook) - 1; i >= 0; i-- { applier = a.applyHook[i](applier) } - if err = applier.Apply(ctx, tx, plan); err != nil { - return errors.Join(fmt.Errorf("sql/schema: %w", err), tx.Rollback()) + return applier.Apply(ctx, conn, plan) +} + +// wrapChangeError wraps an error with the change comment if present. +func wrapChangeError(c *migrate.Change, err error) error { + if c.Comment != "" { + return fmt.Errorf("%s: %w", c.Comment, err) } - return tx.Commit() + return err } // For BC reason, we omit the schema qualifier from the migration plan. @@ -1065,6 +1103,11 @@ func (a *Atlas) aIndexes(et *Table, at *schema.Table) error { if err := a.sqlDialect.atIndex(idx1, at, idx2); err != nil { return err } + + if len(idx2.Parts) == 0 { + continue + } + desc := descIndexes(idx1) for _, p := range idx2.Parts { p.Desc = desc[p.C.Name] @@ -1126,6 +1169,8 @@ func (a *Atlas) entDialect(ctx context.Context, drv dialect.Driver) (sqlDialect, d = &SQLite{Driver: drv, WithForeignKeys: a.withForeignKeys} case dialect.Postgres: d = &Postgres{Driver: drv} + case dialect.YDB: + d = &YDB{Driver: drv} default: return nil, fmt.Errorf("sql/schema: unsupported dialect %q", a.dialect) } diff --git a/dialect/sql/schema/schema.go b/dialect/sql/schema/schema.go index 5bd04245c6..5fd0c307e8 100644 --- a/dialect/sql/schema/schema.go +++ b/dialect/sql/schema/schema.go @@ -17,6 +17,7 @@ import ( "ariga.io/atlas/sql/postgres" "ariga.io/atlas/sql/schema" "ariga.io/atlas/sql/sqlite" + "ariga.io/atlas/sql/ydb" entdialect "entgo.io/ent/dialect" "entgo.io/ent/dialect/entsql" "entgo.io/ent/dialect/sql" @@ -584,6 +585,14 @@ var drivers = func(v string) map[string]driver { postgres.DefaultDiff, postgres.DefaultPlan, }, + entdialect.YDB: { + &YDB{ + version: v, + Driver: nopDriver{dialect: entdialect.YDB}, + }, + ydb.DefaultDiff, + ydb.DefaultPlan, + }, } } diff --git a/dialect/sql/schema/ydb.go b/dialect/sql/schema/ydb.go new file mode 100644 index 0000000000..95a7494d4a --- /dev/null +++ b/dialect/sql/schema/ydb.go @@ -0,0 +1,343 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +package schema + +import ( + "context" + "database/sql" + "fmt" + "strings" + + "entgo.io/ent/dialect" + entsql "entgo.io/ent/dialect/sql" + "entgo.io/ent/schema/field" + + "ariga.io/atlas/sql/migrate" + "ariga.io/atlas/sql/schema" + atlas "ariga.io/atlas/sql/ydb" +) + +// YDB adapter for Atlas migration engine. +type YDB struct { + dialect.Driver + + version string +} + +// init loads the YDB version from the database for later use in the migration process. +func (d *YDB) init(ctx context.Context) error { + if d.version != "" { + return nil // already initialized. + } + + rows := &entsql.Rows{} + if err := d.Driver.Query(ctx, "SELECT version()", []any{}, rows); err != nil { + return fmt.Errorf("ydb: failed to query version: %w", err) + } + defer rows.Close() + + if !rows.Next() { + if err := rows.Err(); err != nil { + return err + } + return fmt.Errorf("ydb: version was not found") + } + + var version string + if err := rows.Scan(&version); err != nil { + return fmt.Errorf("ydb: failed to scan version: %w", err) + } + + d.version = version + return nil +} + +// tableExist checks if a table exists in the database by querying the .sys/tables system table. +func (d *YDB) tableExist(ctx context.Context, conn dialect.ExecQuerier, name string) (bool, error) { + query, args := entsql.Dialect(dialect.YDB). + Select(entsql.Count("*")). + From(entsql.Table(".sys/tables")). + Where(entsql.EQ("table_name", name)). + Query() + + return exist(ctx, conn, query, args...) +} + +// atOpen returns a custom Atlas migrate.Driver for YDB. +func (d *YDB) atOpen(conn dialect.ExecQuerier) (migrate.Driver, error) { + sqlDB := unwrapDB(conn) + if sqlDB == nil { + sqlDB = unwrapDB(d.Driver) + } + if sqlDB == nil { + return nil, fmt.Errorf("ydb: cannot get *sql.DB from %T (driver: %T)", conn, d.Driver) + } + return atlas.Open(sqlDB) +} + +func unwrapDB(db any) *sql.DB { + switch casted := db.(type) { + case interface{ DB() *sql.DB }: + return casted.DB() + case *YDB: + return unwrapDB(casted.Driver) + case *dialect.DebugDriver: + return unwrapDB(casted.Driver) + case *WriteDriver: + return unwrapDB(casted.Driver) + default: + return nil + } +} + +func (d *YDB) atTable(table1 *Table, table2 *schema.Table) { + if table1.Annotation != nil { + setAtChecks(table1, table2) + } +} + +// supportsDefault returns whether YDB supports DEFAULT values for the given column type. +func (d *YDB) supportsDefault(column *Column) bool { + switch column.Default.(type) { + case Expr, map[string]Expr: + // Expression defaults are not well supported in YDB + return false + default: + // Simple literal defaults should work for basic types + return column.supportDefault() + } +} + +// atTypeC converts an Ent column type to a YDB Atlas schema type. +func (d *YDB) atTypeC(column1 *Column, column2 *schema.Column) error { + // Check for custom schema type override. + if column1.SchemaType != nil && column1.SchemaType[dialect.YDB] != "" { + typ, err := atlas.ParseType( + column1.SchemaType[dialect.YDB], + ) + if err != nil { + return err + } + column2.Type.Type = typ + return nil + } + + var ( + typ schema.Type + err error + ) + + switch column1.Type { + case field.TypeBool: + typ = &schema.BoolType{T: atlas.TypeBool} + case field.TypeInt8: + typ = &schema.IntegerType{T: atlas.TypeInt8} + case field.TypeInt16: + typ = &schema.IntegerType{T: atlas.TypeInt16} + case field.TypeInt32: + typ = &schema.IntegerType{T: atlas.TypeInt32} + case field.TypeInt, field.TypeInt64: + typ = &schema.IntegerType{T: atlas.TypeInt64} + case field.TypeUint8: + typ = &schema.IntegerType{T: atlas.TypeUint8, Unsigned: true} + case field.TypeUint16: + typ = &schema.IntegerType{T: atlas.TypeUint16, Unsigned: true} + case field.TypeUint32: + typ = &schema.IntegerType{T: atlas.TypeUint32, Unsigned: true} + case field.TypeUint, field.TypeUint64: + typ = &schema.IntegerType{T: atlas.TypeUint64, Unsigned: true} + case field.TypeFloat32: + typ = &schema.FloatType{T: atlas.TypeFloat} + case field.TypeFloat64: + typ = &schema.FloatType{T: atlas.TypeDouble} + case field.TypeBytes: + typ = &schema.BinaryType{T: atlas.TypeString} + case field.TypeString: + typ = &schema.StringType{T: atlas.TypeUtf8} + case field.TypeJSON: + typ = &schema.JSONType{T: atlas.TypeJSON} + case field.TypeTime: + typ = &schema.TimeType{T: atlas.TypeTimestamp} + case field.TypeUUID: + typ = &schema.UUIDType{T: atlas.TypeUUID} + case field.TypeEnum: + // YDB doesn't support enum types in DDL statements + // But ent can handle enum validation, so we just map it to Utf8 + typ = &schema.StringType{T: atlas.TypeUtf8} + case field.TypeOther: + typ = &schema.UnsupportedType{T: column1.typ} + default: + typ, err = atlas.ParseType(column1.typ) + } + + if err != nil { + return err + } + + column2.Type.Type = typ + return nil +} + +// atUniqueC adds a unique constraint for a column. +// In YDB, unique constraints are implemented as GLOBAL UNIQUE indexes. +func (d *YDB) atUniqueC( + table1 *Table, + column1 *Column, + table2 *schema.Table, + column2 *schema.Column, +) { + if !canBeIndexKey(column1) { + return + } + + // Check if there's already an explicit unique index defined for this column. + for _, idx := range table1.Indexes { + if idx.Unique && len(idx.Columns) == 1 && idx.Columns[0].Name == column1.Name { + // Index already defined explicitly, will be added in atIndexes. + return + } + } + // Create a unique index for this column. + indexName := fmt.Sprintf("%s_%s_uniq_idx", table1.Name, column1.Name) + index := schema.NewUniqueIndex(indexName).AddParts(&schema.IndexPart{C: column2}) + + table2.AddIndexes(index) +} + +// atIncrementC configures auto-increment for a column. +// YDB uses Serial types for auto-increment. +func (d *YDB) atIncrementC(table *schema.Table, column *schema.Column) { + if intType, ok := column.Type.Type.(*schema.IntegerType); ok { + serial, err := atlas.SerialFromInt(intType) + if err != nil { + panic(err) + } + column.Type.Type = serial + } +} + +// atIncrementT sets the table-level auto-increment starting value. +func (d *YDB) atIncrementT(table *schema.Table, v int64) { + // not implemented +} + +// atIndex configures an index for ydb. +func (d *YDB) atIndex( + index1 *Index, + table2 *schema.Table, + index2 *schema.Index, +) error { + indexColumns := make([]string, 0) + for _, column1 := range index1.Columns { + if isPrimaryKeyColumn(table2, column1.Name) { + continue + } + + column2, ok := table2.Column(column1.Name) + if !ok { + return fmt.Errorf("unexpected index %q column: %q", index1.Name, column1.Name) + } + + if !canBeIndexKeyBySchema(column2) { + continue + } + + index2.AddParts(&schema.IndexPart{C: column2}) + indexColumns = append(indexColumns, column2.Name) + } + + // Set YDB-specific index attributes. + // By default, use GLOBAL SYNC for consistency. + idxAttrs := &atlas.IndexAttributes{} + + if index1.Annotation != nil { + annotation := index1.Annotation + + if len(annotation.IncludeColumns) > 0 { + columns := make([]*schema.Column, len(annotation.IncludeColumns)) + + for i, include := range annotation.IncludeColumns { + column, ok := table2.Column(include) + if !ok { + return fmt.Errorf("include column %q was not found for index %q", include, index1.Name) + } + columns[i] = column + } + + idxAttrs.CoverColumns = columns + } + + if indexType, ok := indexType(index1, dialect.YDB); ok { + upperIndexType := strings.ToUpper(indexType) + + if strings.Contains(upperIndexType, "ASYNC") { + idxAttrs.Async = true + } + if strings.Contains(upperIndexType, "UNIQUE") { + index2.Unique = true + } + } + } + + index2.Name = fmt.Sprintf( + "%s_%s_idx", + table2.Name, + strings.Join(indexColumns, "_"), + ) + + index2.AddAttrs(idxAttrs) + return nil +} + +// atTypeRangeSQL returns the SQL statement to insert type ranges for global unique IDs. +func (*YDB) atTypeRangeSQL(ts ...string) string { + values := make([]string, len(ts)) + for i, t := range ts { + values[i] = fmt.Sprintf("('%s')", t) + } + return fmt.Sprintf( + "UPSERT INTO `%s` (`type`) VALUES %s", + TypeTable, + strings.Join(values, ", "), + ) +} + +// canBeIndexKey checks if a column type can be used as an index key in YDB. +// YDB doesn't allow Float/Double types as index keys. +func canBeIndexKey(column *Column) bool { + switch column.Type { + case field.TypeFloat32, field.TypeFloat64: + return false + default: + return true + } +} + +// canBeIndexKeyBySchema checks if a column type can be used as an index key in YDB +// by checking the Atlas schema column type. +func canBeIndexKeyBySchema(column *schema.Column) bool { + if column.Type == nil || column.Type.Type == nil { + return true + } + switch column.Type.Type.(type) { + case *schema.FloatType: + return false + default: + return true + } +} + +// isPrimaryKeyColumn checks if a column is part of the table's primary key. +func isPrimaryKeyColumn(table *schema.Table, columnName string) bool { + if table.PrimaryKey == nil { + return false + } + for _, primaryKeyPart := range table.PrimaryKey.Parts { + if primaryKeyPart.C != nil && primaryKeyPart.C.Name == columnName { + return true + } + } + return false +} diff --git a/dialect/sql/sqlgraph/errors.go b/dialect/sql/sqlgraph/errors.go index 863cdc003f..fb63bf0ed0 100644 --- a/dialect/sql/sqlgraph/errors.go +++ b/dialect/sql/sqlgraph/errors.go @@ -28,6 +28,7 @@ func IsUniqueConstraintError(err error) bool { "Error 1062", // MySQL "violates unique constraint", // Postgres "UNIQUE constraint failed", // SQLite + "PRECONDITION_FAILED", // YDB unique index violation } { if strings.Contains(err.Error(), s) { return true diff --git a/dialect/sql/sqlgraph/graph.go b/dialect/sql/sqlgraph/graph.go index c41c6b9ca0..c70293bfc2 100644 --- a/dialect/sql/sqlgraph/graph.go +++ b/dialect/sql/sqlgraph/graph.go @@ -162,193 +162,256 @@ func (s *Step) ThroughEdgeTable() bool { // Neighbors returns a Selector for evaluating the path-step // and getting the neighbors of one vertex. -func Neighbors(dialect string, s *Step) (q *sql.Selector) { +func Neighbors(dialect string, step *Step) (query *sql.Selector) { builder := sql.Dialect(dialect) + switch { - case s.ThroughEdgeTable(): - pk1, pk2 := s.Edge.Columns[1], s.Edge.Columns[0] - if s.Edge.Inverse { - pk1, pk2 = pk2, pk1 + case step.ThroughEdgeTable(): + pk1, pk2 := step.Edge.Columns[0], step.Edge.Columns[1] + if step.Edge.Inverse { + pk2, pk1 = pk1, pk2 } - to := builder.Table(s.To.Table).Schema(s.To.Schema) - join := builder.Table(s.Edge.Table).Schema(s.Edge.Schema) - match := builder.Select(join.C(pk1)). + + to := builder.Table(step.To.Table).Schema(step.To.Schema) + join := builder.Table(step.Edge.Table).Schema(step.Edge.Schema) + + match := builder.Select(join.C(pk2)). From(join). - Where(sql.EQ(join.C(pk2), s.From.V)) - q = builder.Select(). + Where(sql.EQ(join.C(pk1), step.From.V)) + + query = builder.Select(). From(to). Join(match). - On(to.C(s.To.Column), match.C(pk1)) - case s.FromEdgeOwner(): - t1 := builder.Table(s.To.Table).Schema(s.To.Schema) - t2 := builder.Select(s.Edge.Columns[0]). - From(builder.Table(s.Edge.Table).Schema(s.Edge.Schema)). - Where(sql.EQ(s.From.Column, s.From.V)) - q = builder.Select(). - From(t1). - Join(t2). - On(t1.C(s.To.Column), t2.C(s.Edge.Columns[0])) - case s.ToEdgeOwner(): - q = builder.Select(). - From(builder.Table(s.To.Table).Schema(s.To.Schema)). - Where(sql.EQ(s.Edge.Columns[0], s.From.V)) + On(to.C(step.To.Column), match.C(pk2)) + + case step.FromEdgeOwner(): + table1 := builder.Table(step.To.Table).Schema(step.To.Schema) + + table2 := builder.Select(step.Edge.Columns[0]). + From(builder.Table(step.Edge.Table).Schema(step.Edge.Schema)). + Where(sql.EQ(step.From.Column, step.From.V)) + + query = builder.Select(). + From(table1). + Join(table2). + On(table1.C(step.To.Column), table2.C(step.Edge.Columns[0])) + + case step.ToEdgeOwner(): + query = builder.Select(). + From(builder.Table(step.To.Table).Schema(step.To.Schema)). + Where(sql.EQ(step.Edge.Columns[0], step.From.V)) } - return q + return query } // SetNeighbors returns a Selector for evaluating the path-step // and getting the neighbors of set of vertices. -func SetNeighbors(dialect string, s *Step) (q *sql.Selector) { - set := s.From.V.(*sql.Selector) +func SetNeighbors(dialect string, step *Step) (query *sql.Selector) { + set := step.From.V.(*sql.Selector) builder := sql.Dialect(dialect) + switch { - case s.ThroughEdgeTable(): - pk1, pk2 := s.Edge.Columns[1], s.Edge.Columns[0] - if s.Edge.Inverse { - pk1, pk2 = pk2, pk1 + case step.ThroughEdgeTable(): + pk1, pk2 := step.Edge.Columns[0], step.Edge.Columns[1] + if step.Edge.Inverse { + pk2, pk1 = pk1, pk2 } - to := builder.Table(s.To.Table).Schema(s.To.Schema) - set.Select(set.C(s.From.Column)) - join := builder.Table(s.Edge.Table).Schema(s.Edge.Schema) - match := builder.Select(join.C(pk1)). + + to := builder.Table(step.To.Table).Schema(step.To.Schema) + join := builder.Table(step.Edge.Table).Schema(step.Edge.Schema) + + set.Select(set.C(step.From.Column)) + + match := builder.Select(join.C(pk2)). From(join). Join(set). - On(join.C(pk2), set.C(s.From.Column)) - q = builder.Select(). + On(join.C(pk1), set.C(step.From.Column)) + + query = builder.Select(). From(to). Join(match). - On(to.C(s.To.Column), match.C(pk1)) - case s.FromEdgeOwner(): - t1 := builder.Table(s.To.Table).Schema(s.To.Schema) - set.Select(set.C(s.Edge.Columns[0])) - q = builder.Select(). - From(t1). + On(to.C(step.To.Column), match.C(pk2)) + + case step.FromEdgeOwner(): + table1 := builder.Table(step.To.Table).Schema(step.To.Schema) + set.Select(set.C(step.Edge.Columns[0])) + + query = builder.Select(). + From(table1). Join(set). - On(t1.C(s.To.Column), set.C(s.Edge.Columns[0])) - case s.ToEdgeOwner(): - t1 := builder.Table(s.To.Table).Schema(s.To.Schema) - set.Select(set.C(s.From.Column)) - q = builder.Select(). - From(t1). + On(table1.C(step.To.Column), set.C(step.Edge.Columns[0])) + + case step.ToEdgeOwner(): + table1 := builder.Table(step.To.Table).Schema(step.To.Schema) + set.Select(set.C(step.From.Column)) + + query = builder.Select(). + From(table1). Join(set). - On(t1.C(s.Edge.Columns[0]), set.C(s.From.Column)) + On(table1.C(step.Edge.Columns[0]), set.C(step.From.Column)) } - return q + return query } // HasNeighbors applies on the given Selector a neighbors check. -func HasNeighbors(q *sql.Selector, s *Step) { - builder := sql.Dialect(q.Dialect()) +func HasNeighbors(query *sql.Selector, step *Step) { + builder := sql.Dialect(query.Dialect()) + switch { - case s.ThroughEdgeTable(): - pk1 := s.Edge.Columns[0] - if s.Edge.Inverse { - pk1 = s.Edge.Columns[1] + case step.ThroughEdgeTable(): + pk1 := step.Edge.Columns[0] + if step.Edge.Inverse { + pk1 = step.Edge.Columns[1] } - join := builder.Table(s.Edge.Table).Schema(s.Edge.Schema) - q.Where( + + join := builder.Table(step.Edge.Table).Schema(step.Edge.Schema) + query.Where( sql.In( - q.C(s.From.Column), + query.C(step.From.Column), builder.Select(join.C(pk1)).From(join), ), ) - case s.FromEdgeOwner(): - q.Where(sql.NotNull(q.C(s.Edge.Columns[0]))) - case s.ToEdgeOwner(): - to := builder.Table(s.Edge.Table).Schema(s.Edge.Schema) + + case step.FromEdgeOwner(): + query.Where(sql.NotNull(query.C(step.Edge.Columns[0]))) + + case step.ToEdgeOwner(): + to := builder.Table(step.Edge.Table).Schema(step.Edge.Schema) // In case the edge reside on the same table, give // the edge an alias to make qualifier different. - if s.From.Table == s.Edge.Table { - to.As(fmt.Sprintf("%s_edge", s.Edge.Table)) - } - q.Where( - sql.Exists( - builder.Select(to.C(s.Edge.Columns[0])). - From(to). - Where( - sql.ColumnsEQ( - q.C(s.From.Column), - to.C(s.Edge.Columns[0]), + if step.From.Table == step.Edge.Table { + to.As(fmt.Sprintf("%s_edge", step.Edge.Table)) + } + + if query.Dialect() == dialect.YDB { + // YDB doesn't support correlated subqueries, use IN with subquery instead. + query.Where( + sql.In( + query.C(step.From.Column), + builder.Select(to.C(step.Edge.Columns[0])). + From(to). + Where(sql.NotNull(to.C(step.Edge.Columns[0]))), + ), + ) + } else { + query.Where( + sql.Exists( + builder.Select(to.C(step.Edge.Columns[0])). + From(to). + Where( + sql.ColumnsEQ( + query.C(step.From.Column), + to.C(step.Edge.Columns[0]), + ), ), - ), - ), - ) + ), + ) + } } } // HasNeighborsWith applies on the given Selector a neighbors check. // The given predicate applies its filtering on the selector. -func HasNeighborsWith(q *sql.Selector, s *Step, pred func(*sql.Selector)) { - builder := sql.Dialect(q.Dialect()) +func HasNeighborsWith( + query *sql.Selector, + step *Step, + predicate func(*sql.Selector), +) { + builder := sql.Dialect(query.Dialect()) + switch { - case s.ThroughEdgeTable(): - pk1, pk2 := s.Edge.Columns[1], s.Edge.Columns[0] - if s.Edge.Inverse { - pk1, pk2 = pk2, pk1 + case step.ThroughEdgeTable(): + pk1, pk2 := step.Edge.Columns[0], step.Edge.Columns[1] + if step.Edge.Inverse { + pk2, pk1 = pk1, pk2 } - to := builder.Table(s.To.Table).Schema(s.To.Schema) - edge := builder.Table(s.Edge.Table).Schema(s.Edge.Schema) - join := builder.Select(edge.C(pk2)). + + to := builder.Table(step.To.Table).Schema(step.To.Schema) + edge := builder.Table(step.Edge.Table).Schema(step.Edge.Schema) + + join := builder.Select(edge.C(pk1)). From(edge). Join(to). - On(edge.C(pk1), to.C(s.To.Column)) + On(edge.C(pk2), to.C(step.To.Column)) + matches := builder.Select().From(to) - matches.WithContext(q.Context()) - pred(matches) + matches.WithContext(query.Context()) + predicate(matches) join.FromSelect(matches) - q.Where(sql.In(q.C(s.From.Column), join)) - case s.FromEdgeOwner(): - to := builder.Table(s.To.Table).Schema(s.To.Schema) + + query.Where(sql.In(query.C(step.From.Column), join)) + + case step.FromEdgeOwner(): + to := builder.Table(step.To.Table).Schema(step.To.Schema) // Avoid ambiguity in case both source // and edge tables are the same. - if s.To.Table == q.TableName() { - to.As(fmt.Sprintf("%s_edge", s.To.Table)) + if step.To.Table == query.TableName() { + to.As(fmt.Sprintf("%s_edge", step.To.Table)) // Choose the alias name until we do not // have a collision. Limit to 5 iterations. for i := 1; i <= 5; i++ { - if to.C("c") != q.C("c") { + if to.C("c") != query.C("c") { break } - to.As(fmt.Sprintf("%s_edge_%d", s.To.Table, i)) + to.As(fmt.Sprintf("%s_edge_%d", step.To.Table, i)) } } - matches := builder.Select(to.C(s.To.Column)). - From(to) - matches.WithContext(q.Context()) - matches.Where( - sql.ColumnsEQ( - q.C(s.Edge.Columns[0]), - to.C(s.To.Column), - ), - ) - pred(matches) - q.Where(sql.Exists(matches)) - case s.ToEdgeOwner(): - to := builder.Table(s.Edge.Table).Schema(s.Edge.Schema) + + if query.Dialect() == dialect.YDB { + // YDB doesn't support correlated subqueries, use IN with subquery instead + matches := builder.Select(to.C(step.To.Column)).From(to) + matches.WithContext(query.Context()) + predicate(matches) + query.Where(sql.In(query.C(step.Edge.Columns[0]), matches)) + } else { + matches := builder.Select(to.C(step.To.Column)). + From(to) + matches.WithContext(query.Context()) + matches.Where( + sql.ColumnsEQ( + query.C(step.Edge.Columns[0]), + to.C(step.To.Column), + ), + ) + predicate(matches) + query.Where(sql.Exists(matches)) + } + + case step.ToEdgeOwner(): + to := builder.Table(step.Edge.Table).Schema(step.Edge.Schema) // Avoid ambiguity in case both source // and edge tables are the same. - if s.Edge.Table == q.TableName() { - to.As(fmt.Sprintf("%s_edge", s.Edge.Table)) + if step.Edge.Table == query.TableName() { + to.As(fmt.Sprintf("%s_edge", step.Edge.Table)) // Choose the alias name until we do not // have a collision. Limit to 5 iterations. for i := 1; i <= 5; i++ { - if to.C("c") != q.C("c") { + if to.C("c") != query.C("c") { break } - to.As(fmt.Sprintf("%s_edge_%d", s.Edge.Table, i)) + to.As(fmt.Sprintf("%s_edge_%d", step.Edge.Table, i)) } } - matches := builder.Select(to.C(s.Edge.Columns[0])). - From(to) - matches.WithContext(q.Context()) - matches.Where( - sql.ColumnsEQ( - q.C(s.From.Column), - to.C(s.Edge.Columns[0]), - ), - ) - pred(matches) - q.Where(sql.Exists(matches)) + + if query.Dialect() == dialect.YDB { + // YDB doesn't support correlated subqueries, using IN with subquery instead + matches := builder.Select(to.C(step.Edge.Columns[0])).From(to) + matches.WithContext(query.Context()) + predicate(matches) + query.Where(sql.In(query.C(step.From.Column), matches)) + } else { + matches := builder.Select(to.C(step.Edge.Columns[0])). + From(to) + matches.WithContext(query.Context()) + matches.Where( + sql.ColumnsEQ( + query.C(step.From.Column), + to.C(step.Edge.Columns[0]), + ), + ) + predicate(matches) + query.Where(sql.Exists(matches)) + } } } @@ -539,11 +602,12 @@ func OrderByNeighborTerms(q *sql.Selector, s *Step, opts ...sql.OrderTerm) { } toT := build.Table(s.To.Table).Schema(s.To.Schema) joinT := build.Table(s.Edge.Table).Schema(s.Edge.Schema) - join = build.Select(pk2). + join = build.SelectExpr(). From(toT). Join(joinT). - On(toT.C(s.To.Column), joinT.C(pk1)). - GroupBy(pk2) + On(toT.C(s.To.Column), joinT.C(pk1)) + join.AppendSelect(joinT.C(pk2)). + GroupBy(joinT.C(pk2)) selectTerms(join, opts) q.LeftJoin(join). On(q.C(s.From.Column), join.C(pk2)) @@ -711,6 +775,8 @@ type ( // } // OnConflict []sql.ConflictOption + + RetryConfig sql.RetryConfig } // BatchCreateSpec holds the information for creating @@ -728,6 +794,8 @@ type ( // } // OnConflict []sql.ConflictOption + + RetryConfig sql.RetryConfig } ) @@ -748,16 +816,58 @@ func (u *CreateSpec) SetField(column string, t field.Type, value driver.Value) { // CreateNode applies the CreateSpec on the graph. The operation creates a new // record in the database, and connects it to other nodes specified in spec.Edges. func CreateNode(ctx context.Context, drv dialect.Driver, spec *CreateSpec) error { - gr := graph{tx: drv, builder: sql.Dialect(drv.Dialect())} - cr := &creator{CreateSpec: spec, graph: gr} - return cr.node(ctx, drv) + return execWithRetryTx( + ctx, + drv, + spec.RetryConfig.Options, + func(ctx context.Context, d dialect.Driver) error { + gr := graph{tx: d, builder: sql.Dialect(drv.Dialect())} + cr := &creator{CreateSpec: spec, graph: gr} + return cr.node(ctx, d) + }, + ) } // BatchCreate applies the BatchCreateSpec on the graph. func BatchCreate(ctx context.Context, drv dialect.Driver, spec *BatchCreateSpec) error { - gr := graph{tx: drv, builder: sql.Dialect(drv.Dialect())} - cr := &batchCreator{BatchCreateSpec: spec, graph: gr} - return cr.nodes(ctx, drv) + return execWithRetryTx( + ctx, + drv, + spec.RetryConfig.Options, + func(ctx context.Context, d dialect.Driver) error { + gr := graph{tx: d, builder: sql.Dialect(drv.Dialect())} + cr := &batchCreator{BatchCreateSpec: spec, graph: gr} + return cr.nodes(ctx, d) + }, + ) +} + +// execWithRetryTx executes the operation with retry +// in a transaction if available, otherwise executes directly. +func execWithRetryTx( + ctx context.Context, + drv dialect.Driver, + opts []any, + op func(context.Context, dialect.Driver) error, +) error { + if retry := sql.GetRetryExecutor(drv); retry != nil { + return retry.DoTx(ctx, op, opts...) + } + return op(ctx, drv) +} + +// execWithRetry executes the operation with retry if available, otherwise executes directly. +// Use this for read-only operations that don't require a transaction. +func execWithRetry( + ctx context.Context, + drv dialect.Driver, + opts []any, + op func(context.Context, dialect.Driver) error, +) error { + if retry := sql.GetRetryExecutor(drv); retry != nil { + return retry.Do(ctx, op, opts...) + } + return op(ctx, drv) } type ( @@ -785,6 +895,8 @@ type ( ScanValues func(columns []string) ([]any, error) Assign func(columns []string, values []any) error + + RetryConfig sql.RetryConfig } ) @@ -840,23 +952,42 @@ func (u *UpdateSpec) ClearField(column string, t field.Type) { // UpdateNode applies the UpdateSpec on one node in the graph. func UpdateNode(ctx context.Context, drv dialect.Driver, spec *UpdateSpec) error { - tx, err := drv.Tx(ctx) - if err != nil { - return err - } - gr := graph{tx: tx, builder: sql.Dialect(drv.Dialect())} - cr := &updater{UpdateSpec: spec, graph: gr} - if err := cr.node(ctx, tx); err != nil { - return rollback(tx, err) - } - return tx.Commit() + return execWithRetryTx( + ctx, + drv, + spec.RetryConfig.Options, + func(ctx context.Context, d dialect.Driver) error { + tx, err := d.Tx(ctx) + if err != nil { + return err + } + gr := graph{tx: tx, builder: sql.Dialect(drv.Dialect())} + cr := &updater{UpdateSpec: spec, graph: gr} + if err := cr.node(ctx, tx); err != nil { + return rollback(tx, err) + } + return tx.Commit() + }, + ) } // UpdateNodes applies the UpdateSpec on a set of nodes in the graph. func UpdateNodes(ctx context.Context, drv dialect.Driver, spec *UpdateSpec) (int, error) { - gr := graph{tx: drv, builder: sql.Dialect(drv.Dialect())} - cr := &updater{UpdateSpec: spec, graph: gr} - return cr.nodes(ctx, drv) + var affected int + op := func(ctx context.Context, d dialect.Driver) error { + gr := graph{tx: d, builder: sql.Dialect(drv.Dialect())} + cr := &updater{UpdateSpec: spec, graph: gr} + n, err := cr.nodes(ctx, d) + if err != nil { + return err + } + affected = n + return nil + } + if err := execWithRetryTx(ctx, drv, spec.RetryConfig.Options, op); err != nil { + return 0, err + } + return affected, nil } // NotFoundError returns when trying to update an @@ -870,11 +1001,18 @@ func (e *NotFoundError) Error() string { return fmt.Sprintf("record with id %v not found in table %s", e.id, e.table) } +// IsNotFound returns true if the error is a NotFoundError or wraps one. +func IsNotFound(err error) bool { + var e *NotFoundError + return errors.As(err, &e) +} + // DeleteSpec holds the information for delete one // or more nodes in the graph. type DeleteSpec struct { - Node *NodeSpec - Predicate func(*sql.Selector) + Node *NodeSpec + Predicate func(*sql.Selector) + RetryConfig sql.RetryConfig } // NewDeleteSpec creates a new node deletion spec. @@ -884,25 +1022,48 @@ func NewDeleteSpec(table string, id *FieldSpec) *DeleteSpec { // DeleteNodes applies the DeleteSpec on the graph. func DeleteNodes(ctx context.Context, drv dialect.Driver, spec *DeleteSpec) (int, error) { - var ( - res sql.Result - builder = sql.Dialect(drv.Dialect()) - ) - selector := builder.Select(). - From(builder.Table(spec.Node.Table).Schema(spec.Node.Schema)). - WithContext(ctx) - if pred := spec.Predicate; pred != nil { - pred(selector) - } - query, args := builder.Delete(spec.Node.Table).Schema(spec.Node.Schema).FromSelect(selector).Query() - if err := drv.Exec(ctx, query, args, &res); err != nil { - return 0, err + var affected int + op := func(ctx context.Context, d dialect.Driver) error { + builder := sql.Dialect(drv.Dialect()) + selector := builder.Select(). + From(builder.Table(spec.Node.Table).Schema(spec.Node.Schema)). + WithContext(ctx) + if pred := spec.Predicate; pred != nil { + pred(selector) + } + delete := builder.Delete(spec.Node.Table).Schema(spec.Node.Schema).FromSelect(selector) + + // YDB doesn't return accurate RowsAffected(), so we use RETURNING to count deleted rows. + if drv.Dialect() == dialect.YDB { + delete.Returning(spec.Node.ID.Column) + query, args := delete.Query() + rows := &sql.Rows{} + if err := d.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + for rows.Next() { + affected++ + } + return rows.Err() + } + + query, args := delete.Query() + var res sql.Result + if err := d.Exec(ctx, query, args, &res); err != nil { + return err + } + n, err := res.RowsAffected() + if err != nil { + return err + } + affected = int(n) + return nil } - affected, err := res.RowsAffected() - if err != nil { + if err := execWithRetryTx(ctx, drv, spec.RetryConfig.Options, op); err != nil { return 0, err } - return int(affected), nil + return affected, nil } // QuerySpec holds the information for querying @@ -920,6 +1081,8 @@ type QuerySpec struct { ScanValues func(columns []string) ([]any, error) Assign func(columns []string, values []any) error + + RetryConfig sql.RetryConfig } // NewQuerySpec creates a new node query spec. @@ -935,25 +1098,45 @@ func NewQuerySpec(table string, columns []string, id *FieldSpec) *QuerySpec { // QueryNodes queries the nodes in the graph query and scans them to the given values. func QueryNodes(ctx context.Context, drv dialect.Driver, spec *QuerySpec) error { - builder := sql.Dialect(drv.Dialect()) - qr := &query{graph: graph{builder: builder}, QuerySpec: spec} - return qr.nodes(ctx, drv) + return execWithRetry( + ctx, + drv, + spec.RetryConfig.Options, + func(ctx context.Context, d dialect.Driver) error { + builder := sql.Dialect(drv.Dialect()) + qr := &query{graph: graph{builder: builder}, QuerySpec: spec} + return qr.nodes(ctx, d) + }, + ) } // CountNodes counts the nodes in the given graph query. func CountNodes(ctx context.Context, drv dialect.Driver, spec *QuerySpec) (int, error) { - builder := sql.Dialect(drv.Dialect()) - qr := &query{graph: graph{builder: builder}, QuerySpec: spec} - return qr.count(ctx, drv) + var count int + op := func(ctx context.Context, d dialect.Driver) error { + builder := sql.Dialect(drv.Dialect()) + qr := &query{graph: graph{builder: builder}, QuerySpec: spec} + n, err := qr.count(ctx, d) + if err != nil { + return err + } + count = n + return nil + } + if err := execWithRetry(ctx, drv, spec.RetryConfig.Options, op); err != nil { + return 0, err + } + return count, nil } // EdgeQuerySpec holds the information for querying // edges in the graph. type EdgeQuerySpec struct { - Edge *EdgeSpec - Predicate func(*sql.Selector) - ScanValues func() [2]any - Assign func(out, in any) error + Edge *EdgeSpec + Predicate func(*sql.Selector) + ScanValues func() [2]any + Assign func(out, in any) error + RetryConfig sql.RetryConfig } // QueryEdges queries the edges in the graph and scans the result with the given dest function. @@ -961,32 +1144,39 @@ func QueryEdges(ctx context.Context, drv dialect.Driver, spec *EdgeQuerySpec) er if len(spec.Edge.Columns) != 2 { return fmt.Errorf("sqlgraph: edge query requires 2 columns (out, in)") } - out, in := spec.Edge.Columns[0], spec.Edge.Columns[1] - if spec.Edge.Inverse { - out, in = in, out - } - selector := sql.Dialect(drv.Dialect()). - Select(out, in). - From(sql.Table(spec.Edge.Table).Schema(spec.Edge.Schema)) - if p := spec.Predicate; p != nil { - p(selector) - } - rows := &sql.Rows{} - query, args := selector.Query() - if err := drv.Query(ctx, query, args, rows); err != nil { - return err - } - defer rows.Close() - for rows.Next() { - values := spec.ScanValues() - if err := rows.Scan(values[0], values[1]); err != nil { - return err - } - if err := spec.Assign(values[0], values[1]); err != nil { - return err - } - } - return rows.Err() + return execWithRetry( + ctx, + drv, + spec.RetryConfig.Options, + func(ctx context.Context, d dialect.Driver) error { + out, in := spec.Edge.Columns[0], spec.Edge.Columns[1] + if spec.Edge.Inverse { + out, in = in, out + } + selector := sql.Dialect(drv.Dialect()). + Select(out, in). + From(sql.Table(spec.Edge.Table).Schema(spec.Edge.Schema)) + if p := spec.Predicate; p != nil { + p(selector) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := d.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + for rows.Next() { + values := spec.ScanValues() + if err := rows.Scan(values[0], values[1]); err != nil { + return err + } + if err := spec.Assign(values[0], values[1]); err != nil { + return err + } + } + return rows.Err() + }, + ) } type query struct { @@ -1142,12 +1332,13 @@ func (u *updater) node(ctx context.Context, tx dialect.ExecQuerier) error { return err } if !update.Empty() { - var res sql.Result - query, args := update.Query() - if err := tx.Exec(ctx, query, args, &res); err != nil { - return err + var returningColumn string + if u.Node.ID != nil { + returningColumn = u.Node.ID.Column + } else { + returningColumn = u.Node.CompositeID[0].Column } - affected, err := res.RowsAffected() + affected, err := execUpdate(ctx, tx, update, returningColumn) if err != nil { return err } @@ -1274,14 +1465,14 @@ func (u *updater) updateTable(ctx context.Context, stmt *sql.UpdateBuilder) (int if stmt.Empty() { return 0, nil } - var ( - res sql.Result - query, args = stmt.Query() - ) - if err := u.tx.Exec(ctx, query, args, &res); err != nil { - return 0, err + // Determine the ID column for RETURNING (needed for YDB). + var idColumn string + if u.Node.ID != nil { + idColumn = u.Node.ID.Column + } else if len(u.Node.CompositeID) > 0 { + idColumn = u.Node.CompositeID[0].Column } - affected, err := res.RowsAffected() + affected, err := execUpdate(ctx, u.tx, stmt, idColumn) if err != nil { return 0, err } @@ -1376,20 +1567,40 @@ func (u *updater) scan(rows *sql.Rows) error { } func (u *updater) ensureExists(ctx context.Context) error { - exists := u.builder.Select().From(u.builder.Table(u.Node.Table).Schema(u.Node.Schema)).Where(sql.EQ(u.Node.ID.Column, u.Node.ID.Value)) - u.Predicate(exists) - query, args := u.builder.SelectExpr(sql.Exists(exists)).Query() + selector := u.builder. + Select(). + From(u.builder.Table(u.Node.Table).Schema(u.Node.Schema)) + + var idValue any + if u.Node.ID != nil { + selector.Where(sql.EQ(u.Node.ID.Column, u.Node.ID.Value)) + idValue = u.Node.ID.Value + } else { + selector.Where(sql.And( + sql.EQ(u.Node.CompositeID[0].Column, u.Node.CompositeID[0].Value), + sql.EQ(u.Node.CompositeID[1].Column, u.Node.CompositeID[1].Value), + )) + idValue = []any{u.Node.CompositeID[0].Value, u.Node.CompositeID[1].Value} + } + u.Predicate(selector) + + var query string + var args []any + + query, args = u.builder.SelectExpr(sql.Exists(selector)).Query() + rows := &sql.Rows{} if err := u.tx.Query(ctx, query, args, rows); err != nil { return err } defer rows.Close() + found, err := sql.ScanBool(rows) if err != nil { return err } if !found { - return &NotFoundError{table: u.Node.Table, id: u.Node.ID.Value} + return &NotFoundError{table: u.Node.Table, id: idValue} } return nil } @@ -1402,8 +1613,19 @@ type creator struct { func (c *creator) node(ctx context.Context, drv dialect.Driver) error { var ( edges = EdgeSpecs(c.Edges).GroupRel() - insert = c.builder.Insert(c.Table).Schema(c.Schema).Default() + insert *sql.InsertBuilder ) + + if c.builder.Dialect() == dialect.YDB { + // For YDB: use UPSERT only when OnConflict options are specified, + if len(c.CreateSpec.OnConflict) > 0 { + insert = c.builder.Upsert(c.Table).Schema(c.Schema) + } else { + insert = c.builder.Insert(c.Table).Schema(c.Schema) + } + } else { + insert = c.builder.Insert(c.Table).Schema(c.Schema).Default() + } if err := c.setTableColumns(insert, edges); err != nil { return err } @@ -1477,6 +1699,10 @@ func (c *creator) insert(ctx context.Context, insert *sql.InsertBuilder) error { // ensureConflict ensures the ON CONFLICT is added to the insert statement. func (c *creator) ensureConflict(insert *sql.InsertBuilder) { + // YDB doesn't support ON CONFLICT clause - UPSERT handles conflicts implicitly. + if insert.Dialect() == dialect.YDB { + return + } if opts := c.CreateSpec.OnConflict; len(opts) > 0 { insert.OnConflict(opts...) c.ensureLastInsertID(insert) @@ -1543,7 +1769,19 @@ func (c *batchCreator) nodes(ctx context.Context, drv dialect.Driver) error { } } sorted := keys(columns) - insert := c.builder.Insert(c.Nodes[0].Table).Schema(c.Nodes[0].Schema).Default().Columns(sorted...) + + var insert *sql.InsertBuilder + if c.builder.Dialect() == dialect.YDB { + // For YDB: use UPSERT only when OnConflict options are specified, + if len(c.BatchCreateSpec.OnConflict) > 0 { + insert = c.builder.Upsert(c.Nodes[0].Table).Schema(c.Nodes[0].Schema).Columns(sorted...) + } else { + insert = c.builder.Insert(c.Nodes[0].Table).Schema(c.Nodes[0].Schema).Columns(sorted...) + } + } else { + insert = c.builder.Insert(c.Nodes[0].Table).Schema(c.Nodes[0].Schema).Default().Columns(sorted...) + } + for i := range values { vs := make([]any, len(sorted)) for j, c := range sorted { @@ -1605,6 +1843,10 @@ func (c *batchCreator) batchInsert(ctx context.Context, tx dialect.ExecQuerier, // ensureConflict ensures the ON CONFLICT is added to the insert statement. func (c *batchCreator) ensureConflict(insert *sql.InsertBuilder) { + // YDB doesn't support ON CONFLICT clause - UPSERT handles conflicts implicitly. + if insert.Dialect() == dialect.YDB { + return + } if opts := c.BatchCreateSpec.OnConflict; len(opts) > 0 { insert.OnConflict(opts...) } @@ -1708,7 +1950,15 @@ func (g *graph) addM2MEdges(ctx context.Context, ids []driver.Value, edges EdgeS values = append(values, f.Value) columns = append(columns, f.Column) } - insert := g.builder.Insert(table).Columns(columns...) + + // YDB doesn't support ON CONFLICT clause. Use UPSERT for M2M edges without extra fields + var insert *sql.InsertBuilder + if len(edges[0].Target.Fields) == 0 && g.builder.Dialect() == dialect.YDB { + insert = g.builder.Upsert(table).Columns(columns...) + } else { + insert = g.builder.Insert(table).Columns(columns...) + } + if edges[0].Schema != "" { // If the Schema field was provided to the EdgeSpec (by the // generated code), it should be the same for all EdgeSpecs. @@ -1728,7 +1978,8 @@ func (g *graph) addM2MEdges(ctx context.Context, ids []driver.Value, edges EdgeS } // Ignore conflicts only if edges do not contain extra fields, because these fields // can hold different values on different insertions (e.g. time.Now() or uuid.New()). - if len(edges[0].Target.Fields) == 0 { + // YDB doesn't support ON CONFLICT clause, so skip it for YDB dialect. + if len(edges[0].Target.Fields) == 0 && insert.Dialect() != dialect.YDB { insert.OnConflict(sql.DoNothing()) } query, args := insert.Query() @@ -1755,7 +2006,14 @@ func (g *graph) batchAddM2M(ctx context.Context, spec *BatchCreateSpec) error { for _, f := range edge.Target.Fields { columns = append(columns, f.Column) } - insert = g.builder.Insert(name).Columns(columns...) + + // YDB doesn't support ON CONFLICT clause. Use UPSERT for M2M edges without extra fields. + if len(edge.Target.Fields) == 0 && g.builder.Dialect() == dialect.YDB { + insert = g.builder.Upsert(name).Columns(columns...) + } else { + insert = g.builder.Insert(name).Columns(columns...) + } + if edge.Schema != "" { // If the Schema field was provided to the EdgeSpec (by the // generated code), it should be the same for all EdgeSpecs. @@ -1763,7 +2021,8 @@ func (g *graph) batchAddM2M(ctx context.Context, spec *BatchCreateSpec) error { } // Ignore conflicts only if edges do not contain extra fields, because these fields // can hold different values on different insertions (e.g. time.Now() or uuid.New()). - if len(edge.Target.Fields) == 0 { + // YDB doesn't support ON CONFLICT clause, so skip it for YDB dialect. + if len(edge.Target.Fields) == 0 && insert.Dialect() != dialect.YDB { insert.OnConflict(sql.DoNothing()) } } @@ -1828,19 +2087,17 @@ func (g *graph) addFKEdges(ctx context.Context, ids []driver.Value, edges []*Edg if len(edge.Target.Nodes) > 1 { p = sql.InValues(edge.Target.IDSpec.Column, edge.Target.Nodes...) } - query, args := g.builder.Update(edge.Table). + + update := g.builder.Update(edge.Table). Schema(edge.Schema). Set(edge.Columns[0], id). - Where(sql.And(p, sql.IsNull(edge.Columns[0]))). - Query() - var res sql.Result - if err := g.tx.Exec(ctx, query, args, &res); err != nil { - return fmt.Errorf("add %s edge for table %s: %w", edge.Rel, edge.Table, err) - } - affected, err := res.RowsAffected() + Where(sql.And(p, sql.IsNull(edge.Columns[0]))) + + affected, err := execUpdate(ctx, g.tx, update, edge.Target.IDSpec.Column) if err != nil { - return err + return fmt.Errorf("add %s edge for table %s: %w", edge.Rel, edge.Table, err) } + // Setting the FK value of the "other" table without clearing it before, is not allowed. // Including no-op (same id), because we rely on "affected" to determine if the FK set. if ids := edge.Target.Nodes; int(affected) < len(ids) { @@ -1867,6 +2124,44 @@ func hasExternalEdges(addEdges, clearEdges map[Rel][]*EdgeSpec) bool { return false } +// execUpdate executes an UPDATE and returns the number of affected rows. +// For YDB, it uses RETURNING clause since RowsAffected() is unreliable. +func execUpdate( + ctx context.Context, + tx dialect.ExecQuerier, + update *sql.UpdateBuilder, + returningColumn string, +) (int64, error) { + if update.Dialect() == dialect.YDB { + update.Returning(returningColumn) + + query, args := update.Query() + rows := &sql.Rows{} + if err := tx.Query(ctx, query, args, rows); err != nil { + return 0, err + } + defer rows.Close() + + var affected int64 + for rows.Next() { + affected++ + } + + if err := rows.Err(); err != nil { + return 0, err + } + + return affected, nil + } else { + query, args := update.Query() + var res sql.Result + if err := tx.Exec(ctx, query, args, &res); err != nil { + return 0, err + } + return res.RowsAffected() + } +} + // isExternalEdge reports if the given edge requires an UPDATE // or an INSERT to other table. func isExternalEdge(e *EdgeSpec) bool { diff --git a/dialect/sql/sqlgraph/graph_test.go b/dialect/sql/sqlgraph/graph_test.go index 13bcf87ae2..64782f6ec8 100644 --- a/dialect/sql/sqlgraph/graph_test.go +++ b/dialect/sql/sqlgraph/graph_test.go @@ -1072,7 +1072,7 @@ func TestOrderByNeighborTerms(t *testing.T) { ) query, args := s.Query() require.Empty(t, args) - require.Equal(t, `SELECT "users"."name", "t1"."total_users" FROM "users" LEFT JOIN (SELECT "user_id", SUM("group"."num_users") AS "total_users" FROM "group" JOIN "user_groups" AS "t1" ON "group"."id" = "t1"."group_id" GROUP BY "user_id") AS "t1" ON "users"."id" = "t1"."user_id" ORDER BY "t1"."total_users" NULLS FIRST`, query) + require.Equal(t, `SELECT "users"."name", "t1"."total_users" FROM "users" LEFT JOIN (SELECT "t1"."user_id", SUM("group"."num_users") AS "total_users" FROM "group" JOIN "user_groups" AS "t1" ON "group"."id" = "t1"."group_id" GROUP BY "t1"."user_id") AS "t1" ON "users"."id" = "t1"."user_id" ORDER BY "t1"."total_users" NULLS FIRST`, query) }) t.Run("M2M/NullsLast", func(t *testing.T) { s := s.Clone() @@ -1090,7 +1090,7 @@ func TestOrderByNeighborTerms(t *testing.T) { ) query, args := s.Query() require.Empty(t, args) - require.Equal(t, `SELECT "users"."name" FROM "users" LEFT JOIN (SELECT "user_id", SUM("group"."num_users") AS "total_users" FROM "group" JOIN "user_groups" AS "t1" ON "group"."id" = "t1"."group_id" GROUP BY "user_id") AS "t1" ON "users"."id" = "t1"."user_id" ORDER BY "t1"."total_users" NULLS LAST`, query) + require.Equal(t, `SELECT "users"."name" FROM "users" LEFT JOIN (SELECT "t1"."user_id", SUM("group"."num_users") AS "total_users" FROM "group" JOIN "user_groups" AS "t1" ON "group"."id" = "t1"."group_id" GROUP BY "t1"."user_id") AS "t1" ON "users"."id" = "t1"."user_id" ORDER BY "t1"."total_users" NULLS LAST`, query) }) } diff --git a/doc/md/dialects.md b/doc/md/dialects.md index f189b8eeed..06c159e8a9 100644 --- a/doc/md/dialects.md +++ b/doc/md/dialects.md @@ -39,3 +39,9 @@ TiDB support is in preview and requires the [Atlas migration engine](migrate.md# TiDB is MySQL compatible and thus any feature that works on MySQL _should_ work on TiDB as well. For a list of known compatibility issues, visit: https://docs.pingcap.com/tidb/stable/mysql-compatibility The integration with TiDB is currently tested on versions `5.4.0`, `6.0.0`. + +## YDB **(preview)** + +YDB (Yandex Database) support is in preview and requires the [Atlas migration engine](migrate.md#atlas-integration). +YDB is a distributed SQL database that supports automatic retries for transient errors. +For detailed information about driver setup, retry handling, and YDB-specific features, see the [YDB documentation](ydb.md). diff --git a/doc/md/getting-started.mdx b/doc/md/getting-started.mdx index 112e43109f..d8e3d2ddb1 100644 --- a/doc/md/getting-started.mdx +++ b/doc/md/getting-started.mdx @@ -117,6 +117,7 @@ values={[ {label: 'SQLite', value: 'sqlite'}, {label: 'PostgreSQL', value: 'postgres'}, {label: 'MySQL (MariaDB)', value: 'mysql'}, +{label: 'YDB', value: 'ydb'}, ]}> @@ -207,6 +208,38 @@ func main() { } ``` + + + +```go title="entdemo/start.go" +package main + +import ( + "context" + "log" + + "entdemo/ent" +) + +func main() { + client, err := ent.Open("ydb", "grpc://localhost:2136/local") + if err != nil { + log.Fatalf("failed opening connection to ydb: %v", err) + } + defer client.Close() + // Run the auto migration tool. + // highlight-start + if err := client.Schema.Create(context.Background()); err != nil { + log.Fatalf("failed creating schema resources: %v", err) + } + // highlight-end +} +``` + +:::note +YDB support is in preview. See the [YDB documentation](ydb.md) for details on retry handling and YDB-specific features. +::: + diff --git a/doc/md/ydb.md b/doc/md/ydb.md new file mode 100644 index 0000000000..7848648872 --- /dev/null +++ b/doc/md/ydb.md @@ -0,0 +1,179 @@ +--- +id: ydb +title: YDB +--- + +## Overview + +[YDB](https://ydb.tech/) is a distributed SQL database developed by Yandex. It provides horizontal scalability, +strong consistency, and automatic handling of transient errors. This page covers YDB-specific features and +considerations when using ent with YDB. + +:::note +YDB support is currently in **preview** and requires the [Atlas migration engine](migrate.md#atlas-integration). +::: + +## Opening a Connection + +To connect to YDB, use the standard `ent.Open()` function with the `"ydb"` dialect: + +```go +package main + +import ( + "context" + "log" + + "entdemo/ent" +) + +func main() { + // Open connection to YDB + client, err := ent.Open("ydb", "grpc://localhost:2136/local") + if err != nil { + log.Fatalf("failed opening connection to ydb: %v", err) + } + defer client.Close() + + ctx := context.Background() + // Run the auto migration tool + if err := client.Schema.Create(ctx); err != nil { + log.Fatalf("failed creating schema resources: %v", err) + } +} +``` + +## Interactive & Non-Interactive Transactions + +It is important to say that every request in YDB is executed in a transaction. +YDB supports two modes of working with transactions, and ent uses both depending on the API you choose. + +### Non-interactive transactions + +When you use the standard CRUD builders (`.Create()`, `.Query()`, `.Update()`, `.Delete()`), ent executes them through ydb-go-sdk's retry helpers: + +- **Write operations** (Create, Update, Delete) go through + [`retry.DoTx`](https://pkg.go.dev/github.com/ydb-platform/ydb-go-sdk/v3/retry#DoTx) — the SDK + begins a transaction, executes the operation as a **callback**, commits, and on a transient error + rolls back and re-executes the callback from scratch. +- **Read operations** (Query) go through + [`retry.Do`](https://pkg.go.dev/github.com/ydb-platform/ydb-go-sdk/v3/retry#Do) — the SDK + obtains a connection, executes the read callback, and retries on transient errors. No explicit + transaction is created; the read runs with an implicit snapshot. + +This is the recommended way to work with YDB through ent. Automatic retries and session management +are handled transparently. + +### Interactive transactions + +When you call `Client.BeginTx()`, ent opens a transaction via the standard `database/sql` API and **returns a `Tx` object** to the caller. You then perform operations on it and manually call +`Commit()` or `Rollback()`. In this model: + +- There is **no callback** for the SDK to re-execute, so automatic retries are not possible. +- Session and transaction lifetime are managed by your code. + +Use interactive transactions only when you need explicit control over commit/rollback boundaries +that can't be expressed through the standard builders. + +## Automatic Retry Mechanism + +Since YDB is a distributed database, it requires special handling for transient errors (network issues, temporary unavailability, etc.). +The ent YDB driver integrates with [ydb-go-sdk's retry package](https://pkg.go.dev/github.com/ydb-platform/ydb-go-sdk/v3/retry) +to automatically handle these scenarios. + +:::note +However, ent does not use automatic retries when you create an interactive transaction using `Client.BeginTx()`. [Read more](ydb.md#no-automatic-retries-when-using-clientbegintx). +::: + +### Using WithRetryOptions + +All CRUD operations support the `WithRetryOptions()` method to configure retry behavior: + +```go +import "github.com/ydb-platform/ydb-go-sdk/v3/retry" + +// Create with retry options +user, err := client.User.Create(). + SetName("John"). + SetAge(30). + WithRetryOptions(retry.WithIdempotent(true)). + Save(ctx) + +// Query with retry options +users, err := client.User.Query(). + Where(user.AgeGT(18)). + WithRetryOptions(retry.WithIdempotent(true)). + All(ctx) + +// Update with retry options +affected, err := client.User.Update(). + Where(user.NameEQ("John")). + SetAge(31). + WithRetryOptions(retry.WithIdempotent(true)). + Save(ctx) + +// Delete with retry options +affected, err := client.User.Delete(). + Where(user.NameEQ("John")). + WithRetryOptions(retry.WithIdempotent(true)). + Exec(ctx) +``` + +### Retry Options + +Common retry options from `ydb-go-sdk`: + +| Option | Description | +|--------|-------------| +| `retry.WithIdempotent(true)` | Mark operation as idempotent, allowing retries on more error types | +| `retry.WithLabel(string)` | Add a label for debugging/tracing | +| `retry.WithTrace(trace.Retry)` | Enable retry tracing | + +## Known Limitations + +When using ent with YDB, be aware of the following limitations: + +### No automatic retries when using Client.BeginTx + +`Client.BeginTx()` returns a transaction object to the caller instead of accepting a callback, +so the retry mechanism from ydb-go-sdk cannot be applied. See +[Interactive transactions](ydb.md#interactive-transactions) for a detailed explanation. + +If you still need interactive transactions, you may write a retry wrapper manually, as done in +[ydb-go-sdk's examples](https://github.com/ydb-platform/ydb-go-sdk/blob/master/examples/basic/database/sql/series.go). + +### No Nested Transactions + +YDB uses flat transactions and doesn't support nested transactions. The ent YDB driver +handles this by returning a no-op transaction when nested transactions are requested. + +### No Correlated Subqueries + +YDB doesn't support correlated subqueries with `EXISTS` or `NOT EXISTS`. Ent automatically +rewrites such queries to use `IN` with subqueries instead. + +### Float/Double Index Restriction + +YDB doesn't allow `Float` or `Double` types as index keys. If you define an index on a +float field, it will be skipped during migration. + +### No Native Enum Types + +YDB doesn't support enum types in DDL statements. Ent maps enum fields to `Utf8` (string) +type, with validation handled at the application level. + +### Primary Key Requirements + +YDB requires explicit primary keys for all tables. Make sure your ent schemas define +appropriate ID fields. + +## Example Project + +A complete working example is available in the ent repository: +[examples/ydb](https://github.com/ent/ent/tree/master/examples/ydb) + +This example demonstrates: +- Opening a YDB connection +- Schema creation with migrations +- CRUD operations with retry options +- Edge traversals diff --git a/entc/gen/feature.go b/entc/gen/feature.go index 1b0c37e4f9..344142a7a5 100644 --- a/entc/gen/feature.go +++ b/entc/gen/feature.go @@ -159,6 +159,15 @@ var ( }, } + // FeatureRetryOptions provides a feature-flag for adding retry options to query/mutation builders. + // This is primarily useful for databases like YDB that require explicit retry handling. + FeatureRetryOptions = Feature{ + Name: "sql/retryoptions", + Stage: Experimental, + Default: false, + Description: "Adds WithRetryOptions methods to builders for databases that require explicit retry handling (e.g., YDB)", + } + // AllFeatures holds a list of all feature-flags. AllFeatures = []Feature{ FeaturePrivacy, @@ -174,6 +183,7 @@ var ( FeatureUpsert, FeatureVersionedMigration, FeatureGlobalID, + FeatureRetryOptions, } // allFeatures includes all public and private features. allFeatures = append(AllFeatures, featureMultiSchema) diff --git a/entc/gen/storage.go b/entc/gen/storage.go index 9a01d683a9..bbf89356ad 100644 --- a/entc/gen/storage.go +++ b/entc/gen/storage.go @@ -54,7 +54,7 @@ var drivers = []*Storage{ Name: "sql", IdentName: "SQL", Builder: reflect.TypeOf(&sql.Selector{}), - Dialects: []string{"dialect.SQLite", "dialect.MySQL", "dialect.Postgres"}, + Dialects: []string{"dialect.SQLite", "dialect.MySQL", "dialect.Postgres", "dialect.YDB"}, Imports: []string{ "database/sql/driver", "entgo.io/ent/dialect/sql", diff --git a/entc/gen/template/builder/delete.tmpl b/entc/gen/template/builder/delete.tmpl index 513f2b502b..c1ad612fef 100644 --- a/entc/gen/template/builder/delete.tmpl +++ b/entc/gen/template/builder/delete.tmpl @@ -26,6 +26,11 @@ type {{ $builder }} struct { config hooks []Hook mutation *{{ $.MutationName }} + {{- /* Additional fields to add to the builder. */}} + {{- $tmpl := printf "dialect/%s/delete/fields" $.Storage }} + {{- if hasTemplate $tmpl }} + {{- xtemplate $tmpl . }} + {{- end }} } // Where appends a list predicates to the {{ $builder }} builder. diff --git a/entc/gen/template/dialect/sql/delete.tmpl b/entc/gen/template/dialect/sql/delete.tmpl index 9e007d256f..be9db4511d 100644 --- a/entc/gen/template/dialect/sql/delete.tmpl +++ b/entc/gen/template/dialect/sql/delete.tmpl @@ -34,4 +34,20 @@ func ({{ $receiver}} *{{ $builder }}) sqlExec(ctx context.Context) (int, error) return affected, err } +{{- /* Allow adding methods to the delete builder by ent extensions or user templates.*/}} +{{- with $tmpls := matchTemplate "dialect/sql/delete/additional/*" }} + {{- range $tmpl := $tmpls }} + {{- xtemplate $tmpl $ }} + {{- end }} +{{- end }} + {{ end }} + +{{/* Additional fields for the delete builder. */}} +{{ define "dialect/sql/delete/fields" }} + {{- with $tmpls := matchTemplate "dialect/sql/delete/fields/additional/*" }} + {{- range $tmpl := $tmpls }} + {{- xtemplate $tmpl $ }} + {{- end }} + {{- end }} +{{- end }} diff --git a/entc/gen/template/dialect/sql/feature/retryoptions.tmpl b/entc/gen/template/dialect/sql/feature/retryoptions.tmpl new file mode 100644 index 0000000000..e817cea5bf --- /dev/null +++ b/entc/gen/template/dialect/sql/feature/retryoptions.tmpl @@ -0,0 +1,155 @@ +{{/* +Copyright 2019-present Facebook Inc. All rights reserved. +This source code is licensed under the Apache 2.0 license found +in the LICENSE file in the root directory of this source tree. +*/}} + +{{/* gotype: entgo.io/ent/entc/gen.Type */}} + +{{/* Templates used by the "sql/retryoptions" feature-flag to add retry options to query/mutation builders. + This is primarily useful for databases like YDB that require explicit retry handling. */}} + +{{/* Additional fields for the create builder. */}} +{{ define "dialect/sql/create/fields/additional/retryoptions" -}} + {{- if $.FeatureEnabled "sql/retryoptions" }} + retryConfig sql.RetryConfig + {{- end }} +{{- end }} + +{{/* Additional fields for the create_bulk builder. */}} +{{ define "dialect/sql/create_bulk/fields/additional/retryoptions" -}} + {{- if $.FeatureEnabled "sql/retryoptions" }} + retryConfig sql.RetryConfig + {{- end }} +{{- end }} + +{{/* Additional fields for the update builder. */}} +{{ define "dialect/sql/update/fields/additional/retryoptions" -}} + {{- if $.FeatureEnabled "sql/retryoptions" }} + retryConfig sql.RetryConfig + {{- end }} +{{- end }} + +{{/* Additional fields for the query builder. */}} +{{ define "dialect/sql/query/fields/additional/retryoptions" -}} + {{- if $.FeatureEnabled "sql/retryoptions" }} + retryConfig sql.RetryConfig + {{- end }} +{{- end }} + +{{/* Additional fields for the delete builder. */}} +{{ define "dialect/sql/delete/fields/additional/retryoptions" -}} + {{- if $.FeatureEnabled "sql/retryoptions" }} + retryConfig sql.RetryConfig + {{- end }} +{{- end }} + +{{/* WithRetryOptions method for create builder. */}} +{{ define "dialect/sql/create/additional/retryoptions" }} +{{- if $.FeatureEnabled "sql/retryoptions" }} +{{ $builder := pascal $.Scope.Builder }} +{{ $receiver := $.Scope.Receiver }} + +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func ({{ $receiver }} *{{ $builder }}) WithRetryOptions(opts ...any) *{{ $builder }} { + {{ $receiver }}.retryConfig.Options = opts + return {{ $receiver }} +} +{{- end }} +{{- end }} + +{{/* WithRetryOptions method for create_bulk builder. */}} +{{ define "dialect/sql/create_bulk/additional/retryoptions" }} +{{- if $.FeatureEnabled "sql/retryoptions" }} +{{ $builder := pascal $.Scope.Builder }} +{{ $receiver := $.Scope.Receiver }} + +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func ({{ $receiver }} *{{ $builder }}) WithRetryOptions(opts ...any) *{{ $builder }} { + {{ $receiver }}.retryConfig.Options = opts + return {{ $receiver }} +} +{{- end }} +{{- end }} + +{{/* WithRetryOptions method for update builder. */}} +{{ define "dialect/sql/update/additional/retryoptions" }} +{{- if $.FeatureEnabled "sql/retryoptions" }} +{{ $builder := pascal $.Scope.Builder }} +{{ $receiver := $.Scope.Receiver }} + +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func ({{ $receiver }} *{{ $builder }}) WithRetryOptions(opts ...any) *{{ $builder }} { + {{ $receiver }}.retryConfig.Options = opts + return {{ $receiver }} +} +{{- end }} +{{- end }} + +{{/* WithRetryOptions method for query builder. */}} +{{ define "dialect/sql/query/additional/retryoptions" }} +{{- if $.FeatureEnabled "sql/retryoptions" }} +{{ $builder := pascal $.Scope.Builder }} +{{ $receiver := $.Scope.Receiver }} + +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func ({{ $receiver }} *{{ $builder }}) WithRetryOptions(opts ...any) *{{ $builder }} { + {{ $receiver }}.retryConfig.Options = opts + return {{ $receiver }} +} +{{- end }} +{{- end }} + +{{/* WithRetryOptions method for delete builder. */}} +{{ define "dialect/sql/delete/additional/retryoptions" }} +{{- if $.FeatureEnabled "sql/retryoptions" }} +{{ $builder := pascal $.Scope.Builder }} +{{ $receiver := $.Scope.Receiver }} + +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func ({{ $receiver }} *{{ $builder }}) WithRetryOptions(opts ...any) *{{ $builder }} { + {{ $receiver }}.retryConfig.Options = opts + return {{ $receiver }} +} +{{- end }} +{{- end }} + +{{/* Pass retry options to CreateSpec. */}} +{{ define "dialect/sql/create/spec/retryoptions" -}} + {{- if $.FeatureEnabled "sql/retryoptions" }} + _spec.RetryConfig = {{ $.Scope.Receiver }}.retryConfig + {{- end }} +{{- end }} + +{{/* Pass retry options to BatchCreateSpec. */}} +{{ define "dialect/sql/create_bulk/spec/retryoptions" -}} + {{- if $.FeatureEnabled "sql/retryoptions" }} + spec.RetryConfig = {{ $.Scope.Receiver }}.retryConfig + {{- end }} +{{- end }} + +{{/* Pass retry options to UpdateSpec. */}} +{{ define "dialect/sql/update/spec/retryoptions" -}} + {{- if $.FeatureEnabled "sql/retryoptions" }} + _spec.RetryConfig = {{ $.Scope.Receiver }}.retryConfig + {{- end }} +{{- end }} + +{{/* Pass retry options to QuerySpec. */}} +{{ define "dialect/sql/query/spec/retryoptions" -}} + {{- if $.FeatureEnabled "sql/retryoptions" }} + _spec.RetryConfig = {{ $.Scope.Receiver }}.retryConfig + {{- end }} +{{- end }} + +{{/* Pass retry options to DeleteSpec. */}} +{{ define "dialect/sql/delete/spec/retryoptions" -}} + {{- if $.FeatureEnabled "sql/retryoptions" }} + _spec.RetryConfig = {{ $.Scope.Receiver }}.retryConfig + {{- end }} +{{- end }} diff --git a/entc/gen/template/dialect/sql/update.tmpl b/entc/gen/template/dialect/sql/update.tmpl index 55bbdd9f85..7ab0f86bf0 100644 --- a/entc/gen/template/dialect/sql/update.tmpl +++ b/entc/gen/template/dialect/sql/update.tmpl @@ -171,7 +171,7 @@ func ({{ $receiver }} *{{ $builder }}) sqlSave(ctx context.Context) (_node {{ if {{- else }} if _node, err = sqlgraph.UpdateNodes(ctx, {{ $receiver }}.driver, _spec); err != nil { {{- end }} - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{ {{ $.Package }}.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/cascadelete/ent/client.go b/entc/integration/cascadelete/ent/client.go index 1d4ef1f1e7..2a7a6da62d 100644 --- a/entc/integration/cascadelete/ent/client.go +++ b/entc/integration/cascadelete/ent/client.go @@ -112,7 +112,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/entc/integration/cascadelete/ent/comment_update.go b/entc/integration/cascadelete/ent/comment_update.go index 3709d909b1..5a2c4eb7fe 100644 --- a/entc/integration/cascadelete/ent/comment_update.go +++ b/entc/integration/cascadelete/ent/comment_update.go @@ -156,7 +156,7 @@ func (_u *CommentUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{comment.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -332,7 +332,7 @@ func (_u *CommentUpdateOne) sqlSave(ctx context.Context) (_node *Comment, err er _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{comment.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/cascadelete/ent/post_update.go b/entc/integration/cascadelete/ent/post_update.go index bce5d98f42..440304b7ac 100644 --- a/entc/integration/cascadelete/ent/post_update.go +++ b/entc/integration/cascadelete/ent/post_update.go @@ -233,7 +233,7 @@ func (_u *PostUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{post.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -485,7 +485,7 @@ func (_u *PostUpdateOne) sqlSave(ctx context.Context) (_node *Post, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{post.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/cascadelete/ent/user_update.go b/entc/integration/cascadelete/ent/user_update.go index 86c8e1f392..4012d76085 100644 --- a/entc/integration/cascadelete/ent/user_update.go +++ b/entc/integration/cascadelete/ent/user_update.go @@ -172,7 +172,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -364,7 +364,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/config/ent/client.go b/entc/integration/config/ent/client.go index 53fdadb55a..9dee134e80 100644 --- a/entc/integration/config/ent/client.go +++ b/entc/integration/config/ent/client.go @@ -103,7 +103,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/entc/integration/config/ent/user_update.go b/entc/integration/config/ent/user_update.go index daa76b2d3d..0917112e59 100644 --- a/entc/integration/config/ent/user_update.go +++ b/entc/integration/config/ent/user_update.go @@ -125,7 +125,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.ClearField(user.FieldLabel, field.TypeString) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -271,7 +271,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/customid/ent/account_update.go b/entc/integration/customid/ent/account_update.go index 92f0950009..e930bf74df 100644 --- a/entc/integration/customid/ent/account_update.go +++ b/entc/integration/customid/ent/account_update.go @@ -186,7 +186,7 @@ func (_u *AccountUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{account.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -391,7 +391,7 @@ func (_u *AccountUpdateOne) sqlSave(ctx context.Context) (_node *Account, err er _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{account.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/customid/ent/blob_update.go b/entc/integration/customid/ent/blob_update.go index 52287f93d3..de498aae9a 100644 --- a/entc/integration/customid/ent/blob_update.go +++ b/entc/integration/customid/ent/blob_update.go @@ -265,7 +265,7 @@ func (_u *BlobUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{blob.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -550,7 +550,7 @@ func (_u *BlobUpdateOne) sqlSave(ctx context.Context) (_node *Blob, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{blob.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/customid/ent/bloblink_update.go b/entc/integration/customid/ent/bloblink_update.go index 4f7a573319..b4f418ec0c 100644 --- a/entc/integration/customid/ent/bloblink_update.go +++ b/entc/integration/customid/ent/bloblink_update.go @@ -215,7 +215,7 @@ func (_u *BlobLinkUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{bloblink.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -450,7 +450,7 @@ func (_u *BlobLinkUpdateOne) sqlSave(ctx context.Context) (_node *BlobLink, err _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{bloblink.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/customid/ent/car_update.go b/entc/integration/customid/ent/car_update.go index 3da75dc398..69b97be16e 100644 --- a/entc/integration/customid/ent/car_update.go +++ b/entc/integration/customid/ent/car_update.go @@ -235,7 +235,7 @@ func (_u *CarUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{car.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -490,7 +490,7 @@ func (_u *CarUpdateOne) sqlSave(ctx context.Context) (_node *Car, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{car.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/customid/ent/client.go b/entc/integration/customid/ent/client.go index af08dc9747..1c0bbeceb2 100644 --- a/entc/integration/customid/ent/client.go +++ b/entc/integration/customid/ent/client.go @@ -172,7 +172,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/entc/integration/customid/ent/device_update.go b/entc/integration/customid/ent/device_update.go index e18f30d5eb..4e2e7baf40 100644 --- a/entc/integration/customid/ent/device_update.go +++ b/entc/integration/customid/ent/device_update.go @@ -210,7 +210,7 @@ func (_u *DeviceUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{device.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -439,7 +439,7 @@ func (_u *DeviceUpdateOne) sqlSave(ctx context.Context) (_node *Device, err erro _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{device.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/customid/ent/doc_update.go b/entc/integration/customid/ent/doc_update.go index a2690acf4f..02aac6296c 100644 --- a/entc/integration/customid/ent/doc_update.go +++ b/entc/integration/customid/ent/doc_update.go @@ -316,7 +316,7 @@ func (_u *DocUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{doc.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -652,7 +652,7 @@ func (_u *DocUpdateOne) sqlSave(ctx context.Context) (_node *Doc, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{doc.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/customid/ent/group_update.go b/entc/integration/customid/ent/group_update.go index d7983c268a..91ec716935 100644 --- a/entc/integration/customid/ent/group_update.go +++ b/entc/integration/customid/ent/group_update.go @@ -155,7 +155,7 @@ func (_u *GroupUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -330,7 +330,7 @@ func (_u *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error) _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/customid/ent/intsid_update.go b/entc/integration/customid/ent/intsid_update.go index e30b4a635e..51eb5c883b 100644 --- a/entc/integration/customid/ent/intsid_update.go +++ b/entc/integration/customid/ent/intsid_update.go @@ -209,7 +209,7 @@ func (_u *IntSIDUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{intsid.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -438,7 +438,7 @@ func (_u *IntSIDUpdateOne) sqlSave(ctx context.Context) (_node *IntSID, err erro _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{intsid.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/customid/ent/link_update.go b/entc/integration/customid/ent/link_update.go index 32b34e6496..6112471569 100644 --- a/entc/integration/customid/ent/link_update.go +++ b/entc/integration/customid/ent/link_update.go @@ -83,7 +83,7 @@ func (_u *LinkUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(link.FieldLinkInformation, field.TypeJSON, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{link.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -186,7 +186,7 @@ func (_u *LinkUpdateOne) sqlSave(ctx context.Context) (_node *Link, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{link.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/customid/ent/mixinid_update.go b/entc/integration/customid/ent/mixinid_update.go index 5e1afcab69..96eed2bdb0 100644 --- a/entc/integration/customid/ent/mixinid_update.go +++ b/entc/integration/customid/ent/mixinid_update.go @@ -107,7 +107,7 @@ func (_u *MixinIDUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(mixinid.FieldMixinField, field.TypeString, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{mixinid.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -235,7 +235,7 @@ func (_u *MixinIDUpdateOne) sqlSave(ctx context.Context) (_node *MixinID, err er _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{mixinid.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/customid/ent/note_update.go b/entc/integration/customid/ent/note_update.go index e7babf44b2..ac320f157f 100644 --- a/entc/integration/customid/ent/note_update.go +++ b/entc/integration/customid/ent/note_update.go @@ -235,7 +235,7 @@ func (_u *NoteUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{note.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -490,7 +490,7 @@ func (_u *NoteUpdateOne) sqlSave(ctx context.Context) (_node *Note, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{note.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/customid/ent/other_update.go b/entc/integration/customid/ent/other_update.go index 350c40a572..ff7a3df4f1 100644 --- a/entc/integration/customid/ent/other_update.go +++ b/entc/integration/customid/ent/other_update.go @@ -73,7 +73,7 @@ func (_u *OtherUpdate) sqlSave(ctx context.Context) (_node int, err error) { } } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{other.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -167,7 +167,7 @@ func (_u *OtherUpdateOne) sqlSave(ctx context.Context) (_node *Other, err error) _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{other.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/customid/ent/pet_update.go b/entc/integration/customid/ent/pet_update.go index 3a5d52c583..93a3ae6f44 100644 --- a/entc/integration/customid/ent/pet_update.go +++ b/entc/integration/customid/ent/pet_update.go @@ -345,7 +345,7 @@ func (_u *PetUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -709,7 +709,7 @@ func (_u *PetUpdateOne) sqlSave(ctx context.Context) (_node *Pet, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/customid/ent/revision_update.go b/entc/integration/customid/ent/revision_update.go index 154dcdefd6..2d005d31fc 100644 --- a/entc/integration/customid/ent/revision_update.go +++ b/entc/integration/customid/ent/revision_update.go @@ -73,7 +73,7 @@ func (_u *RevisionUpdate) sqlSave(ctx context.Context) (_node int, err error) { } } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{revision.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -167,7 +167,7 @@ func (_u *RevisionUpdateOne) sqlSave(ctx context.Context) (_node *Revision, err _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{revision.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/customid/ent/session_update.go b/entc/integration/customid/ent/session_update.go index d9b0605f0c..3529baa1c0 100644 --- a/entc/integration/customid/ent/session_update.go +++ b/entc/integration/customid/ent/session_update.go @@ -129,7 +129,7 @@ func (_u *SessionUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{session.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -277,7 +277,7 @@ func (_u *SessionUpdateOne) sqlSave(ctx context.Context) (_node *Session, err er _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{session.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/customid/ent/token_update.go b/entc/integration/customid/ent/token_update.go index 3611085333..7c0d603fac 100644 --- a/entc/integration/customid/ent/token_update.go +++ b/entc/integration/customid/ent/token_update.go @@ -154,7 +154,7 @@ func (_u *TokenUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{token.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -327,7 +327,7 @@ func (_u *TokenUpdateOne) sqlSave(ctx context.Context) (_node *Token, err error) _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{token.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/customid/ent/user_update.go b/entc/integration/customid/ent/user_update.go index c78665c533..ed50c01421 100644 --- a/entc/integration/customid/ent/user_update.go +++ b/entc/integration/customid/ent/user_update.go @@ -372,7 +372,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -763,7 +763,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/docker-compose.yaml b/entc/integration/docker-compose.yaml index 32ac1af284..4357026d1c 100644 --- a/entc/integration/docker-compose.yaml +++ b/entc/integration/docker-compose.yaml @@ -167,3 +167,21 @@ services: restart: on-failure ports: - 8182:8182 + + ydb: + image: ydbplatform/local-ydb:trunk + platform: linux/amd64 + hostname: localhost + environment: + - GRPC_TLS_PORT=2135 + - GRPC_PORT=2136 + - MON_PORT=8765 + ports: + - 2136:2136 + - 8765:8765 + healthcheck: + test: ["CMD-SHELL", "nc -z localhost 2136"] + interval: 10s + timeout: 5s + retries: 10 + start_period: 30s diff --git a/entc/integration/edgefield/ent/car_update.go b/entc/integration/edgefield/ent/car_update.go index b7b73e2c37..0ae3b6f090 100644 --- a/entc/integration/edgefield/ent/car_update.go +++ b/entc/integration/edgefield/ent/car_update.go @@ -181,7 +181,7 @@ func (_u *CarUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{car.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -382,7 +382,7 @@ func (_u *CarUpdateOne) sqlSave(ctx context.Context) (_node *Car, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{car.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgefield/ent/card_update.go b/entc/integration/edgefield/ent/card_update.go index d4acf756c5..6f6608a9c2 100644 --- a/entc/integration/edgefield/ent/card_update.go +++ b/entc/integration/edgefield/ent/card_update.go @@ -160,7 +160,7 @@ func (_u *CardUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{card.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -340,7 +340,7 @@ func (_u *CardUpdateOne) sqlSave(ctx context.Context) (_node *Card, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{card.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgefield/ent/client.go b/entc/integration/edgefield/ent/client.go index ca24675669..85ad70493c 100644 --- a/entc/integration/edgefield/ent/client.go +++ b/entc/integration/edgefield/ent/client.go @@ -137,7 +137,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/entc/integration/edgefield/ent/info_update.go b/entc/integration/edgefield/ent/info_update.go index 2b8f1bc544..b474b8bf0f 100644 --- a/entc/integration/edgefield/ent/info_update.go +++ b/entc/integration/edgefield/ent/info_update.go @@ -150,7 +150,7 @@ func (_u *InfoUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{info.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -318,7 +318,7 @@ func (_u *InfoUpdateOne) sqlSave(ctx context.Context) (_node *Info, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{info.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgefield/ent/metadata_update.go b/entc/integration/edgefield/ent/metadata_update.go index 2b64eb39d1..b3e9f06a5e 100644 --- a/entc/integration/edgefield/ent/metadata_update.go +++ b/entc/integration/edgefield/ent/metadata_update.go @@ -296,7 +296,7 @@ func (_u *MetadataUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{metadata.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -612,7 +612,7 @@ func (_u *MetadataUpdateOne) sqlSave(ctx context.Context) (_node *Metadata, err _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{metadata.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgefield/ent/node_update.go b/entc/integration/edgefield/ent/node_update.go index 06e313bd49..d91369ba26 100644 --- a/entc/integration/edgefield/ent/node_update.go +++ b/entc/integration/edgefield/ent/node_update.go @@ -214,7 +214,7 @@ func (_u *NodeUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{node.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -449,7 +449,7 @@ func (_u *NodeUpdateOne) sqlSave(ctx context.Context) (_node *Node, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{node.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgefield/ent/pet_update.go b/entc/integration/edgefield/ent/pet_update.go index 312aa37156..d84f709c58 100644 --- a/entc/integration/edgefield/ent/pet_update.go +++ b/entc/integration/edgefield/ent/pet_update.go @@ -134,7 +134,7 @@ func (_u *PetUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -288,7 +288,7 @@ func (_u *PetUpdateOne) sqlSave(ctx context.Context) (_node *Pet, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgefield/ent/post_update.go b/entc/integration/edgefield/ent/post_update.go index 7ebdb4cdd1..52c9241c1e 100644 --- a/entc/integration/edgefield/ent/post_update.go +++ b/entc/integration/edgefield/ent/post_update.go @@ -151,7 +151,7 @@ func (_u *PostUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{post.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -322,7 +322,7 @@ func (_u *PostUpdateOne) sqlSave(ctx context.Context) (_node *Post, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{post.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgefield/ent/rental_update.go b/entc/integration/edgefield/ent/rental_update.go index de755ad991..fa4f996ce6 100644 --- a/entc/integration/edgefield/ent/rental_update.go +++ b/entc/integration/edgefield/ent/rental_update.go @@ -105,7 +105,7 @@ func (_u *RentalUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(rental.FieldDate, field.TypeTime, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{rental.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -230,7 +230,7 @@ func (_u *RentalUpdateOne) sqlSave(ctx context.Context) (_node *Rental, err erro _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{rental.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgefield/ent/user_update.go b/entc/integration/edgefield/ent/user_update.go index 674eaf5812..3e06858d21 100644 --- a/entc/integration/edgefield/ent/user_update.go +++ b/entc/integration/edgefield/ent/user_update.go @@ -570,7 +570,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -1156,7 +1156,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgeschema/ent/attachedfile_update.go b/entc/integration/edgeschema/ent/attachedfile_update.go index fae5b0a9a6..b7a72efc00 100644 --- a/entc/integration/edgeschema/ent/attachedfile_update.go +++ b/entc/integration/edgeschema/ent/attachedfile_update.go @@ -221,7 +221,7 @@ func (_u *AttachedFileUpdate) sqlSave(ctx context.Context) (_node int, err error _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{attachedfile.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -460,7 +460,7 @@ func (_u *AttachedFileUpdateOne) sqlSave(ctx context.Context) (_node *AttachedFi _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{attachedfile.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgeschema/ent/client.go b/entc/integration/edgeschema/ent/client.go index 0d084d1535..e7ef36af0f 100644 --- a/entc/integration/edgeschema/ent/client.go +++ b/entc/integration/edgeschema/ent/client.go @@ -169,7 +169,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/entc/integration/edgeschema/ent/file_update.go b/entc/integration/edgeschema/ent/file_update.go index 2d33593f74..03928e49bc 100644 --- a/entc/integration/edgeschema/ent/file_update.go +++ b/entc/integration/edgeschema/ent/file_update.go @@ -172,7 +172,7 @@ func (_u *FileUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{file.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -364,7 +364,7 @@ func (_u *FileUpdateOne) sqlSave(ctx context.Context) (_node *File, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{file.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgeschema/ent/friendship_update.go b/entc/integration/edgeschema/ent/friendship_update.go index caf0e0f2ab..456770a6a1 100644 --- a/entc/integration/edgeschema/ent/friendship_update.go +++ b/entc/integration/edgeschema/ent/friendship_update.go @@ -132,7 +132,7 @@ func (_u *FriendshipUpdate) sqlSave(ctx context.Context) (_node int, err error) _spec.SetField(friendship.FieldCreatedAt, field.TypeTime, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{friendship.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -284,7 +284,7 @@ func (_u *FriendshipUpdateOne) sqlSave(ctx context.Context) (_node *Friendship, _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{friendship.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgeschema/ent/group_update.go b/entc/integration/edgeschema/ent/group_update.go index 71261d26fa..0a1c383cb5 100644 --- a/entc/integration/edgeschema/ent/group_update.go +++ b/entc/integration/edgeschema/ent/group_update.go @@ -430,7 +430,7 @@ func (_u *GroupUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -877,7 +877,7 @@ func (_u *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error) _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgeschema/ent/grouptag_update.go b/entc/integration/edgeschema/ent/grouptag_update.go index f18425c559..5e15b0a553 100644 --- a/entc/integration/edgeschema/ent/grouptag_update.go +++ b/entc/integration/edgeschema/ent/grouptag_update.go @@ -197,7 +197,7 @@ func (_u *GroupTagUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{grouptag.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -413,7 +413,7 @@ func (_u *GroupTagUpdateOne) sqlSave(ctx context.Context) (_node *GroupTag, err _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{grouptag.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgeschema/ent/process_update.go b/entc/integration/edgeschema/ent/process_update.go index cd9c6adcba..7df34a4da1 100644 --- a/entc/integration/edgeschema/ent/process_update.go +++ b/entc/integration/edgeschema/ent/process_update.go @@ -249,7 +249,7 @@ func (_u *ProcessUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{process.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -517,7 +517,7 @@ func (_u *ProcessUpdateOne) sqlSave(ctx context.Context) (_node *Process, err er _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{process.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgeschema/ent/relationship_update.go b/entc/integration/edgeschema/ent/relationship_update.go index 5d21c62a84..35610a3220 100644 --- a/entc/integration/edgeschema/ent/relationship_update.go +++ b/entc/integration/edgeschema/ent/relationship_update.go @@ -284,7 +284,7 @@ func (_u *RelationshipUpdate) sqlSave(ctx context.Context) (_node int, err error _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{relationship.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -589,7 +589,7 @@ func (_u *RelationshipUpdateOne) sqlSave(ctx context.Context) (_node *Relationsh _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{relationship.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgeschema/ent/relationshipinfo_update.go b/entc/integration/edgeschema/ent/relationshipinfo_update.go index 7c2b1ca503..620c6615af 100644 --- a/entc/integration/edgeschema/ent/relationshipinfo_update.go +++ b/entc/integration/edgeschema/ent/relationshipinfo_update.go @@ -90,7 +90,7 @@ func (_u *RelationshipInfoUpdate) sqlSave(ctx context.Context) (_node int, err e _spec.SetField(relationshipinfo.FieldText, field.TypeString, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{relationshipinfo.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -201,7 +201,7 @@ func (_u *RelationshipInfoUpdateOne) sqlSave(ctx context.Context) (_node *Relati _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{relationshipinfo.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgeschema/ent/role_update.go b/entc/integration/edgeschema/ent/role_update.go index 8c146dcb6d..64816a797a 100644 --- a/entc/integration/edgeschema/ent/role_update.go +++ b/entc/integration/edgeschema/ent/role_update.go @@ -202,7 +202,7 @@ func (_u *RoleUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{role.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -423,7 +423,7 @@ func (_u *RoleUpdateOne) sqlSave(ctx context.Context) (_node *Role, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{role.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgeschema/ent/roleuser_update.go b/entc/integration/edgeschema/ent/roleuser_update.go index 226e7fd5fc..9590eff01e 100644 --- a/entc/integration/edgeschema/ent/roleuser_update.go +++ b/entc/integration/edgeschema/ent/roleuser_update.go @@ -215,7 +215,7 @@ func (_u *RoleUserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{roleuser.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -450,7 +450,7 @@ func (_u *RoleUserUpdateOne) sqlSave(ctx context.Context) (_node *RoleUser, err _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{roleuser.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgeschema/ent/tag_update.go b/entc/integration/edgeschema/ent/tag_update.go index dde23a2c07..f242a901e1 100644 --- a/entc/integration/edgeschema/ent/tag_update.go +++ b/entc/integration/edgeschema/ent/tag_update.go @@ -440,7 +440,7 @@ func (_u *TagUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{tag.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -896,7 +896,7 @@ func (_u *TagUpdateOne) sqlSave(ctx context.Context) (_node *Tag, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{tag.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgeschema/ent/tweet_update.go b/entc/integration/edgeschema/ent/tweet_update.go index abe45843c9..39c15b8e52 100644 --- a/entc/integration/edgeschema/ent/tweet_update.go +++ b/entc/integration/edgeschema/ent/tweet_update.go @@ -545,7 +545,7 @@ func (_u *TweetUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{tweet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -1106,7 +1106,7 @@ func (_u *TweetUpdateOne) sqlSave(ctx context.Context) (_node *Tweet, err error) _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{tweet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgeschema/ent/tweetlike_update.go b/entc/integration/edgeschema/ent/tweetlike_update.go index e9c7b880df..1053ae710e 100644 --- a/entc/integration/edgeschema/ent/tweetlike_update.go +++ b/entc/integration/edgeschema/ent/tweetlike_update.go @@ -215,7 +215,7 @@ func (_u *TweetLikeUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{tweetlike.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -450,7 +450,7 @@ func (_u *TweetLikeUpdateOne) sqlSave(ctx context.Context) (_node *TweetLike, er _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{tweetlike.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgeschema/ent/tweettag_update.go b/entc/integration/edgeschema/ent/tweettag_update.go index 73e657a7b8..c8047cc7bf 100644 --- a/entc/integration/edgeschema/ent/tweettag_update.go +++ b/entc/integration/edgeschema/ent/tweettag_update.go @@ -215,7 +215,7 @@ func (_u *TweetTagUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{tweettag.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -448,7 +448,7 @@ func (_u *TweetTagUpdateOne) sqlSave(ctx context.Context) (_node *TweetTag, err _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{tweettag.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgeschema/ent/user_update.go b/entc/integration/edgeschema/ent/user_update.go index a5bf9b8c6e..d588e013a6 100644 --- a/entc/integration/edgeschema/ent/user_update.go +++ b/entc/integration/edgeschema/ent/user_update.go @@ -897,7 +897,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -1809,7 +1809,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgeschema/ent/usergroup_update.go b/entc/integration/edgeschema/ent/usergroup_update.go index abaecec83b..22f1b746f0 100644 --- a/entc/integration/edgeschema/ent/usergroup_update.go +++ b/entc/integration/edgeschema/ent/usergroup_update.go @@ -215,7 +215,7 @@ func (_u *UserGroupUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{usergroup.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -448,7 +448,7 @@ func (_u *UserGroupUpdateOne) sqlSave(ctx context.Context) (_node *UserGroup, er _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{usergroup.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/edgeschema/ent/usertweet_update.go b/entc/integration/edgeschema/ent/usertweet_update.go index d992ee8d45..e283fd16d2 100644 --- a/entc/integration/edgeschema/ent/usertweet_update.go +++ b/entc/integration/edgeschema/ent/usertweet_update.go @@ -215,7 +215,7 @@ func (_u *UserTweetUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{usertweet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -448,7 +448,7 @@ func (_u *UserTweetUpdateOne) sqlSave(ctx context.Context) (_node *UserTweet, er _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{usertweet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/ent/api_create.go b/entc/integration/ent/api_create.go index ec60346db8..40511ea5bf 100644 --- a/entc/integration/ent/api_create.go +++ b/entc/integration/ent/api_create.go @@ -20,9 +20,10 @@ import ( // APICreate is the builder for creating a Api entity. type APICreate struct { config - mutation *APIMutation - hooks []Hook - conflict []sql.ConflictOption + mutation *APIMutation + hooks []Hook + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Mutation returns the APIMutation object of the builder. @@ -85,10 +86,18 @@ func (_c *APICreate) createSpec() (*Api, *sqlgraph.CreateSpec) { _node = &Api{config: _c.config} _spec = sqlgraph.NewCreateSpec(api.Table, sqlgraph.NewFieldSpec(api.FieldID, field.TypeInt)) ) + _spec.RetryConfig = _c.retryConfig _spec.OnConflict = _c.conflict return _node, _spec } +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *APICreate) WithRetryOptions(opts ...any) *APICreate { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // @@ -208,9 +217,10 @@ func (u *ApiUpsertOne) IDX(ctx context.Context) int { // APICreateBulk is the builder for creating many Api entities in bulk. type APICreateBulk struct { config - err error - builders []*APICreate - conflict []sql.ConflictOption + err error + builders []*APICreate + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Save creates the Api entities in the database. @@ -239,6 +249,7 @@ func (_c *APICreateBulk) Save(ctx context.Context) ([]*Api, error) { _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig spec.OnConflict = _c.conflict // Invoke the actual operation on the latest mutation in the chain. if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { @@ -294,6 +305,13 @@ func (_c *APICreateBulk) ExecX(ctx context.Context) { } } +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *APICreateBulk) WithRetryOptions(opts ...any) *APICreateBulk { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // diff --git a/entc/integration/ent/api_delete.go b/entc/integration/ent/api_delete.go index fcbbdb3bc1..e4fee7c501 100644 --- a/entc/integration/ent/api_delete.go +++ b/entc/integration/ent/api_delete.go @@ -19,8 +19,9 @@ import ( // APIDelete is the builder for deleting a Api entity. type APIDelete struct { config - hooks []Hook - mutation *APIMutation + hooks []Hook + mutation *APIMutation + retryConfig sql.RetryConfig } // Where appends a list predicates to the APIDelete builder. @@ -45,6 +46,7 @@ func (_d *APIDelete) ExecX(ctx context.Context) int { func (_d *APIDelete) sqlExec(ctx context.Context) (int, error) { _spec := sqlgraph.NewDeleteSpec(api.Table, sqlgraph.NewFieldSpec(api.FieldID, field.TypeInt)) + _spec.RetryConfig = _d.retryConfig if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -60,6 +62,13 @@ func (_d *APIDelete) sqlExec(ctx context.Context) (int, error) { return affected, err } +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *APIDelete) WithRetryOptions(opts ...any) *APIDelete { + _d.retryConfig.Options = opts + return _d +} + // APIDeleteOne is the builder for deleting a single Api entity. type APIDeleteOne struct { _d *APIDelete diff --git a/entc/integration/ent/api_query.go b/entc/integration/ent/api_query.go index 78aa8e9aa1..a8fa9ae8a5 100644 --- a/entc/integration/ent/api_query.go +++ b/entc/integration/ent/api_query.go @@ -23,11 +23,12 @@ import ( // APIQuery is the builder for querying Api entities. type APIQuery struct { config - ctx *QueryContext - order []api.OrderOption - inters []Interceptor - predicates []predicate.Api - modifiers []func(*sql.Selector) + ctx *QueryContext + order []api.OrderOption + inters []Interceptor + predicates []predicate.Api + modifiers []func(*sql.Selector) + retryConfig sql.RetryConfig // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -331,6 +332,7 @@ func (_q *APIQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Api, err if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig for i := range hooks { hooks[i](ctx, _spec) } @@ -348,6 +350,7 @@ func (_q *APIQuery) sqlCount(ctx context.Context) (int, error) { if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig _spec.Node.Columns = _q.ctx.Fields if len(_q.ctx.Fields) > 0 { _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique @@ -462,6 +465,13 @@ func (_q *APIQuery) Modify(modifiers ...func(s *sql.Selector)) *APISelect { return _q.Select() } +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *APIQuery) WithRetryOptions(opts ...any) *APIQuery { + _q.retryConfig.Options = opts + return _q +} + // APIGroupBy is the group-by builder for Api entities. type APIGroupBy struct { selector diff --git a/entc/integration/ent/api_update.go b/entc/integration/ent/api_update.go index fd9d0a456e..928383bf25 100644 --- a/entc/integration/ent/api_update.go +++ b/entc/integration/ent/api_update.go @@ -21,9 +21,10 @@ import ( // APIUpdate is the builder for updating Api entities. type APIUpdate struct { config - hooks []Hook - mutation *APIMutation - modifiers []func(*sql.UpdateBuilder) + hooks []Hook + mutation *APIMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Where appends a list predicates to the APIUpdate builder. @@ -70,6 +71,13 @@ func (_u *APIUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *APIUpdate return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *APIUpdate) WithRetryOptions(opts ...any) *APIUpdate { + _u.retryConfig.Options = opts + return _u +} + func (_u *APIUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec := sqlgraph.NewUpdateSpec(api.Table, api.Columns, sqlgraph.NewFieldSpec(api.FieldID, field.TypeInt)) if ps := _u.mutation.predicates; len(ps) > 0 { @@ -80,8 +88,9 @@ func (_u *APIUpdate) sqlSave(ctx context.Context) (_node int, err error) { } } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{api.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -95,10 +104,11 @@ func (_u *APIUpdate) sqlSave(ctx context.Context) (_node int, err error) { // APIUpdateOne is the builder for updating a single Api entity. type APIUpdateOne struct { config - fields []string - hooks []Hook - mutation *APIMutation - modifiers []func(*sql.UpdateBuilder) + fields []string + hooks []Hook + mutation *APIMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Mutation returns the APIMutation object of the builder. @@ -152,6 +162,13 @@ func (_u *APIUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *APIUpda return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *APIUpdateOne) WithRetryOptions(opts ...any) *APIUpdateOne { + _u.retryConfig.Options = opts + return _u +} + func (_u *APIUpdateOne) sqlSave(ctx context.Context) (_node *Api, err error) { _spec := sqlgraph.NewUpdateSpec(api.Table, api.Columns, sqlgraph.NewFieldSpec(api.FieldID, field.TypeInt)) id, ok := _u.mutation.ID() @@ -179,11 +196,12 @@ func (_u *APIUpdateOne) sqlSave(ctx context.Context) (_node *Api, err error) { } } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig _node = &Api{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{api.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/ent/builder_create.go b/entc/integration/ent/builder_create.go index bc698496b2..c926f3f72d 100644 --- a/entc/integration/ent/builder_create.go +++ b/entc/integration/ent/builder_create.go @@ -20,9 +20,10 @@ import ( // BuilderCreate is the builder for creating a Builder entity. type BuilderCreate struct { config - mutation *BuilderMutation - hooks []Hook - conflict []sql.ConflictOption + mutation *BuilderMutation + hooks []Hook + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Mutation returns the BuilderMutation object of the builder. @@ -85,10 +86,18 @@ func (_c *BuilderCreate) createSpec() (*Builder, *sqlgraph.CreateSpec) { _node = &Builder{config: _c.config} _spec = sqlgraph.NewCreateSpec(builder.Table, sqlgraph.NewFieldSpec(builder.FieldID, field.TypeInt)) ) + _spec.RetryConfig = _c.retryConfig _spec.OnConflict = _c.conflict return _node, _spec } +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *BuilderCreate) WithRetryOptions(opts ...any) *BuilderCreate { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // @@ -208,9 +217,10 @@ func (u *BuilderUpsertOne) IDX(ctx context.Context) int { // BuilderCreateBulk is the builder for creating many Builder entities in bulk. type BuilderCreateBulk struct { config - err error - builders []*BuilderCreate - conflict []sql.ConflictOption + err error + builders []*BuilderCreate + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Save creates the Builder entities in the database. @@ -239,6 +249,7 @@ func (_c *BuilderCreateBulk) Save(ctx context.Context) ([]*Builder, error) { _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig spec.OnConflict = _c.conflict // Invoke the actual operation on the latest mutation in the chain. if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { @@ -294,6 +305,13 @@ func (_c *BuilderCreateBulk) ExecX(ctx context.Context) { } } +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *BuilderCreateBulk) WithRetryOptions(opts ...any) *BuilderCreateBulk { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // diff --git a/entc/integration/ent/builder_delete.go b/entc/integration/ent/builder_delete.go index 530a021b40..45427b58fc 100644 --- a/entc/integration/ent/builder_delete.go +++ b/entc/integration/ent/builder_delete.go @@ -19,8 +19,9 @@ import ( // BuilderDelete is the builder for deleting a Builder entity. type BuilderDelete struct { config - hooks []Hook - mutation *BuilderMutation + hooks []Hook + mutation *BuilderMutation + retryConfig sql.RetryConfig } // Where appends a list predicates to the BuilderDelete builder. @@ -45,6 +46,7 @@ func (_d *BuilderDelete) ExecX(ctx context.Context) int { func (_d *BuilderDelete) sqlExec(ctx context.Context) (int, error) { _spec := sqlgraph.NewDeleteSpec(builder.Table, sqlgraph.NewFieldSpec(builder.FieldID, field.TypeInt)) + _spec.RetryConfig = _d.retryConfig if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -60,6 +62,13 @@ func (_d *BuilderDelete) sqlExec(ctx context.Context) (int, error) { return affected, err } +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *BuilderDelete) WithRetryOptions(opts ...any) *BuilderDelete { + _d.retryConfig.Options = opts + return _d +} + // BuilderDeleteOne is the builder for deleting a single Builder entity. type BuilderDeleteOne struct { _d *BuilderDelete diff --git a/entc/integration/ent/builder_query.go b/entc/integration/ent/builder_query.go index e797623818..d6d02e3e1f 100644 --- a/entc/integration/ent/builder_query.go +++ b/entc/integration/ent/builder_query.go @@ -23,11 +23,12 @@ import ( // BuilderQuery is the builder for querying Builder entities. type BuilderQuery struct { config - ctx *QueryContext - order []builder.OrderOption - inters []Interceptor - predicates []predicate.Builder - modifiers []func(*sql.Selector) + ctx *QueryContext + order []builder.OrderOption + inters []Interceptor + predicates []predicate.Builder + modifiers []func(*sql.Selector) + retryConfig sql.RetryConfig // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -331,6 +332,7 @@ func (_q *BuilderQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Buil if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig for i := range hooks { hooks[i](ctx, _spec) } @@ -348,6 +350,7 @@ func (_q *BuilderQuery) sqlCount(ctx context.Context) (int, error) { if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig _spec.Node.Columns = _q.ctx.Fields if len(_q.ctx.Fields) > 0 { _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique @@ -462,6 +465,13 @@ func (_q *BuilderQuery) Modify(modifiers ...func(s *sql.Selector)) *BuilderSelec return _q.Select() } +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *BuilderQuery) WithRetryOptions(opts ...any) *BuilderQuery { + _q.retryConfig.Options = opts + return _q +} + // BuilderGroupBy is the group-by builder for Builder entities. type BuilderGroupBy struct { selector diff --git a/entc/integration/ent/builder_update.go b/entc/integration/ent/builder_update.go index 179c6d84b8..d9502522bf 100644 --- a/entc/integration/ent/builder_update.go +++ b/entc/integration/ent/builder_update.go @@ -21,9 +21,10 @@ import ( // BuilderUpdate is the builder for updating Builder entities. type BuilderUpdate struct { config - hooks []Hook - mutation *BuilderMutation - modifiers []func(*sql.UpdateBuilder) + hooks []Hook + mutation *BuilderMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Where appends a list predicates to the BuilderUpdate builder. @@ -70,6 +71,13 @@ func (_u *BuilderUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *Builde return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *BuilderUpdate) WithRetryOptions(opts ...any) *BuilderUpdate { + _u.retryConfig.Options = opts + return _u +} + func (_u *BuilderUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec := sqlgraph.NewUpdateSpec(builder.Table, builder.Columns, sqlgraph.NewFieldSpec(builder.FieldID, field.TypeInt)) if ps := _u.mutation.predicates; len(ps) > 0 { @@ -80,8 +88,9 @@ func (_u *BuilderUpdate) sqlSave(ctx context.Context) (_node int, err error) { } } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{builder.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -95,10 +104,11 @@ func (_u *BuilderUpdate) sqlSave(ctx context.Context) (_node int, err error) { // BuilderUpdateOne is the builder for updating a single Builder entity. type BuilderUpdateOne struct { config - fields []string - hooks []Hook - mutation *BuilderMutation - modifiers []func(*sql.UpdateBuilder) + fields []string + hooks []Hook + mutation *BuilderMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Mutation returns the BuilderMutation object of the builder. @@ -152,6 +162,13 @@ func (_u *BuilderUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *Bui return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *BuilderUpdateOne) WithRetryOptions(opts ...any) *BuilderUpdateOne { + _u.retryConfig.Options = opts + return _u +} + func (_u *BuilderUpdateOne) sqlSave(ctx context.Context) (_node *Builder, err error) { _spec := sqlgraph.NewUpdateSpec(builder.Table, builder.Columns, sqlgraph.NewFieldSpec(builder.FieldID, field.TypeInt)) id, ok := _u.mutation.ID() @@ -179,11 +196,12 @@ func (_u *BuilderUpdateOne) sqlSave(ctx context.Context) (_node *Builder, err er } } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig _node = &Builder{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{builder.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/ent/card_create.go b/entc/integration/ent/card_create.go index 793ccc994c..ae150a3579 100644 --- a/entc/integration/ent/card_create.go +++ b/entc/integration/ent/card_create.go @@ -23,9 +23,10 @@ import ( // CardCreate is the builder for creating a Card entity. type CardCreate struct { config - mutation *CardMutation - hooks []Hook - conflict []sql.ConflictOption + mutation *CardMutation + hooks []Hook + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // SetCreateTime sets the "create_time" field. @@ -223,6 +224,7 @@ func (_c *CardCreate) createSpec() (*Card, *sqlgraph.CreateSpec) { _node = &Card{config: _c.config} _spec = sqlgraph.NewCreateSpec(card.Table, sqlgraph.NewFieldSpec(card.FieldID, field.TypeInt)) ) + _spec.RetryConfig = _c.retryConfig _spec.OnConflict = _c.conflict if value, ok := _c.mutation.CreateTime(); ok { _spec.SetField(card.FieldCreateTime, field.TypeTime, value) @@ -280,6 +282,13 @@ func (_c *CardCreate) createSpec() (*Card, *sqlgraph.CreateSpec) { return _node, _spec } +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *CardCreate) WithRetryOptions(opts ...any) *CardCreate { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // @@ -517,9 +526,10 @@ func (u *CardUpsertOne) IDX(ctx context.Context) int { // CardCreateBulk is the builder for creating many Card entities in bulk. type CardCreateBulk struct { config - err error - builders []*CardCreate - conflict []sql.ConflictOption + err error + builders []*CardCreate + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Save creates the Card entities in the database. @@ -549,6 +559,7 @@ func (_c *CardCreateBulk) Save(ctx context.Context) ([]*Card, error) { _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig spec.OnConflict = _c.conflict // Invoke the actual operation on the latest mutation in the chain. if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { @@ -604,6 +615,13 @@ func (_c *CardCreateBulk) ExecX(ctx context.Context) { } } +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *CardCreateBulk) WithRetryOptions(opts ...any) *CardCreateBulk { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // diff --git a/entc/integration/ent/card_delete.go b/entc/integration/ent/card_delete.go index d177539bb0..8953497378 100644 --- a/entc/integration/ent/card_delete.go +++ b/entc/integration/ent/card_delete.go @@ -19,8 +19,9 @@ import ( // CardDelete is the builder for deleting a Card entity. type CardDelete struct { config - hooks []Hook - mutation *CardMutation + hooks []Hook + mutation *CardMutation + retryConfig sql.RetryConfig } // Where appends a list predicates to the CardDelete builder. @@ -45,6 +46,7 @@ func (_d *CardDelete) ExecX(ctx context.Context) int { func (_d *CardDelete) sqlExec(ctx context.Context) (int, error) { _spec := sqlgraph.NewDeleteSpec(card.Table, sqlgraph.NewFieldSpec(card.FieldID, field.TypeInt)) + _spec.RetryConfig = _d.retryConfig if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -60,6 +62,13 @@ func (_d *CardDelete) sqlExec(ctx context.Context) (int, error) { return affected, err } +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *CardDelete) WithRetryOptions(opts ...any) *CardDelete { + _d.retryConfig.Options = opts + return _d +} + // CardDeleteOne is the builder for deleting a single Card entity. type CardDeleteOne struct { _d *CardDelete diff --git a/entc/integration/ent/card_query.go b/entc/integration/ent/card_query.go index 9b8f319b1d..8af02449f6 100644 --- a/entc/integration/ent/card_query.go +++ b/entc/integration/ent/card_query.go @@ -35,6 +35,7 @@ type CardQuery struct { withFKs bool modifiers []func(*sql.Selector) withNamedSpec map[string]*SpecQuery + retryConfig sql.RetryConfig // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -440,6 +441,7 @@ func (_q *CardQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Card, e if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig for i := range hooks { hooks[i](ctx, _spec) } @@ -576,6 +578,7 @@ func (_q *CardQuery) sqlCount(ctx context.Context) (int, error) { if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig _spec.Node.Columns = _q.ctx.Fields if len(_q.ctx.Fields) > 0 { _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique @@ -704,6 +707,13 @@ func (_q *CardQuery) WithNamedSpec(name string, opts ...func(*SpecQuery)) *CardQ return _q } +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *CardQuery) WithRetryOptions(opts ...any) *CardQuery { + _q.retryConfig.Options = opts + return _q +} + // CardGroupBy is the group-by builder for Card entities. type CardGroupBy struct { selector diff --git a/entc/integration/ent/card_update.go b/entc/integration/ent/card_update.go index 3eeffb0202..30df6c085a 100644 --- a/entc/integration/ent/card_update.go +++ b/entc/integration/ent/card_update.go @@ -24,9 +24,10 @@ import ( // CardUpdate is the builder for updating Card entities. type CardUpdate struct { config - hooks []Hook - mutation *CardMutation - modifiers []func(*sql.UpdateBuilder) + hooks []Hook + mutation *CardMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Where appends a list predicates to the CardUpdate builder. @@ -200,6 +201,13 @@ func (_u *CardUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *CardUpdat return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *CardUpdate) WithRetryOptions(opts ...any) *CardUpdate { + _u.retryConfig.Options = opts + return _u +} + func (_u *CardUpdate) sqlSave(ctx context.Context) (_node int, err error) { if err := _u.check(); err != nil { return _node, err @@ -302,8 +310,9 @@ func (_u *CardUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{card.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -317,10 +326,11 @@ func (_u *CardUpdate) sqlSave(ctx context.Context) (_node int, err error) { // CardUpdateOne is the builder for updating a single Card entity. type CardUpdateOne struct { config - fields []string - hooks []Hook - mutation *CardMutation - modifiers []func(*sql.UpdateBuilder) + fields []string + hooks []Hook + mutation *CardMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // SetUpdateTime sets the "update_time" field. @@ -501,6 +511,13 @@ func (_u *CardUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *CardUp return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *CardUpdateOne) WithRetryOptions(opts ...any) *CardUpdateOne { + _u.retryConfig.Options = opts + return _u +} + func (_u *CardUpdateOne) sqlSave(ctx context.Context) (_node *Card, err error) { if err := _u.check(); err != nil { return _node, err @@ -620,11 +637,12 @@ func (_u *CardUpdateOne) sqlSave(ctx context.Context) (_node *Card, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig _node = &Card{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{card.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/ent/client.go b/entc/integration/ent/client.go index c848a9fe37..9c603777ea 100644 --- a/entc/integration/ent/client.go +++ b/entc/integration/ent/client.go @@ -179,7 +179,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/entc/integration/ent/comment_create.go b/entc/integration/ent/comment_create.go index 3d30fb8ed8..bd422a6d50 100644 --- a/entc/integration/ent/comment_create.go +++ b/entc/integration/ent/comment_create.go @@ -21,9 +21,10 @@ import ( // CommentCreate is the builder for creating a Comment entity. type CommentCreate struct { config - mutation *CommentMutation - hooks []Hook - conflict []sql.ConflictOption + mutation *CommentMutation + hooks []Hook + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // SetUniqueInt sets the "unique_int" field. @@ -160,6 +161,7 @@ func (_c *CommentCreate) createSpec() (*Comment, *sqlgraph.CreateSpec) { _node = &Comment{config: _c.config} _spec = sqlgraph.NewCreateSpec(comment.Table, sqlgraph.NewFieldSpec(comment.FieldID, field.TypeInt)) ) + _spec.RetryConfig = _c.retryConfig _spec.OnConflict = _c.conflict if value, ok := _c.mutation.UniqueInt(); ok { _spec.SetField(comment.FieldUniqueInt, field.TypeInt, value) @@ -188,6 +190,13 @@ func (_c *CommentCreate) createSpec() (*Comment, *sqlgraph.CreateSpec) { return _node, _spec } +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *CommentCreate) WithRetryOptions(opts ...any) *CommentCreate { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // @@ -560,9 +569,10 @@ func (u *CommentUpsertOne) IDX(ctx context.Context) int { // CommentCreateBulk is the builder for creating many Comment entities in bulk. type CommentCreateBulk struct { config - err error - builders []*CommentCreate - conflict []sql.ConflictOption + err error + builders []*CommentCreate + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Save creates the Comment entities in the database. @@ -591,6 +601,7 @@ func (_c *CommentCreateBulk) Save(ctx context.Context) ([]*Comment, error) { _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig spec.OnConflict = _c.conflict // Invoke the actual operation on the latest mutation in the chain. if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { @@ -646,6 +657,13 @@ func (_c *CommentCreateBulk) ExecX(ctx context.Context) { } } +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *CommentCreateBulk) WithRetryOptions(opts ...any) *CommentCreateBulk { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // diff --git a/entc/integration/ent/comment_delete.go b/entc/integration/ent/comment_delete.go index 5e6d04f522..93e119c963 100644 --- a/entc/integration/ent/comment_delete.go +++ b/entc/integration/ent/comment_delete.go @@ -19,8 +19,9 @@ import ( // CommentDelete is the builder for deleting a Comment entity. type CommentDelete struct { config - hooks []Hook - mutation *CommentMutation + hooks []Hook + mutation *CommentMutation + retryConfig sql.RetryConfig } // Where appends a list predicates to the CommentDelete builder. @@ -45,6 +46,7 @@ func (_d *CommentDelete) ExecX(ctx context.Context) int { func (_d *CommentDelete) sqlExec(ctx context.Context) (int, error) { _spec := sqlgraph.NewDeleteSpec(comment.Table, sqlgraph.NewFieldSpec(comment.FieldID, field.TypeInt)) + _spec.RetryConfig = _d.retryConfig if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -60,6 +62,13 @@ func (_d *CommentDelete) sqlExec(ctx context.Context) (int, error) { return affected, err } +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *CommentDelete) WithRetryOptions(opts ...any) *CommentDelete { + _d.retryConfig.Options = opts + return _d +} + // CommentDeleteOne is the builder for deleting a single Comment entity. type CommentDeleteOne struct { _d *CommentDelete diff --git a/entc/integration/ent/comment_query.go b/entc/integration/ent/comment_query.go index a8e5165de9..c3baf3ad40 100644 --- a/entc/integration/ent/comment_query.go +++ b/entc/integration/ent/comment_query.go @@ -23,11 +23,12 @@ import ( // CommentQuery is the builder for querying Comment entities. type CommentQuery struct { config - ctx *QueryContext - order []comment.OrderOption - inters []Interceptor - predicates []predicate.Comment - modifiers []func(*sql.Selector) + ctx *QueryContext + order []comment.OrderOption + inters []Interceptor + predicates []predicate.Comment + modifiers []func(*sql.Selector) + retryConfig sql.RetryConfig // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -353,6 +354,7 @@ func (_q *CommentQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Comm if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig for i := range hooks { hooks[i](ctx, _spec) } @@ -370,6 +372,7 @@ func (_q *CommentQuery) sqlCount(ctx context.Context) (int, error) { if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig _spec.Node.Columns = _q.ctx.Fields if len(_q.ctx.Fields) > 0 { _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique @@ -484,6 +487,13 @@ func (_q *CommentQuery) Modify(modifiers ...func(s *sql.Selector)) *CommentSelec return _q.Select() } +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *CommentQuery) WithRetryOptions(opts ...any) *CommentQuery { + _q.retryConfig.Options = opts + return _q +} + // CommentGroupBy is the group-by builder for Comment entities. type CommentGroupBy struct { selector diff --git a/entc/integration/ent/comment_update.go b/entc/integration/ent/comment_update.go index 5a07e393a1..6cb40439ad 100644 --- a/entc/integration/ent/comment_update.go +++ b/entc/integration/ent/comment_update.go @@ -22,9 +22,10 @@ import ( // CommentUpdate is the builder for updating Comment entities. type CommentUpdate struct { config - hooks []Hook - mutation *CommentMutation - modifiers []func(*sql.UpdateBuilder) + hooks []Hook + mutation *CommentMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Where appends a list predicates to the CommentUpdate builder. @@ -200,6 +201,13 @@ func (_u *CommentUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *Commen return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *CommentUpdate) WithRetryOptions(opts ...any) *CommentUpdate { + _u.retryConfig.Options = opts + return _u +} + func (_u *CommentUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec := sqlgraph.NewUpdateSpec(comment.Table, comment.Columns, sqlgraph.NewFieldSpec(comment.FieldID, field.TypeInt)) if ps := _u.mutation.predicates; len(ps) > 0 { @@ -249,8 +257,9 @@ func (_u *CommentUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.ClearField(comment.FieldClient, field.TypeString) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{comment.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -264,10 +273,11 @@ func (_u *CommentUpdate) sqlSave(ctx context.Context) (_node int, err error) { // CommentUpdateOne is the builder for updating a single Comment entity. type CommentUpdateOne struct { config - fields []string - hooks []Hook - mutation *CommentMutation - modifiers []func(*sql.UpdateBuilder) + fields []string + hooks []Hook + mutation *CommentMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // SetUniqueInt sets the "unique_int" field. @@ -450,6 +460,13 @@ func (_u *CommentUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *Com return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *CommentUpdateOne) WithRetryOptions(opts ...any) *CommentUpdateOne { + _u.retryConfig.Options = opts + return _u +} + func (_u *CommentUpdateOne) sqlSave(ctx context.Context) (_node *Comment, err error) { _spec := sqlgraph.NewUpdateSpec(comment.Table, comment.Columns, sqlgraph.NewFieldSpec(comment.FieldID, field.TypeInt)) id, ok := _u.mutation.ID() @@ -516,11 +533,12 @@ func (_u *CommentUpdateOne) sqlSave(ctx context.Context) (_node *Comment, err er _spec.ClearField(comment.FieldClient, field.TypeString) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig _node = &Comment{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{comment.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/ent/exvaluescan_create.go b/entc/integration/ent/exvaluescan_create.go index 55fb92073f..ac8d39e056 100644 --- a/entc/integration/ent/exvaluescan_create.go +++ b/entc/integration/ent/exvaluescan_create.go @@ -22,9 +22,10 @@ import ( // ExValueScanCreate is the builder for creating a ExValueScan entity. type ExValueScanCreate struct { config - mutation *ExValueScanMutation - hooks []Hook - conflict []sql.ConflictOption + mutation *ExValueScanMutation + hooks []Hook + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // SetBinary sets the "binary" field. @@ -161,6 +162,7 @@ func (_c *ExValueScanCreate) createSpec() (*ExValueScan, *sqlgraph.CreateSpec, e _node = &ExValueScan{config: _c.config} _spec = sqlgraph.NewCreateSpec(exvaluescan.Table, sqlgraph.NewFieldSpec(exvaluescan.FieldID, field.TypeInt)) ) + _spec.RetryConfig = _c.retryConfig _spec.OnConflict = _c.conflict if value, ok := _c.mutation.Binary(); ok { vv, err := exvaluescan.ValueScanner.Binary.Value(value) @@ -229,6 +231,13 @@ func (_c *ExValueScanCreate) createSpec() (*ExValueScan, *sqlgraph.CreateSpec, e return _node, _spec, nil } +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *ExValueScanCreate) WithRetryOptions(opts ...any) *ExValueScanCreate { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // @@ -601,9 +610,10 @@ func (u *ExValueScanUpsertOne) IDX(ctx context.Context) int { // ExValueScanCreateBulk is the builder for creating many ExValueScan entities in bulk. type ExValueScanCreateBulk struct { config - err error - builders []*ExValueScanCreate - conflict []sql.ConflictOption + err error + builders []*ExValueScanCreate + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Save creates the ExValueScan entities in the database. @@ -635,6 +645,7 @@ func (_c *ExValueScanCreateBulk) Save(ctx context.Context) ([]*ExValueScan, erro _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig spec.OnConflict = _c.conflict // Invoke the actual operation on the latest mutation in the chain. if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { @@ -690,6 +701,13 @@ func (_c *ExValueScanCreateBulk) ExecX(ctx context.Context) { } } +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *ExValueScanCreateBulk) WithRetryOptions(opts ...any) *ExValueScanCreateBulk { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // diff --git a/entc/integration/ent/exvaluescan_delete.go b/entc/integration/ent/exvaluescan_delete.go index 3b9b8eb5e8..3c35359eb4 100644 --- a/entc/integration/ent/exvaluescan_delete.go +++ b/entc/integration/ent/exvaluescan_delete.go @@ -19,8 +19,9 @@ import ( // ExValueScanDelete is the builder for deleting a ExValueScan entity. type ExValueScanDelete struct { config - hooks []Hook - mutation *ExValueScanMutation + hooks []Hook + mutation *ExValueScanMutation + retryConfig sql.RetryConfig } // Where appends a list predicates to the ExValueScanDelete builder. @@ -45,6 +46,7 @@ func (_d *ExValueScanDelete) ExecX(ctx context.Context) int { func (_d *ExValueScanDelete) sqlExec(ctx context.Context) (int, error) { _spec := sqlgraph.NewDeleteSpec(exvaluescan.Table, sqlgraph.NewFieldSpec(exvaluescan.FieldID, field.TypeInt)) + _spec.RetryConfig = _d.retryConfig if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -60,6 +62,13 @@ func (_d *ExValueScanDelete) sqlExec(ctx context.Context) (int, error) { return affected, err } +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *ExValueScanDelete) WithRetryOptions(opts ...any) *ExValueScanDelete { + _d.retryConfig.Options = opts + return _d +} + // ExValueScanDeleteOne is the builder for deleting a single ExValueScan entity. type ExValueScanDeleteOne struct { _d *ExValueScanDelete diff --git a/entc/integration/ent/exvaluescan_query.go b/entc/integration/ent/exvaluescan_query.go index 76d343604d..a7f938c531 100644 --- a/entc/integration/ent/exvaluescan_query.go +++ b/entc/integration/ent/exvaluescan_query.go @@ -23,11 +23,12 @@ import ( // ExValueScanQuery is the builder for querying ExValueScan entities. type ExValueScanQuery struct { config - ctx *QueryContext - order []exvaluescan.OrderOption - inters []Interceptor - predicates []predicate.ExValueScan - modifiers []func(*sql.Selector) + ctx *QueryContext + order []exvaluescan.OrderOption + inters []Interceptor + predicates []predicate.ExValueScan + modifiers []func(*sql.Selector) + retryConfig sql.RetryConfig // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -353,6 +354,7 @@ func (_q *ExValueScanQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]* if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig for i := range hooks { hooks[i](ctx, _spec) } @@ -370,6 +372,7 @@ func (_q *ExValueScanQuery) sqlCount(ctx context.Context) (int, error) { if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig _spec.Node.Columns = _q.ctx.Fields if len(_q.ctx.Fields) > 0 { _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique @@ -484,6 +487,13 @@ func (_q *ExValueScanQuery) Modify(modifiers ...func(s *sql.Selector)) *ExValueS return _q.Select() } +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *ExValueScanQuery) WithRetryOptions(opts ...any) *ExValueScanQuery { + _q.retryConfig.Options = opts + return _q +} + // ExValueScanGroupBy is the group-by builder for ExValueScan entities. type ExValueScanGroupBy struct { selector diff --git a/entc/integration/ent/exvaluescan_update.go b/entc/integration/ent/exvaluescan_update.go index 389c051db1..855ad39a59 100644 --- a/entc/integration/ent/exvaluescan_update.go +++ b/entc/integration/ent/exvaluescan_update.go @@ -23,9 +23,10 @@ import ( // ExValueScanUpdate is the builder for updating ExValueScan entities. type ExValueScanUpdate struct { config - hooks []Hook - mutation *ExValueScanMutation - modifiers []func(*sql.UpdateBuilder) + hooks []Hook + mutation *ExValueScanMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Where appends a list predicates to the ExValueScanUpdate builder. @@ -162,6 +163,13 @@ func (_u *ExValueScanUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *Ex return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *ExValueScanUpdate) WithRetryOptions(opts ...any) *ExValueScanUpdate { + _u.retryConfig.Options = opts + return _u +} + func (_u *ExValueScanUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec := sqlgraph.NewUpdateSpec(exvaluescan.Table, exvaluescan.Columns, sqlgraph.NewFieldSpec(exvaluescan.FieldID, field.TypeInt)) if ps := _u.mutation.predicates; len(ps) > 0 { @@ -237,8 +245,9 @@ func (_u *ExValueScanUpdate) sqlSave(ctx context.Context) (_node int, err error) _spec.ClearField(exvaluescan.FieldCustomOptional, field.TypeString) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{exvaluescan.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -252,10 +261,11 @@ func (_u *ExValueScanUpdate) sqlSave(ctx context.Context) (_node int, err error) // ExValueScanUpdateOne is the builder for updating a single ExValueScan entity. type ExValueScanUpdateOne struct { config - fields []string - hooks []Hook - mutation *ExValueScanMutation - modifiers []func(*sql.UpdateBuilder) + fields []string + hooks []Hook + mutation *ExValueScanMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // SetBinary sets the "binary" field. @@ -399,6 +409,13 @@ func (_u *ExValueScanUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *ExValueScanUpdateOne) WithRetryOptions(opts ...any) *ExValueScanUpdateOne { + _u.retryConfig.Options = opts + return _u +} + func (_u *ExValueScanUpdateOne) sqlSave(ctx context.Context) (_node *ExValueScan, err error) { _spec := sqlgraph.NewUpdateSpec(exvaluescan.Table, exvaluescan.Columns, sqlgraph.NewFieldSpec(exvaluescan.FieldID, field.TypeInt)) id, ok := _u.mutation.ID() @@ -491,11 +508,12 @@ func (_u *ExValueScanUpdateOne) sqlSave(ctx context.Context) (_node *ExValueScan _spec.ClearField(exvaluescan.FieldCustomOptional, field.TypeString) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig _node = &ExValueScan{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{exvaluescan.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/ent/fieldtype_create.go b/entc/integration/ent/fieldtype_create.go index 5b4f8776e9..9c84c807a4 100644 --- a/entc/integration/ent/fieldtype_create.go +++ b/entc/integration/ent/fieldtype_create.go @@ -26,9 +26,10 @@ import ( // FieldTypeCreate is the builder for creating a FieldType entity. type FieldTypeCreate struct { config - mutation *FieldTypeMutation - hooks []Hook - conflict []sql.ConflictOption + mutation *FieldTypeMutation + hooks []Hook + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // SetInt sets the "int" field. @@ -973,6 +974,7 @@ func (_c *FieldTypeCreate) createSpec() (*FieldType, *sqlgraph.CreateSpec) { _node = &FieldType{config: _c.config} _spec = sqlgraph.NewCreateSpec(fieldtype.Table, sqlgraph.NewFieldSpec(fieldtype.FieldID, field.TypeInt)) ) + _spec.RetryConfig = _c.retryConfig _spec.OnConflict = _c.conflict if value, ok := _c.mutation.Int(); ok { _spec.SetField(fieldtype.FieldInt, field.TypeInt, value) @@ -1237,6 +1239,13 @@ func (_c *FieldTypeCreate) createSpec() (*FieldType, *sqlgraph.CreateSpec) { return _node, _spec } +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *FieldTypeCreate) WithRetryOptions(opts ...any) *FieldTypeCreate { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // @@ -4170,9 +4179,10 @@ func (u *FieldTypeUpsertOne) IDX(ctx context.Context) int { // FieldTypeCreateBulk is the builder for creating many FieldType entities in bulk. type FieldTypeCreateBulk struct { config - err error - builders []*FieldTypeCreate - conflict []sql.ConflictOption + err error + builders []*FieldTypeCreate + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Save creates the FieldType entities in the database. @@ -4202,6 +4212,7 @@ func (_c *FieldTypeCreateBulk) Save(ctx context.Context) ([]*FieldType, error) { _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig spec.OnConflict = _c.conflict // Invoke the actual operation on the latest mutation in the chain. if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { @@ -4257,6 +4268,13 @@ func (_c *FieldTypeCreateBulk) ExecX(ctx context.Context) { } } +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *FieldTypeCreateBulk) WithRetryOptions(opts ...any) *FieldTypeCreateBulk { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // diff --git a/entc/integration/ent/fieldtype_delete.go b/entc/integration/ent/fieldtype_delete.go index 28e4ccbcd9..c08698333c 100644 --- a/entc/integration/ent/fieldtype_delete.go +++ b/entc/integration/ent/fieldtype_delete.go @@ -19,8 +19,9 @@ import ( // FieldTypeDelete is the builder for deleting a FieldType entity. type FieldTypeDelete struct { config - hooks []Hook - mutation *FieldTypeMutation + hooks []Hook + mutation *FieldTypeMutation + retryConfig sql.RetryConfig } // Where appends a list predicates to the FieldTypeDelete builder. @@ -45,6 +46,7 @@ func (_d *FieldTypeDelete) ExecX(ctx context.Context) int { func (_d *FieldTypeDelete) sqlExec(ctx context.Context) (int, error) { _spec := sqlgraph.NewDeleteSpec(fieldtype.Table, sqlgraph.NewFieldSpec(fieldtype.FieldID, field.TypeInt)) + _spec.RetryConfig = _d.retryConfig if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -60,6 +62,13 @@ func (_d *FieldTypeDelete) sqlExec(ctx context.Context) (int, error) { return affected, err } +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *FieldTypeDelete) WithRetryOptions(opts ...any) *FieldTypeDelete { + _d.retryConfig.Options = opts + return _d +} + // FieldTypeDeleteOne is the builder for deleting a single FieldType entity. type FieldTypeDeleteOne struct { _d *FieldTypeDelete diff --git a/entc/integration/ent/fieldtype_query.go b/entc/integration/ent/fieldtype_query.go index 639514fac4..1ea3fa68f8 100644 --- a/entc/integration/ent/fieldtype_query.go +++ b/entc/integration/ent/fieldtype_query.go @@ -23,12 +23,13 @@ import ( // FieldTypeQuery is the builder for querying FieldType entities. type FieldTypeQuery struct { config - ctx *QueryContext - order []fieldtype.OrderOption - inters []Interceptor - predicates []predicate.FieldType - withFKs bool - modifiers []func(*sql.Selector) + ctx *QueryContext + order []fieldtype.OrderOption + inters []Interceptor + predicates []predicate.FieldType + withFKs bool + modifiers []func(*sql.Selector) + retryConfig sql.RetryConfig // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -358,6 +359,7 @@ func (_q *FieldTypeQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Fi if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig for i := range hooks { hooks[i](ctx, _spec) } @@ -375,6 +377,7 @@ func (_q *FieldTypeQuery) sqlCount(ctx context.Context) (int, error) { if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig _spec.Node.Columns = _q.ctx.Fields if len(_q.ctx.Fields) > 0 { _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique @@ -489,6 +492,13 @@ func (_q *FieldTypeQuery) Modify(modifiers ...func(s *sql.Selector)) *FieldTypeS return _q.Select() } +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *FieldTypeQuery) WithRetryOptions(opts ...any) *FieldTypeQuery { + _q.retryConfig.Options = opts + return _q +} + // FieldTypeGroupBy is the group-by builder for FieldType entities. type FieldTypeGroupBy struct { selector diff --git a/entc/integration/ent/fieldtype_update.go b/entc/integration/ent/fieldtype_update.go index eda886c8e1..a26206cf23 100644 --- a/entc/integration/ent/fieldtype_update.go +++ b/entc/integration/ent/fieldtype_update.go @@ -28,9 +28,10 @@ import ( // FieldTypeUpdate is the builder for updating FieldType entities. type FieldTypeUpdate struct { config - hooks []Hook - mutation *FieldTypeMutation - modifiers []func(*sql.UpdateBuilder) + hooks []Hook + mutation *FieldTypeMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Where appends a list predicates to the FieldTypeUpdate builder. @@ -1447,6 +1448,13 @@ func (_u *FieldTypeUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *Fiel return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *FieldTypeUpdate) WithRetryOptions(opts ...any) *FieldTypeUpdate { + _u.retryConfig.Options = opts + return _u +} + func (_u *FieldTypeUpdate) sqlSave(ctx context.Context) (_node int, err error) { if err := _u.check(); err != nil { return _node, err @@ -1918,8 +1926,9 @@ func (_u *FieldTypeUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.ClearField(fieldtype.FieldPasswordOther, field.TypeOther) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{fieldtype.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -1933,10 +1942,11 @@ func (_u *FieldTypeUpdate) sqlSave(ctx context.Context) (_node int, err error) { // FieldTypeUpdateOne is the builder for updating a single FieldType entity. type FieldTypeUpdateOne struct { config - fields []string - hooks []Hook - mutation *FieldTypeMutation - modifiers []func(*sql.UpdateBuilder) + fields []string + hooks []Hook + mutation *FieldTypeMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // SetInt sets the "int" field. @@ -3360,6 +3370,13 @@ func (_u *FieldTypeUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *F return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *FieldTypeUpdateOne) WithRetryOptions(opts ...any) *FieldTypeUpdateOne { + _u.retryConfig.Options = opts + return _u +} + func (_u *FieldTypeUpdateOne) sqlSave(ctx context.Context) (_node *FieldType, err error) { if err := _u.check(); err != nil { return _node, err @@ -3848,11 +3865,12 @@ func (_u *FieldTypeUpdateOne) sqlSave(ctx context.Context) (_node *FieldType, er _spec.ClearField(fieldtype.FieldPasswordOther, field.TypeOther) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig _node = &FieldType{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{fieldtype.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/ent/file_create.go b/entc/integration/ent/file_create.go index 6130182028..b989f0ae66 100644 --- a/entc/integration/ent/file_create.go +++ b/entc/integration/ent/file_create.go @@ -24,9 +24,10 @@ import ( // FileCreate is the builder for creating a File entity. type FileCreate struct { config - mutation *FileMutation - hooks []Hook - conflict []sql.ConflictOption + mutation *FileMutation + hooks []Hook + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // SetSetID sets the "set_id" field. @@ -271,6 +272,7 @@ func (_c *FileCreate) createSpec() (*File, *sqlgraph.CreateSpec) { _node = &File{config: _c.config} _spec = sqlgraph.NewCreateSpec(file.Table, sqlgraph.NewFieldSpec(file.FieldID, field.TypeInt)) ) + _spec.RetryConfig = _c.retryConfig _spec.OnConflict = _c.conflict if value, ok := _c.mutation.SetID(); ok { _spec.SetField(file.FieldSetID, field.TypeInt, value) @@ -357,6 +359,13 @@ func (_c *FileCreate) createSpec() (*File, *sqlgraph.CreateSpec) { return _node, _spec } +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *FileCreate) WithRetryOptions(opts ...any) *FileCreate { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // @@ -807,9 +816,10 @@ func (u *FileUpsertOne) IDX(ctx context.Context) int { // FileCreateBulk is the builder for creating many File entities in bulk. type FileCreateBulk struct { config - err error - builders []*FileCreate - conflict []sql.ConflictOption + err error + builders []*FileCreate + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Save creates the File entities in the database. @@ -839,6 +849,7 @@ func (_c *FileCreateBulk) Save(ctx context.Context) ([]*File, error) { _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig spec.OnConflict = _c.conflict // Invoke the actual operation on the latest mutation in the chain. if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { @@ -894,6 +905,13 @@ func (_c *FileCreateBulk) ExecX(ctx context.Context) { } } +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *FileCreateBulk) WithRetryOptions(opts ...any) *FileCreateBulk { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // diff --git a/entc/integration/ent/file_delete.go b/entc/integration/ent/file_delete.go index c6a5d4f570..e3b570ae33 100644 --- a/entc/integration/ent/file_delete.go +++ b/entc/integration/ent/file_delete.go @@ -19,8 +19,9 @@ import ( // FileDelete is the builder for deleting a File entity. type FileDelete struct { config - hooks []Hook - mutation *FileMutation + hooks []Hook + mutation *FileMutation + retryConfig sql.RetryConfig } // Where appends a list predicates to the FileDelete builder. @@ -45,6 +46,7 @@ func (_d *FileDelete) ExecX(ctx context.Context) int { func (_d *FileDelete) sqlExec(ctx context.Context) (int, error) { _spec := sqlgraph.NewDeleteSpec(file.Table, sqlgraph.NewFieldSpec(file.FieldID, field.TypeInt)) + _spec.RetryConfig = _d.retryConfig if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -60,6 +62,13 @@ func (_d *FileDelete) sqlExec(ctx context.Context) (int, error) { return affected, err } +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *FileDelete) WithRetryOptions(opts ...any) *FileDelete { + _d.retryConfig.Options = opts + return _d +} + // FileDeleteOne is the builder for deleting a single File entity. type FileDeleteOne struct { _d *FileDelete diff --git a/entc/integration/ent/file_query.go b/entc/integration/ent/file_query.go index e5769c49b8..0cfa86a0f1 100644 --- a/entc/integration/ent/file_query.go +++ b/entc/integration/ent/file_query.go @@ -37,6 +37,7 @@ type FileQuery struct { withFKs bool modifiers []func(*sql.Selector) withNamedField map[string]*FieldTypeQuery + retryConfig sql.RetryConfig // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -477,6 +478,7 @@ func (_q *FileQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*File, e if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig for i := range hooks { hooks[i](ctx, _spec) } @@ -616,6 +618,7 @@ func (_q *FileQuery) sqlCount(ctx context.Context) (int, error) { if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig _spec.Node.Columns = _q.ctx.Fields if len(_q.ctx.Fields) > 0 { _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique @@ -744,6 +747,13 @@ func (_q *FileQuery) WithNamedField(name string, opts ...func(*FieldTypeQuery)) return _q } +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *FileQuery) WithRetryOptions(opts ...any) *FileQuery { + _q.retryConfig.Options = opts + return _q +} + // FileGroupBy is the group-by builder for File entities. type FileGroupBy struct { selector diff --git a/entc/integration/ent/file_update.go b/entc/integration/ent/file_update.go index 2b1e5eb831..90b25b9939 100644 --- a/entc/integration/ent/file_update.go +++ b/entc/integration/ent/file_update.go @@ -25,9 +25,10 @@ import ( // FileUpdate is the builder for updating File entities. type FileUpdate struct { config - hooks []Hook - mutation *FileMutation - modifiers []func(*sql.UpdateBuilder) + hooks []Hook + mutation *FileMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Where appends a list predicates to the FileUpdate builder. @@ -344,6 +345,13 @@ func (_u *FileUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *FileUpdat return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *FileUpdate) WithRetryOptions(opts ...any) *FileUpdate { + _u.retryConfig.Options = opts + return _u +} + func (_u *FileUpdate) sqlSave(ctx context.Context) (_node int, err error) { if err := _u.check(); err != nil { return _node, err @@ -511,8 +519,9 @@ func (_u *FileUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{file.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -526,10 +535,11 @@ func (_u *FileUpdate) sqlSave(ctx context.Context) (_node int, err error) { // FileUpdateOne is the builder for updating a single File entity. type FileUpdateOne struct { config - fields []string - hooks []Hook - mutation *FileMutation - modifiers []func(*sql.UpdateBuilder) + fields []string + hooks []Hook + mutation *FileMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // SetSetID sets the "set_id" field. @@ -853,6 +863,13 @@ func (_u *FileUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *FileUp return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *FileUpdateOne) WithRetryOptions(opts ...any) *FileUpdateOne { + _u.retryConfig.Options = opts + return _u +} + func (_u *FileUpdateOne) sqlSave(ctx context.Context) (_node *File, err error) { if err := _u.check(); err != nil { return _node, err @@ -1037,11 +1054,12 @@ func (_u *FileUpdateOne) sqlSave(ctx context.Context) (_node *File, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig _node = &File{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{file.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/ent/filetype_create.go b/entc/integration/ent/filetype_create.go index 8b7923bc37..7acd4c3bce 100644 --- a/entc/integration/ent/filetype_create.go +++ b/entc/integration/ent/filetype_create.go @@ -21,9 +21,10 @@ import ( // FileTypeCreate is the builder for creating a FileType entity. type FileTypeCreate struct { config - mutation *FileTypeMutation - hooks []Hook - conflict []sql.ConflictOption + mutation *FileTypeMutation + hooks []Hook + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // SetName sets the "name" field. @@ -167,6 +168,7 @@ func (_c *FileTypeCreate) createSpec() (*FileType, *sqlgraph.CreateSpec) { _node = &FileType{config: _c.config} _spec = sqlgraph.NewCreateSpec(filetype.Table, sqlgraph.NewFieldSpec(filetype.FieldID, field.TypeInt)) ) + _spec.RetryConfig = _c.retryConfig _spec.OnConflict = _c.conflict if value, ok := _c.mutation.Name(); ok { _spec.SetField(filetype.FieldName, field.TypeString, value) @@ -199,6 +201,13 @@ func (_c *FileTypeCreate) createSpec() (*FileType, *sqlgraph.CreateSpec) { return _node, _spec } +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *FileTypeCreate) WithRetryOptions(opts ...any) *FileTypeCreate { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // @@ -402,9 +411,10 @@ func (u *FileTypeUpsertOne) IDX(ctx context.Context) int { // FileTypeCreateBulk is the builder for creating many FileType entities in bulk. type FileTypeCreateBulk struct { config - err error - builders []*FileTypeCreate - conflict []sql.ConflictOption + err error + builders []*FileTypeCreate + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Save creates the FileType entities in the database. @@ -434,6 +444,7 @@ func (_c *FileTypeCreateBulk) Save(ctx context.Context) ([]*FileType, error) { _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig spec.OnConflict = _c.conflict // Invoke the actual operation on the latest mutation in the chain. if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { @@ -489,6 +500,13 @@ func (_c *FileTypeCreateBulk) ExecX(ctx context.Context) { } } +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *FileTypeCreateBulk) WithRetryOptions(opts ...any) *FileTypeCreateBulk { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // diff --git a/entc/integration/ent/filetype_delete.go b/entc/integration/ent/filetype_delete.go index cdc590de47..aed5948604 100644 --- a/entc/integration/ent/filetype_delete.go +++ b/entc/integration/ent/filetype_delete.go @@ -19,8 +19,9 @@ import ( // FileTypeDelete is the builder for deleting a FileType entity. type FileTypeDelete struct { config - hooks []Hook - mutation *FileTypeMutation + hooks []Hook + mutation *FileTypeMutation + retryConfig sql.RetryConfig } // Where appends a list predicates to the FileTypeDelete builder. @@ -45,6 +46,7 @@ func (_d *FileTypeDelete) ExecX(ctx context.Context) int { func (_d *FileTypeDelete) sqlExec(ctx context.Context) (int, error) { _spec := sqlgraph.NewDeleteSpec(filetype.Table, sqlgraph.NewFieldSpec(filetype.FieldID, field.TypeInt)) + _spec.RetryConfig = _d.retryConfig if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -60,6 +62,13 @@ func (_d *FileTypeDelete) sqlExec(ctx context.Context) (int, error) { return affected, err } +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *FileTypeDelete) WithRetryOptions(opts ...any) *FileTypeDelete { + _d.retryConfig.Options = opts + return _d +} + // FileTypeDeleteOne is the builder for deleting a single FileType entity. type FileTypeDeleteOne struct { _d *FileTypeDelete diff --git a/entc/integration/ent/filetype_query.go b/entc/integration/ent/filetype_query.go index f03514db3b..720c82a824 100644 --- a/entc/integration/ent/filetype_query.go +++ b/entc/integration/ent/filetype_query.go @@ -32,6 +32,7 @@ type FileTypeQuery struct { withFiles *FileQuery modifiers []func(*sql.Selector) withNamedFiles map[string]*FileQuery + retryConfig sql.RetryConfig // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -395,6 +396,7 @@ func (_q *FileTypeQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Fil if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig for i := range hooks { hooks[i](ctx, _spec) } @@ -468,6 +470,7 @@ func (_q *FileTypeQuery) sqlCount(ctx context.Context) (int, error) { if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig _spec.Node.Columns = _q.ctx.Fields if len(_q.ctx.Fields) > 0 { _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique @@ -596,6 +599,13 @@ func (_q *FileTypeQuery) WithNamedFiles(name string, opts ...func(*FileQuery)) * return _q } +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *FileTypeQuery) WithRetryOptions(opts ...any) *FileTypeQuery { + _q.retryConfig.Options = opts + return _q +} + // FileTypeGroupBy is the group-by builder for FileType entities. type FileTypeGroupBy struct { selector diff --git a/entc/integration/ent/filetype_update.go b/entc/integration/ent/filetype_update.go index ef57d68545..7a9d983507 100644 --- a/entc/integration/ent/filetype_update.go +++ b/entc/integration/ent/filetype_update.go @@ -22,9 +22,10 @@ import ( // FileTypeUpdate is the builder for updating FileType entities. type FileTypeUpdate struct { config - hooks []Hook - mutation *FileTypeMutation - modifiers []func(*sql.UpdateBuilder) + hooks []Hook + mutation *FileTypeMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Where appends a list predicates to the FileTypeUpdate builder. @@ -164,6 +165,13 @@ func (_u *FileTypeUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *FileT return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *FileTypeUpdate) WithRetryOptions(opts ...any) *FileTypeUpdate { + _u.retryConfig.Options = opts + return _u +} + func (_u *FileTypeUpdate) sqlSave(ctx context.Context) (_node int, err error) { if err := _u.check(); err != nil { return _node, err @@ -231,8 +239,9 @@ func (_u *FileTypeUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{filetype.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -246,10 +255,11 @@ func (_u *FileTypeUpdate) sqlSave(ctx context.Context) (_node int, err error) { // FileTypeUpdateOne is the builder for updating a single FileType entity. type FileTypeUpdateOne struct { config - fields []string - hooks []Hook - mutation *FileTypeMutation - modifiers []func(*sql.UpdateBuilder) + fields []string + hooks []Hook + mutation *FileTypeMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // SetName sets the "name" field. @@ -396,6 +406,13 @@ func (_u *FileTypeUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *Fi return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *FileTypeUpdateOne) WithRetryOptions(opts ...any) *FileTypeUpdateOne { + _u.retryConfig.Options = opts + return _u +} + func (_u *FileTypeUpdateOne) sqlSave(ctx context.Context) (_node *FileType, err error) { if err := _u.check(); err != nil { return _node, err @@ -480,11 +497,12 @@ func (_u *FileTypeUpdateOne) sqlSave(ctx context.Context) (_node *FileType, err _spec.Edges.Add = append(_spec.Edges.Add, edge) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig _node = &FileType{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{filetype.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/ent/generate.go b/entc/integration/ent/generate.go index 98a2607f37..6f7e2ee331 100644 --- a/entc/integration/ent/generate.go +++ b/entc/integration/ent/generate.go @@ -4,4 +4,4 @@ package ent -//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate --feature entql,sql/modifier,sql/lock,sql/upsert,sql/execquery,namedges,bidiedges,sql/globalid --template ./template --header "// Copyright 2019-present Facebook Inc. All rights reserved.\n// This source code is licensed under the Apache 2.0 license found\n// in the LICENSE file in the root directory of this source tree.\n\n// Code generated by ent, DO NOT EDIT." ./schema +//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate --feature entql,sql/modifier,sql/lock,sql/upsert,sql/execquery,namedges,bidiedges,sql/globalid,sql/retryoptions --template ./template --header "// Copyright 2019-present Facebook Inc. All rights reserved.\n// This source code is licensed under the Apache 2.0 license found\n// in the LICENSE file in the root directory of this source tree.\n\n// Code generated by ent, DO NOT EDIT." ./schema diff --git a/entc/integration/ent/goods_create.go b/entc/integration/ent/goods_create.go index 5c13ecad9c..dbe0c88b5e 100644 --- a/entc/integration/ent/goods_create.go +++ b/entc/integration/ent/goods_create.go @@ -20,9 +20,10 @@ import ( // GoodsCreate is the builder for creating a Goods entity. type GoodsCreate struct { config - mutation *GoodsMutation - hooks []Hook - conflict []sql.ConflictOption + mutation *GoodsMutation + hooks []Hook + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Mutation returns the GoodsMutation object of the builder. @@ -85,10 +86,18 @@ func (_c *GoodsCreate) createSpec() (*Goods, *sqlgraph.CreateSpec) { _node = &Goods{config: _c.config} _spec = sqlgraph.NewCreateSpec(goods.Table, sqlgraph.NewFieldSpec(goods.FieldID, field.TypeInt)) ) + _spec.RetryConfig = _c.retryConfig _spec.OnConflict = _c.conflict return _node, _spec } +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *GoodsCreate) WithRetryOptions(opts ...any) *GoodsCreate { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // @@ -208,9 +217,10 @@ func (u *GoodsUpsertOne) IDX(ctx context.Context) int { // GoodsCreateBulk is the builder for creating many Goods entities in bulk. type GoodsCreateBulk struct { config - err error - builders []*GoodsCreate - conflict []sql.ConflictOption + err error + builders []*GoodsCreate + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Save creates the Goods entities in the database. @@ -239,6 +249,7 @@ func (_c *GoodsCreateBulk) Save(ctx context.Context) ([]*Goods, error) { _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig spec.OnConflict = _c.conflict // Invoke the actual operation on the latest mutation in the chain. if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { @@ -294,6 +305,13 @@ func (_c *GoodsCreateBulk) ExecX(ctx context.Context) { } } +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *GoodsCreateBulk) WithRetryOptions(opts ...any) *GoodsCreateBulk { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // diff --git a/entc/integration/ent/goods_delete.go b/entc/integration/ent/goods_delete.go index cc05623319..95d1cefec2 100644 --- a/entc/integration/ent/goods_delete.go +++ b/entc/integration/ent/goods_delete.go @@ -19,8 +19,9 @@ import ( // GoodsDelete is the builder for deleting a Goods entity. type GoodsDelete struct { config - hooks []Hook - mutation *GoodsMutation + hooks []Hook + mutation *GoodsMutation + retryConfig sql.RetryConfig } // Where appends a list predicates to the GoodsDelete builder. @@ -45,6 +46,7 @@ func (_d *GoodsDelete) ExecX(ctx context.Context) int { func (_d *GoodsDelete) sqlExec(ctx context.Context) (int, error) { _spec := sqlgraph.NewDeleteSpec(goods.Table, sqlgraph.NewFieldSpec(goods.FieldID, field.TypeInt)) + _spec.RetryConfig = _d.retryConfig if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -60,6 +62,13 @@ func (_d *GoodsDelete) sqlExec(ctx context.Context) (int, error) { return affected, err } +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *GoodsDelete) WithRetryOptions(opts ...any) *GoodsDelete { + _d.retryConfig.Options = opts + return _d +} + // GoodsDeleteOne is the builder for deleting a single Goods entity. type GoodsDeleteOne struct { _d *GoodsDelete diff --git a/entc/integration/ent/goods_query.go b/entc/integration/ent/goods_query.go index 87a19f788a..467114a544 100644 --- a/entc/integration/ent/goods_query.go +++ b/entc/integration/ent/goods_query.go @@ -23,11 +23,12 @@ import ( // GoodsQuery is the builder for querying Goods entities. type GoodsQuery struct { config - ctx *QueryContext - order []goods.OrderOption - inters []Interceptor - predicates []predicate.Goods - modifiers []func(*sql.Selector) + ctx *QueryContext + order []goods.OrderOption + inters []Interceptor + predicates []predicate.Goods + modifiers []func(*sql.Selector) + retryConfig sql.RetryConfig // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -331,6 +332,7 @@ func (_q *GoodsQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Goods, if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig for i := range hooks { hooks[i](ctx, _spec) } @@ -348,6 +350,7 @@ func (_q *GoodsQuery) sqlCount(ctx context.Context) (int, error) { if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig _spec.Node.Columns = _q.ctx.Fields if len(_q.ctx.Fields) > 0 { _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique @@ -462,6 +465,13 @@ func (_q *GoodsQuery) Modify(modifiers ...func(s *sql.Selector)) *GoodsSelect { return _q.Select() } +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *GoodsQuery) WithRetryOptions(opts ...any) *GoodsQuery { + _q.retryConfig.Options = opts + return _q +} + // GoodsGroupBy is the group-by builder for Goods entities. type GoodsGroupBy struct { selector diff --git a/entc/integration/ent/goods_update.go b/entc/integration/ent/goods_update.go index e0105fddd3..70c2a2f242 100644 --- a/entc/integration/ent/goods_update.go +++ b/entc/integration/ent/goods_update.go @@ -21,9 +21,10 @@ import ( // GoodsUpdate is the builder for updating Goods entities. type GoodsUpdate struct { config - hooks []Hook - mutation *GoodsMutation - modifiers []func(*sql.UpdateBuilder) + hooks []Hook + mutation *GoodsMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Where appends a list predicates to the GoodsUpdate builder. @@ -70,6 +71,13 @@ func (_u *GoodsUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *GoodsUpd return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *GoodsUpdate) WithRetryOptions(opts ...any) *GoodsUpdate { + _u.retryConfig.Options = opts + return _u +} + func (_u *GoodsUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec := sqlgraph.NewUpdateSpec(goods.Table, goods.Columns, sqlgraph.NewFieldSpec(goods.FieldID, field.TypeInt)) if ps := _u.mutation.predicates; len(ps) > 0 { @@ -80,8 +88,9 @@ func (_u *GoodsUpdate) sqlSave(ctx context.Context) (_node int, err error) { } } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{goods.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -95,10 +104,11 @@ func (_u *GoodsUpdate) sqlSave(ctx context.Context) (_node int, err error) { // GoodsUpdateOne is the builder for updating a single Goods entity. type GoodsUpdateOne struct { config - fields []string - hooks []Hook - mutation *GoodsMutation - modifiers []func(*sql.UpdateBuilder) + fields []string + hooks []Hook + mutation *GoodsMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Mutation returns the GoodsMutation object of the builder. @@ -152,6 +162,13 @@ func (_u *GoodsUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *Goods return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *GoodsUpdateOne) WithRetryOptions(opts ...any) *GoodsUpdateOne { + _u.retryConfig.Options = opts + return _u +} + func (_u *GoodsUpdateOne) sqlSave(ctx context.Context) (_node *Goods, err error) { _spec := sqlgraph.NewUpdateSpec(goods.Table, goods.Columns, sqlgraph.NewFieldSpec(goods.FieldID, field.TypeInt)) id, ok := _u.mutation.ID() @@ -179,11 +196,12 @@ func (_u *GoodsUpdateOne) sqlSave(ctx context.Context) (_node *Goods, err error) } } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig _node = &Goods{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{goods.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/ent/group_create.go b/entc/integration/ent/group_create.go index 5b5506a68c..e8d46a90ad 100644 --- a/entc/integration/ent/group_create.go +++ b/entc/integration/ent/group_create.go @@ -24,9 +24,10 @@ import ( // GroupCreate is the builder for creating a Group entity. type GroupCreate struct { config - mutation *GroupMutation - hooks []Hook - conflict []sql.ConflictOption + mutation *GroupMutation + hooks []Hook + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // SetActive sets the "active" field. @@ -239,6 +240,7 @@ func (_c *GroupCreate) createSpec() (*Group, *sqlgraph.CreateSpec) { _node = &Group{config: _c.config} _spec = sqlgraph.NewCreateSpec(group.Table, sqlgraph.NewFieldSpec(group.FieldID, field.TypeInt)) ) + _spec.RetryConfig = _c.retryConfig _spec.OnConflict = _c.conflict if value, ok := _c.mutation.Active(); ok { _spec.SetField(group.FieldActive, field.TypeBool, value) @@ -328,6 +330,13 @@ func (_c *GroupCreate) createSpec() (*Group, *sqlgraph.CreateSpec) { return _node, _spec } +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *GroupCreate) WithRetryOptions(opts ...any) *GroupCreate { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // @@ -622,9 +631,10 @@ func (u *GroupUpsertOne) IDX(ctx context.Context) int { // GroupCreateBulk is the builder for creating many Group entities in bulk. type GroupCreateBulk struct { config - err error - builders []*GroupCreate - conflict []sql.ConflictOption + err error + builders []*GroupCreate + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Save creates the Group entities in the database. @@ -654,6 +664,7 @@ func (_c *GroupCreateBulk) Save(ctx context.Context) ([]*Group, error) { _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig spec.OnConflict = _c.conflict // Invoke the actual operation on the latest mutation in the chain. if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { @@ -709,6 +720,13 @@ func (_c *GroupCreateBulk) ExecX(ctx context.Context) { } } +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *GroupCreateBulk) WithRetryOptions(opts ...any) *GroupCreateBulk { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // diff --git a/entc/integration/ent/group_delete.go b/entc/integration/ent/group_delete.go index c1555ee064..c1cbe6a2ff 100644 --- a/entc/integration/ent/group_delete.go +++ b/entc/integration/ent/group_delete.go @@ -19,8 +19,9 @@ import ( // GroupDelete is the builder for deleting a Group entity. type GroupDelete struct { config - hooks []Hook - mutation *GroupMutation + hooks []Hook + mutation *GroupMutation + retryConfig sql.RetryConfig } // Where appends a list predicates to the GroupDelete builder. @@ -45,6 +46,7 @@ func (_d *GroupDelete) ExecX(ctx context.Context) int { func (_d *GroupDelete) sqlExec(ctx context.Context) (int, error) { _spec := sqlgraph.NewDeleteSpec(group.Table, sqlgraph.NewFieldSpec(group.FieldID, field.TypeInt)) + _spec.RetryConfig = _d.retryConfig if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -60,6 +62,13 @@ func (_d *GroupDelete) sqlExec(ctx context.Context) (int, error) { return affected, err } +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *GroupDelete) WithRetryOptions(opts ...any) *GroupDelete { + _d.retryConfig.Options = opts + return _d +} + // GroupDeleteOne is the builder for deleting a single Group entity. type GroupDeleteOne struct { _d *GroupDelete diff --git a/entc/integration/ent/group_query.go b/entc/integration/ent/group_query.go index 295755d48a..233675c2c8 100644 --- a/entc/integration/ent/group_query.go +++ b/entc/integration/ent/group_query.go @@ -40,6 +40,7 @@ type GroupQuery struct { withNamedFiles map[string]*FileQuery withNamedBlocked map[string]*UserQuery withNamedUsers map[string]*UserQuery + retryConfig sql.RetryConfig // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -515,6 +516,7 @@ func (_q *GroupQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Group, if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig for i := range hooks { hooks[i](ctx, _spec) } @@ -736,6 +738,7 @@ func (_q *GroupQuery) sqlCount(ctx context.Context) (int, error) { if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig _spec.Node.Columns = _q.ctx.Fields if len(_q.ctx.Fields) > 0 { _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique @@ -892,6 +895,13 @@ func (_q *GroupQuery) WithNamedUsers(name string, opts ...func(*UserQuery)) *Gro return _q } +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *GroupQuery) WithRetryOptions(opts ...any) *GroupQuery { + _q.retryConfig.Options = opts + return _q +} + // GroupGroupBy is the group-by builder for Group entities. type GroupGroupBy struct { selector diff --git a/entc/integration/ent/group_update.go b/entc/integration/ent/group_update.go index f3c19a8321..d7919dd516 100644 --- a/entc/integration/ent/group_update.go +++ b/entc/integration/ent/group_update.go @@ -25,9 +25,10 @@ import ( // GroupUpdate is the builder for updating Group entities. type GroupUpdate struct { config - hooks []Hook - mutation *GroupMutation - modifiers []func(*sql.UpdateBuilder) + hooks []Hook + mutation *GroupMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Where appends a list predicates to the GroupUpdate builder. @@ -311,6 +312,13 @@ func (_u *GroupUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *GroupUpd return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *GroupUpdate) WithRetryOptions(opts ...any) *GroupUpdate { + _u.retryConfig.Options = opts + return _u +} + func (_u *GroupUpdate) sqlSave(ctx context.Context) (_node int, err error) { if err := _u.check(); err != nil { return _node, err @@ -512,8 +520,9 @@ func (_u *GroupUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -527,10 +536,11 @@ func (_u *GroupUpdate) sqlSave(ctx context.Context) (_node int, err error) { // GroupUpdateOne is the builder for updating a single Group entity. type GroupUpdateOne struct { config - fields []string - hooks []Hook - mutation *GroupMutation - modifiers []func(*sql.UpdateBuilder) + fields []string + hooks []Hook + mutation *GroupMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // SetActive sets the "active" field. @@ -821,6 +831,13 @@ func (_u *GroupUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *Group return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *GroupUpdateOne) WithRetryOptions(opts ...any) *GroupUpdateOne { + _u.retryConfig.Options = opts + return _u +} + func (_u *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error) { if err := _u.check(); err != nil { return _node, err @@ -1039,11 +1056,12 @@ func (_u *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error) _spec.Edges.Add = append(_spec.Edges.Add, edge) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig _node = &Group{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/ent/groupinfo_create.go b/entc/integration/ent/groupinfo_create.go index ede6d1706a..10fb463642 100644 --- a/entc/integration/ent/groupinfo_create.go +++ b/entc/integration/ent/groupinfo_create.go @@ -21,9 +21,10 @@ import ( // GroupInfoCreate is the builder for creating a GroupInfo entity. type GroupInfoCreate struct { config - mutation *GroupInfoMutation - hooks []Hook - conflict []sql.ConflictOption + mutation *GroupInfoMutation + hooks []Hook + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // SetDesc sets the "desc" field. @@ -136,6 +137,7 @@ func (_c *GroupInfoCreate) createSpec() (*GroupInfo, *sqlgraph.CreateSpec) { _node = &GroupInfo{config: _c.config} _spec = sqlgraph.NewCreateSpec(groupinfo.Table, sqlgraph.NewFieldSpec(groupinfo.FieldID, field.TypeInt)) ) + _spec.RetryConfig = _c.retryConfig _spec.OnConflict = _c.conflict if value, ok := _c.mutation.Desc(); ok { _spec.SetField(groupinfo.FieldDesc, field.TypeString, value) @@ -164,6 +166,13 @@ func (_c *GroupInfoCreate) createSpec() (*GroupInfo, *sqlgraph.CreateSpec) { return _node, _spec } +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *GroupInfoCreate) WithRetryOptions(opts ...any) *GroupInfoCreate { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // @@ -354,9 +363,10 @@ func (u *GroupInfoUpsertOne) IDX(ctx context.Context) int { // GroupInfoCreateBulk is the builder for creating many GroupInfo entities in bulk. type GroupInfoCreateBulk struct { config - err error - builders []*GroupInfoCreate - conflict []sql.ConflictOption + err error + builders []*GroupInfoCreate + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Save creates the GroupInfo entities in the database. @@ -386,6 +396,7 @@ func (_c *GroupInfoCreateBulk) Save(ctx context.Context) ([]*GroupInfo, error) { _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig spec.OnConflict = _c.conflict // Invoke the actual operation on the latest mutation in the chain. if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { @@ -441,6 +452,13 @@ func (_c *GroupInfoCreateBulk) ExecX(ctx context.Context) { } } +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *GroupInfoCreateBulk) WithRetryOptions(opts ...any) *GroupInfoCreateBulk { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // diff --git a/entc/integration/ent/groupinfo_delete.go b/entc/integration/ent/groupinfo_delete.go index ee218c89ad..4beaaa1dc0 100644 --- a/entc/integration/ent/groupinfo_delete.go +++ b/entc/integration/ent/groupinfo_delete.go @@ -19,8 +19,9 @@ import ( // GroupInfoDelete is the builder for deleting a GroupInfo entity. type GroupInfoDelete struct { config - hooks []Hook - mutation *GroupInfoMutation + hooks []Hook + mutation *GroupInfoMutation + retryConfig sql.RetryConfig } // Where appends a list predicates to the GroupInfoDelete builder. @@ -45,6 +46,7 @@ func (_d *GroupInfoDelete) ExecX(ctx context.Context) int { func (_d *GroupInfoDelete) sqlExec(ctx context.Context) (int, error) { _spec := sqlgraph.NewDeleteSpec(groupinfo.Table, sqlgraph.NewFieldSpec(groupinfo.FieldID, field.TypeInt)) + _spec.RetryConfig = _d.retryConfig if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -60,6 +62,13 @@ func (_d *GroupInfoDelete) sqlExec(ctx context.Context) (int, error) { return affected, err } +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *GroupInfoDelete) WithRetryOptions(opts ...any) *GroupInfoDelete { + _d.retryConfig.Options = opts + return _d +} + // GroupInfoDeleteOne is the builder for deleting a single GroupInfo entity. type GroupInfoDeleteOne struct { _d *GroupInfoDelete diff --git a/entc/integration/ent/groupinfo_query.go b/entc/integration/ent/groupinfo_query.go index 67c4fc0ffa..534fdec199 100644 --- a/entc/integration/ent/groupinfo_query.go +++ b/entc/integration/ent/groupinfo_query.go @@ -32,6 +32,7 @@ type GroupInfoQuery struct { withGroups *GroupQuery modifiers []func(*sql.Selector) withNamedGroups map[string]*GroupQuery + retryConfig sql.RetryConfig // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -395,6 +396,7 @@ func (_q *GroupInfoQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Gr if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig for i := range hooks { hooks[i](ctx, _spec) } @@ -468,6 +470,7 @@ func (_q *GroupInfoQuery) sqlCount(ctx context.Context) (int, error) { if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig _spec.Node.Columns = _q.ctx.Fields if len(_q.ctx.Fields) > 0 { _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique @@ -596,6 +599,13 @@ func (_q *GroupInfoQuery) WithNamedGroups(name string, opts ...func(*GroupQuery) return _q } +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *GroupInfoQuery) WithRetryOptions(opts ...any) *GroupInfoQuery { + _q.retryConfig.Options = opts + return _q +} + // GroupInfoGroupBy is the group-by builder for GroupInfo entities. type GroupInfoGroupBy struct { selector diff --git a/entc/integration/ent/groupinfo_update.go b/entc/integration/ent/groupinfo_update.go index 261d0e00ee..84804c05c3 100644 --- a/entc/integration/ent/groupinfo_update.go +++ b/entc/integration/ent/groupinfo_update.go @@ -22,9 +22,10 @@ import ( // GroupInfoUpdate is the builder for updating GroupInfo entities. type GroupInfoUpdate struct { config - hooks []Hook - mutation *GroupInfoMutation - modifiers []func(*sql.UpdateBuilder) + hooks []Hook + mutation *GroupInfoMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Where appends a list predicates to the GroupInfoUpdate builder. @@ -142,6 +143,13 @@ func (_u *GroupInfoUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *Grou return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *GroupInfoUpdate) WithRetryOptions(opts ...any) *GroupInfoUpdate { + _u.retryConfig.Options = opts + return _u +} + func (_u *GroupInfoUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec := sqlgraph.NewUpdateSpec(groupinfo.Table, groupinfo.Columns, sqlgraph.NewFieldSpec(groupinfo.FieldID, field.TypeInt)) if ps := _u.mutation.predicates; len(ps) > 0 { @@ -206,8 +214,9 @@ func (_u *GroupInfoUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{groupinfo.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -221,10 +230,11 @@ func (_u *GroupInfoUpdate) sqlSave(ctx context.Context) (_node int, err error) { // GroupInfoUpdateOne is the builder for updating a single GroupInfo entity. type GroupInfoUpdateOne struct { config - fields []string - hooks []Hook - mutation *GroupInfoMutation - modifiers []func(*sql.UpdateBuilder) + fields []string + hooks []Hook + mutation *GroupInfoMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // SetDesc sets the "desc" field. @@ -349,6 +359,13 @@ func (_u *GroupInfoUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *G return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *GroupInfoUpdateOne) WithRetryOptions(opts ...any) *GroupInfoUpdateOne { + _u.retryConfig.Options = opts + return _u +} + func (_u *GroupInfoUpdateOne) sqlSave(ctx context.Context) (_node *GroupInfo, err error) { _spec := sqlgraph.NewUpdateSpec(groupinfo.Table, groupinfo.Columns, sqlgraph.NewFieldSpec(groupinfo.FieldID, field.TypeInt)) id, ok := _u.mutation.ID() @@ -430,11 +447,12 @@ func (_u *GroupInfoUpdateOne) sqlSave(ctx context.Context) (_node *GroupInfo, er _spec.Edges.Add = append(_spec.Edges.Add, edge) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig _node = &GroupInfo{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{groupinfo.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/ent/item_create.go b/entc/integration/ent/item_create.go index 07ab7e886f..25fcbbab0a 100644 --- a/entc/integration/ent/item_create.go +++ b/entc/integration/ent/item_create.go @@ -21,9 +21,10 @@ import ( // ItemCreate is the builder for creating a Item entity. type ItemCreate struct { config - mutation *ItemMutation - hooks []Hook - conflict []sql.ConflictOption + mutation *ItemMutation + hooks []Hook + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // SetText sets the "text" field. @@ -138,6 +139,7 @@ func (_c *ItemCreate) createSpec() (*Item, *sqlgraph.CreateSpec) { _node = &Item{config: _c.config} _spec = sqlgraph.NewCreateSpec(item.Table, sqlgraph.NewFieldSpec(item.FieldID, field.TypeString)) ) + _spec.RetryConfig = _c.retryConfig _spec.OnConflict = _c.conflict if id, ok := _c.mutation.ID(); ok { _node.ID = id @@ -150,6 +152,13 @@ func (_c *ItemCreate) createSpec() (*Item, *sqlgraph.CreateSpec) { return _node, _spec } +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *ItemCreate) WithRetryOptions(opts ...any) *ItemCreate { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // @@ -327,9 +336,10 @@ func (u *ItemUpsertOne) IDX(ctx context.Context) string { // ItemCreateBulk is the builder for creating many Item entities in bulk. type ItemCreateBulk struct { config - err error - builders []*ItemCreate - conflict []sql.ConflictOption + err error + builders []*ItemCreate + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Save creates the Item entities in the database. @@ -359,6 +369,7 @@ func (_c *ItemCreateBulk) Save(ctx context.Context) ([]*Item, error) { _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig spec.OnConflict = _c.conflict // Invoke the actual operation on the latest mutation in the chain. if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { @@ -410,6 +421,13 @@ func (_c *ItemCreateBulk) ExecX(ctx context.Context) { } } +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *ItemCreateBulk) WithRetryOptions(opts ...any) *ItemCreateBulk { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // diff --git a/entc/integration/ent/item_delete.go b/entc/integration/ent/item_delete.go index a0107e3de6..0589a45b60 100644 --- a/entc/integration/ent/item_delete.go +++ b/entc/integration/ent/item_delete.go @@ -19,8 +19,9 @@ import ( // ItemDelete is the builder for deleting a Item entity. type ItemDelete struct { config - hooks []Hook - mutation *ItemMutation + hooks []Hook + mutation *ItemMutation + retryConfig sql.RetryConfig } // Where appends a list predicates to the ItemDelete builder. @@ -45,6 +46,7 @@ func (_d *ItemDelete) ExecX(ctx context.Context) int { func (_d *ItemDelete) sqlExec(ctx context.Context) (int, error) { _spec := sqlgraph.NewDeleteSpec(item.Table, sqlgraph.NewFieldSpec(item.FieldID, field.TypeString)) + _spec.RetryConfig = _d.retryConfig if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -60,6 +62,13 @@ func (_d *ItemDelete) sqlExec(ctx context.Context) (int, error) { return affected, err } +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *ItemDelete) WithRetryOptions(opts ...any) *ItemDelete { + _d.retryConfig.Options = opts + return _d +} + // ItemDeleteOne is the builder for deleting a single Item entity. type ItemDeleteOne struct { _d *ItemDelete diff --git a/entc/integration/ent/item_query.go b/entc/integration/ent/item_query.go index 03672184f8..b0f0a503b9 100644 --- a/entc/integration/ent/item_query.go +++ b/entc/integration/ent/item_query.go @@ -23,11 +23,12 @@ import ( // ItemQuery is the builder for querying Item entities. type ItemQuery struct { config - ctx *QueryContext - order []item.OrderOption - inters []Interceptor - predicates []predicate.Item - modifiers []func(*sql.Selector) + ctx *QueryContext + order []item.OrderOption + inters []Interceptor + predicates []predicate.Item + modifiers []func(*sql.Selector) + retryConfig sql.RetryConfig // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -353,6 +354,7 @@ func (_q *ItemQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Item, e if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig for i := range hooks { hooks[i](ctx, _spec) } @@ -370,6 +372,7 @@ func (_q *ItemQuery) sqlCount(ctx context.Context) (int, error) { if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig _spec.Node.Columns = _q.ctx.Fields if len(_q.ctx.Fields) > 0 { _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique @@ -484,6 +487,13 @@ func (_q *ItemQuery) Modify(modifiers ...func(s *sql.Selector)) *ItemSelect { return _q.Select() } +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *ItemQuery) WithRetryOptions(opts ...any) *ItemQuery { + _q.retryConfig.Options = opts + return _q +} + // ItemGroupBy is the group-by builder for Item entities. type ItemGroupBy struct { selector diff --git a/entc/integration/ent/item_update.go b/entc/integration/ent/item_update.go index dd09136087..e38cbf0762 100644 --- a/entc/integration/ent/item_update.go +++ b/entc/integration/ent/item_update.go @@ -21,9 +21,10 @@ import ( // ItemUpdate is the builder for updating Item entities. type ItemUpdate struct { config - hooks []Hook - mutation *ItemMutation - modifiers []func(*sql.UpdateBuilder) + hooks []Hook + mutation *ItemMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Where appends a list predicates to the ItemUpdate builder. @@ -100,6 +101,13 @@ func (_u *ItemUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *ItemUpdat return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *ItemUpdate) WithRetryOptions(opts ...any) *ItemUpdate { + _u.retryConfig.Options = opts + return _u +} + func (_u *ItemUpdate) sqlSave(ctx context.Context) (_node int, err error) { if err := _u.check(); err != nil { return _node, err @@ -119,8 +127,9 @@ func (_u *ItemUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.ClearField(item.FieldText, field.TypeString) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{item.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -134,10 +143,11 @@ func (_u *ItemUpdate) sqlSave(ctx context.Context) (_node int, err error) { // ItemUpdateOne is the builder for updating a single Item entity. type ItemUpdateOne struct { config - fields []string - hooks []Hook - mutation *ItemMutation - modifiers []func(*sql.UpdateBuilder) + fields []string + hooks []Hook + mutation *ItemMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // SetText sets the "text" field. @@ -221,6 +231,13 @@ func (_u *ItemUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *ItemUp return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *ItemUpdateOne) WithRetryOptions(opts ...any) *ItemUpdateOne { + _u.retryConfig.Options = opts + return _u +} + func (_u *ItemUpdateOne) sqlSave(ctx context.Context) (_node *Item, err error) { if err := _u.check(); err != nil { return _node, err @@ -257,11 +274,12 @@ func (_u *ItemUpdateOne) sqlSave(ctx context.Context) (_node *Item, err error) { _spec.ClearField(item.FieldText, field.TypeString) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig _node = &Item{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{item.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/ent/license_create.go b/entc/integration/ent/license_create.go index be85871465..dcf6b262ff 100644 --- a/entc/integration/ent/license_create.go +++ b/entc/integration/ent/license_create.go @@ -21,9 +21,10 @@ import ( // LicenseCreate is the builder for creating a License entity. type LicenseCreate struct { config - mutation *LicenseMutation - hooks []Hook - conflict []sql.ConflictOption + mutation *LicenseMutation + hooks []Hook + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // SetCreateTime sets the "create_time" field. @@ -141,6 +142,7 @@ func (_c *LicenseCreate) createSpec() (*License, *sqlgraph.CreateSpec) { _node = &License{config: _c.config} _spec = sqlgraph.NewCreateSpec(license.Table, sqlgraph.NewFieldSpec(license.FieldID, field.TypeInt)) ) + _spec.RetryConfig = _c.retryConfig _spec.OnConflict = _c.conflict if id, ok := _c.mutation.ID(); ok { _node.ID = id @@ -157,6 +159,13 @@ func (_c *LicenseCreate) createSpec() (*License, *sqlgraph.CreateSpec) { return _node, _spec } +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *LicenseCreate) WithRetryOptions(opts ...any) *LicenseCreate { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // @@ -319,9 +328,10 @@ func (u *LicenseUpsertOne) IDX(ctx context.Context) int { // LicenseCreateBulk is the builder for creating many License entities in bulk. type LicenseCreateBulk struct { config - err error - builders []*LicenseCreate - conflict []sql.ConflictOption + err error + builders []*LicenseCreate + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Save creates the License entities in the database. @@ -351,6 +361,7 @@ func (_c *LicenseCreateBulk) Save(ctx context.Context) ([]*License, error) { _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig spec.OnConflict = _c.conflict // Invoke the actual operation on the latest mutation in the chain. if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { @@ -406,6 +417,13 @@ func (_c *LicenseCreateBulk) ExecX(ctx context.Context) { } } +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *LicenseCreateBulk) WithRetryOptions(opts ...any) *LicenseCreateBulk { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // diff --git a/entc/integration/ent/license_delete.go b/entc/integration/ent/license_delete.go index 9e35225d09..a5eb96cf39 100644 --- a/entc/integration/ent/license_delete.go +++ b/entc/integration/ent/license_delete.go @@ -19,8 +19,9 @@ import ( // LicenseDelete is the builder for deleting a License entity. type LicenseDelete struct { config - hooks []Hook - mutation *LicenseMutation + hooks []Hook + mutation *LicenseMutation + retryConfig sql.RetryConfig } // Where appends a list predicates to the LicenseDelete builder. @@ -45,6 +46,7 @@ func (_d *LicenseDelete) ExecX(ctx context.Context) int { func (_d *LicenseDelete) sqlExec(ctx context.Context) (int, error) { _spec := sqlgraph.NewDeleteSpec(license.Table, sqlgraph.NewFieldSpec(license.FieldID, field.TypeInt)) + _spec.RetryConfig = _d.retryConfig if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -60,6 +62,13 @@ func (_d *LicenseDelete) sqlExec(ctx context.Context) (int, error) { return affected, err } +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *LicenseDelete) WithRetryOptions(opts ...any) *LicenseDelete { + _d.retryConfig.Options = opts + return _d +} + // LicenseDeleteOne is the builder for deleting a single License entity. type LicenseDeleteOne struct { _d *LicenseDelete diff --git a/entc/integration/ent/license_query.go b/entc/integration/ent/license_query.go index 60c538a432..6c44d53753 100644 --- a/entc/integration/ent/license_query.go +++ b/entc/integration/ent/license_query.go @@ -23,11 +23,12 @@ import ( // LicenseQuery is the builder for querying License entities. type LicenseQuery struct { config - ctx *QueryContext - order []license.OrderOption - inters []Interceptor - predicates []predicate.License - modifiers []func(*sql.Selector) + ctx *QueryContext + order []license.OrderOption + inters []Interceptor + predicates []predicate.License + modifiers []func(*sql.Selector) + retryConfig sql.RetryConfig // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -353,6 +354,7 @@ func (_q *LicenseQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Lice if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig for i := range hooks { hooks[i](ctx, _spec) } @@ -370,6 +372,7 @@ func (_q *LicenseQuery) sqlCount(ctx context.Context) (int, error) { if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig _spec.Node.Columns = _q.ctx.Fields if len(_q.ctx.Fields) > 0 { _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique @@ -484,6 +487,13 @@ func (_q *LicenseQuery) Modify(modifiers ...func(s *sql.Selector)) *LicenseSelec return _q.Select() } +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *LicenseQuery) WithRetryOptions(opts ...any) *LicenseQuery { + _q.retryConfig.Options = opts + return _q +} + // LicenseGroupBy is the group-by builder for License entities. type LicenseGroupBy struct { selector diff --git a/entc/integration/ent/license_update.go b/entc/integration/ent/license_update.go index a945974280..7000b4b0b9 100644 --- a/entc/integration/ent/license_update.go +++ b/entc/integration/ent/license_update.go @@ -22,9 +22,10 @@ import ( // LicenseUpdate is the builder for updating License entities. type LicenseUpdate struct { config - hooks []Hook - mutation *LicenseMutation - modifiers []func(*sql.UpdateBuilder) + hooks []Hook + mutation *LicenseMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Where appends a list predicates to the LicenseUpdate builder. @@ -86,6 +87,13 @@ func (_u *LicenseUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *Licens return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *LicenseUpdate) WithRetryOptions(opts ...any) *LicenseUpdate { + _u.retryConfig.Options = opts + return _u +} + func (_u *LicenseUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec := sqlgraph.NewUpdateSpec(license.Table, license.Columns, sqlgraph.NewFieldSpec(license.FieldID, field.TypeInt)) if ps := _u.mutation.predicates; len(ps) > 0 { @@ -99,8 +107,9 @@ func (_u *LicenseUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(license.FieldUpdateTime, field.TypeTime, value) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{license.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -114,10 +123,11 @@ func (_u *LicenseUpdate) sqlSave(ctx context.Context) (_node int, err error) { // LicenseUpdateOne is the builder for updating a single License entity. type LicenseUpdateOne struct { config - fields []string - hooks []Hook - mutation *LicenseMutation - modifiers []func(*sql.UpdateBuilder) + fields []string + hooks []Hook + mutation *LicenseMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // SetUpdateTime sets the "update_time" field. @@ -186,6 +196,13 @@ func (_u *LicenseUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *Lic return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *LicenseUpdateOne) WithRetryOptions(opts ...any) *LicenseUpdateOne { + _u.retryConfig.Options = opts + return _u +} + func (_u *LicenseUpdateOne) sqlSave(ctx context.Context) (_node *License, err error) { _spec := sqlgraph.NewUpdateSpec(license.Table, license.Columns, sqlgraph.NewFieldSpec(license.FieldID, field.TypeInt)) id, ok := _u.mutation.ID() @@ -216,11 +233,12 @@ func (_u *LicenseUpdateOne) sqlSave(ctx context.Context) (_node *License, err er _spec.SetField(license.FieldUpdateTime, field.TypeTime, value) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig _node = &License{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{license.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/ent/migrate/schema.go b/entc/integration/ent/migrate/schema.go index 3704811a3a..e0051670d9 100644 --- a/entc/integration/ent/migrate/schema.go +++ b/entc/integration/ent/migrate/schema.go @@ -138,10 +138,10 @@ var ( {Name: "text", Type: field.TypeString, Nullable: true, Size: 2147483647, SchemaType: map[string]string{"mysql": "mediumtext"}}, {Name: "datetime", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"mysql": "datetime", "postgres": "date"}}, {Name: "decimal", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"mysql": "decimal(6,2)", "postgres": "numeric"}}, - {Name: "link_other", Type: field.TypeOther, Nullable: true, SchemaType: map[string]string{"mysql": "varchar(255)", "postgres": "varchar", "sqlite3": "varchar(255)"}}, - {Name: "link_other_func", Type: field.TypeOther, Nullable: true, SchemaType: map[string]string{"mysql": "varchar(255)", "postgres": "varchar", "sqlite3": "varchar(255)"}}, + {Name: "link_other", Type: field.TypeOther, Nullable: true, SchemaType: map[string]string{"mysql": "varchar(255)", "postgres": "varchar", "sqlite3": "varchar(255)", "ydb": "Utf8"}}, + {Name: "link_other_func", Type: field.TypeOther, Nullable: true, SchemaType: map[string]string{"mysql": "varchar(255)", "postgres": "varchar", "sqlite3": "varchar(255)", "ydb": "Utf8"}}, {Name: "mac", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "macaddr"}}, - {Name: "string_array", Type: field.TypeOther, Nullable: true, SchemaType: map[string]string{"mysql": "blob", "postgres": "text[]", "sqlite3": "json"}}, + {Name: "string_array", Type: field.TypeOther, Nullable: true, SchemaType: map[string]string{"mysql": "blob", "postgres": "text[]", "sqlite3": "json", "ydb": "Utf8"}}, {Name: "password", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"mysql": "char(32)"}}, {Name: "string_scanner", Type: field.TypeString, Nullable: true}, {Name: "duration", Type: field.TypeInt64, Nullable: true}, @@ -174,8 +174,8 @@ var ( {Name: "nil_pair", Type: field.TypeBytes, Nullable: true}, {Name: "vstring", Type: field.TypeString}, {Name: "triple", Type: field.TypeString}, - {Name: "big_int", Type: field.TypeInt, Nullable: true}, - {Name: "password_other", Type: field.TypeOther, Nullable: true, SchemaType: map[string]string{"mysql": "char(32)", "postgres": "varchar", "sqlite3": "char(32)"}}, + {Name: "big_int", Type: field.TypeInt, Nullable: true, SchemaType: map[string]string{"ydb": "Utf8"}}, + {Name: "password_other", Type: field.TypeOther, Nullable: true, SchemaType: map[string]string{"mysql": "char(32)", "postgres": "varchar", "sqlite3": "char(32)", "ydb": "Utf8"}}, {Name: "file_field", Type: field.TypeInt, Nullable: true}, } // FieldTypesTable holds the schema information for the "field_types" table. diff --git a/entc/integration/ent/node_create.go b/entc/integration/ent/node_create.go index e1e912644f..413d951bd7 100644 --- a/entc/integration/ent/node_create.go +++ b/entc/integration/ent/node_create.go @@ -21,9 +21,10 @@ import ( // NodeCreate is the builder for creating a Node entity. type NodeCreate struct { config - mutation *NodeMutation - hooks []Hook - conflict []sql.ConflictOption + mutation *NodeMutation + hooks []Hook + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // SetValue sets the "value" field. @@ -152,6 +153,7 @@ func (_c *NodeCreate) createSpec() (*Node, *sqlgraph.CreateSpec) { _node = &Node{config: _c.config} _spec = sqlgraph.NewCreateSpec(node.Table, sqlgraph.NewFieldSpec(node.FieldID, field.TypeInt)) ) + _spec.RetryConfig = _c.retryConfig _spec.OnConflict = _c.conflict if value, ok := _c.mutation.Value(); ok { _spec.SetField(node.FieldValue, field.TypeInt, value) @@ -197,6 +199,13 @@ func (_c *NodeCreate) createSpec() (*Node, *sqlgraph.CreateSpec) { return _node, _spec } +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *NodeCreate) WithRetryOptions(opts ...any) *NodeCreate { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // @@ -413,9 +422,10 @@ func (u *NodeUpsertOne) IDX(ctx context.Context) int { // NodeCreateBulk is the builder for creating many Node entities in bulk. type NodeCreateBulk struct { config - err error - builders []*NodeCreate - conflict []sql.ConflictOption + err error + builders []*NodeCreate + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Save creates the Node entities in the database. @@ -444,6 +454,7 @@ func (_c *NodeCreateBulk) Save(ctx context.Context) ([]*Node, error) { _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig spec.OnConflict = _c.conflict // Invoke the actual operation on the latest mutation in the chain. if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { @@ -499,6 +510,13 @@ func (_c *NodeCreateBulk) ExecX(ctx context.Context) { } } +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *NodeCreateBulk) WithRetryOptions(opts ...any) *NodeCreateBulk { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // diff --git a/entc/integration/ent/node_delete.go b/entc/integration/ent/node_delete.go index e456e5620a..d92900c1a3 100644 --- a/entc/integration/ent/node_delete.go +++ b/entc/integration/ent/node_delete.go @@ -19,8 +19,9 @@ import ( // NodeDelete is the builder for deleting a Node entity. type NodeDelete struct { config - hooks []Hook - mutation *NodeMutation + hooks []Hook + mutation *NodeMutation + retryConfig sql.RetryConfig } // Where appends a list predicates to the NodeDelete builder. @@ -45,6 +46,7 @@ func (_d *NodeDelete) ExecX(ctx context.Context) int { func (_d *NodeDelete) sqlExec(ctx context.Context) (int, error) { _spec := sqlgraph.NewDeleteSpec(node.Table, sqlgraph.NewFieldSpec(node.FieldID, field.TypeInt)) + _spec.RetryConfig = _d.retryConfig if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -60,6 +62,13 @@ func (_d *NodeDelete) sqlExec(ctx context.Context) (int, error) { return affected, err } +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *NodeDelete) WithRetryOptions(opts ...any) *NodeDelete { + _d.retryConfig.Options = opts + return _d +} + // NodeDeleteOne is the builder for deleting a single Node entity. type NodeDeleteOne struct { _d *NodeDelete diff --git a/entc/integration/ent/node_query.go b/entc/integration/ent/node_query.go index 19b6f8922d..e8ef5e909a 100644 --- a/entc/integration/ent/node_query.go +++ b/entc/integration/ent/node_query.go @@ -24,14 +24,15 @@ import ( // NodeQuery is the builder for querying Node entities. type NodeQuery struct { config - ctx *QueryContext - order []node.OrderOption - inters []Interceptor - predicates []predicate.Node - withPrev *NodeQuery - withNext *NodeQuery - withFKs bool - modifiers []func(*sql.Selector) + ctx *QueryContext + order []node.OrderOption + inters []Interceptor + predicates []predicate.Node + withPrev *NodeQuery + withNext *NodeQuery + withFKs bool + modifiers []func(*sql.Selector) + retryConfig sql.RetryConfig // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -437,6 +438,7 @@ func (_q *NodeQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Node, e if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig for i := range hooks { hooks[i](ctx, _spec) } @@ -537,6 +539,7 @@ func (_q *NodeQuery) sqlCount(ctx context.Context) (int, error) { if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig _spec.Node.Columns = _q.ctx.Fields if len(_q.ctx.Fields) > 0 { _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique @@ -651,6 +654,13 @@ func (_q *NodeQuery) Modify(modifiers ...func(s *sql.Selector)) *NodeSelect { return _q.Select() } +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *NodeQuery) WithRetryOptions(opts ...any) *NodeQuery { + _q.retryConfig.Options = opts + return _q +} + // NodeGroupBy is the group-by builder for Node entities. type NodeGroupBy struct { selector diff --git a/entc/integration/ent/node_update.go b/entc/integration/ent/node_update.go index 6611f936ea..9abd19022d 100644 --- a/entc/integration/ent/node_update.go +++ b/entc/integration/ent/node_update.go @@ -22,9 +22,10 @@ import ( // NodeUpdate is the builder for updating Node entities. type NodeUpdate struct { config - hooks []Hook - mutation *NodeMutation - modifiers []func(*sql.UpdateBuilder) + hooks []Hook + mutation *NodeMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Where appends a list predicates to the NodeUpdate builder. @@ -169,6 +170,13 @@ func (_u *NodeUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *NodeUpdat return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *NodeUpdate) WithRetryOptions(opts ...any) *NodeUpdate { + _u.retryConfig.Options = opts + return _u +} + func (_u *NodeUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec := sqlgraph.NewUpdateSpec(node.Table, node.Columns, sqlgraph.NewFieldSpec(node.FieldID, field.TypeInt)) if ps := _u.mutation.predicates; len(ps) > 0 { @@ -252,8 +260,9 @@ func (_u *NodeUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{node.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -267,10 +276,11 @@ func (_u *NodeUpdate) sqlSave(ctx context.Context) (_node int, err error) { // NodeUpdateOne is the builder for updating a single Node entity. type NodeUpdateOne struct { config - fields []string - hooks []Hook - mutation *NodeMutation - modifiers []func(*sql.UpdateBuilder) + fields []string + hooks []Hook + mutation *NodeMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // SetValue sets the "value" field. @@ -422,6 +432,13 @@ func (_u *NodeUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *NodeUp return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *NodeUpdateOne) WithRetryOptions(opts ...any) *NodeUpdateOne { + _u.retryConfig.Options = opts + return _u +} + func (_u *NodeUpdateOne) sqlSave(ctx context.Context) (_node *Node, err error) { _spec := sqlgraph.NewUpdateSpec(node.Table, node.Columns, sqlgraph.NewFieldSpec(node.FieldID, field.TypeInt)) id, ok := _u.mutation.ID() @@ -522,11 +539,12 @@ func (_u *NodeUpdateOne) sqlSave(ctx context.Context) (_node *Node, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig _node = &Node{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{node.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/ent/pc_create.go b/entc/integration/ent/pc_create.go index dcf1a5cdbd..d79c7b453a 100644 --- a/entc/integration/ent/pc_create.go +++ b/entc/integration/ent/pc_create.go @@ -20,9 +20,10 @@ import ( // PCCreate is the builder for creating a PC entity. type PCCreate struct { config - mutation *PCMutation - hooks []Hook - conflict []sql.ConflictOption + mutation *PCMutation + hooks []Hook + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Mutation returns the PCMutation object of the builder. @@ -85,10 +86,18 @@ func (_c *PCCreate) createSpec() (*PC, *sqlgraph.CreateSpec) { _node = &PC{config: _c.config} _spec = sqlgraph.NewCreateSpec(pc.Table, sqlgraph.NewFieldSpec(pc.FieldID, field.TypeInt)) ) + _spec.RetryConfig = _c.retryConfig _spec.OnConflict = _c.conflict return _node, _spec } +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *PCCreate) WithRetryOptions(opts ...any) *PCCreate { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // @@ -208,9 +217,10 @@ func (u *PCUpsertOne) IDX(ctx context.Context) int { // PCCreateBulk is the builder for creating many PC entities in bulk. type PCCreateBulk struct { config - err error - builders []*PCCreate - conflict []sql.ConflictOption + err error + builders []*PCCreate + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Save creates the PC entities in the database. @@ -239,6 +249,7 @@ func (_c *PCCreateBulk) Save(ctx context.Context) ([]*PC, error) { _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig spec.OnConflict = _c.conflict // Invoke the actual operation on the latest mutation in the chain. if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { @@ -294,6 +305,13 @@ func (_c *PCCreateBulk) ExecX(ctx context.Context) { } } +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *PCCreateBulk) WithRetryOptions(opts ...any) *PCCreateBulk { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // diff --git a/entc/integration/ent/pc_delete.go b/entc/integration/ent/pc_delete.go index 48f2e3932a..a96dee3753 100644 --- a/entc/integration/ent/pc_delete.go +++ b/entc/integration/ent/pc_delete.go @@ -19,8 +19,9 @@ import ( // PCDelete is the builder for deleting a PC entity. type PCDelete struct { config - hooks []Hook - mutation *PCMutation + hooks []Hook + mutation *PCMutation + retryConfig sql.RetryConfig } // Where appends a list predicates to the PCDelete builder. @@ -45,6 +46,7 @@ func (_d *PCDelete) ExecX(ctx context.Context) int { func (_d *PCDelete) sqlExec(ctx context.Context) (int, error) { _spec := sqlgraph.NewDeleteSpec(pc.Table, sqlgraph.NewFieldSpec(pc.FieldID, field.TypeInt)) + _spec.RetryConfig = _d.retryConfig if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -60,6 +62,13 @@ func (_d *PCDelete) sqlExec(ctx context.Context) (int, error) { return affected, err } +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *PCDelete) WithRetryOptions(opts ...any) *PCDelete { + _d.retryConfig.Options = opts + return _d +} + // PCDeleteOne is the builder for deleting a single PC entity. type PCDeleteOne struct { _d *PCDelete diff --git a/entc/integration/ent/pc_query.go b/entc/integration/ent/pc_query.go index 0e1d7e0d82..c5a0449843 100644 --- a/entc/integration/ent/pc_query.go +++ b/entc/integration/ent/pc_query.go @@ -23,11 +23,12 @@ import ( // PCQuery is the builder for querying PC entities. type PCQuery struct { config - ctx *QueryContext - order []pc.OrderOption - inters []Interceptor - predicates []predicate.PC - modifiers []func(*sql.Selector) + ctx *QueryContext + order []pc.OrderOption + inters []Interceptor + predicates []predicate.PC + modifiers []func(*sql.Selector) + retryConfig sql.RetryConfig // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -331,6 +332,7 @@ func (_q *PCQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*PC, error if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig for i := range hooks { hooks[i](ctx, _spec) } @@ -348,6 +350,7 @@ func (_q *PCQuery) sqlCount(ctx context.Context) (int, error) { if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig _spec.Node.Columns = _q.ctx.Fields if len(_q.ctx.Fields) > 0 { _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique @@ -462,6 +465,13 @@ func (_q *PCQuery) Modify(modifiers ...func(s *sql.Selector)) *PCSelect { return _q.Select() } +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *PCQuery) WithRetryOptions(opts ...any) *PCQuery { + _q.retryConfig.Options = opts + return _q +} + // PCGroupBy is the group-by builder for PC entities. type PCGroupBy struct { selector diff --git a/entc/integration/ent/pc_update.go b/entc/integration/ent/pc_update.go index cfcfe797a4..4a28a9b895 100644 --- a/entc/integration/ent/pc_update.go +++ b/entc/integration/ent/pc_update.go @@ -21,9 +21,10 @@ import ( // PCUpdate is the builder for updating PC entities. type PCUpdate struct { config - hooks []Hook - mutation *PCMutation - modifiers []func(*sql.UpdateBuilder) + hooks []Hook + mutation *PCMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Where appends a list predicates to the PCUpdate builder. @@ -70,6 +71,13 @@ func (_u *PCUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *PCUpdate { return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *PCUpdate) WithRetryOptions(opts ...any) *PCUpdate { + _u.retryConfig.Options = opts + return _u +} + func (_u *PCUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec := sqlgraph.NewUpdateSpec(pc.Table, pc.Columns, sqlgraph.NewFieldSpec(pc.FieldID, field.TypeInt)) if ps := _u.mutation.predicates; len(ps) > 0 { @@ -80,8 +88,9 @@ func (_u *PCUpdate) sqlSave(ctx context.Context) (_node int, err error) { } } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pc.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -95,10 +104,11 @@ func (_u *PCUpdate) sqlSave(ctx context.Context) (_node int, err error) { // PCUpdateOne is the builder for updating a single PC entity. type PCUpdateOne struct { config - fields []string - hooks []Hook - mutation *PCMutation - modifiers []func(*sql.UpdateBuilder) + fields []string + hooks []Hook + mutation *PCMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Mutation returns the PCMutation object of the builder. @@ -152,6 +162,13 @@ func (_u *PCUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *PCUpdate return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *PCUpdateOne) WithRetryOptions(opts ...any) *PCUpdateOne { + _u.retryConfig.Options = opts + return _u +} + func (_u *PCUpdateOne) sqlSave(ctx context.Context) (_node *PC, err error) { _spec := sqlgraph.NewUpdateSpec(pc.Table, pc.Columns, sqlgraph.NewFieldSpec(pc.FieldID, field.TypeInt)) id, ok := _u.mutation.ID() @@ -179,11 +196,12 @@ func (_u *PCUpdateOne) sqlSave(ctx context.Context) (_node *PC, err error) { } } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig _node = &PC{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pc.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/ent/pet_create.go b/entc/integration/ent/pet_create.go index d2164af6eb..802090e351 100644 --- a/entc/integration/ent/pet_create.go +++ b/entc/integration/ent/pet_create.go @@ -23,9 +23,10 @@ import ( // PetCreate is the builder for creating a Pet entity. type PetCreate struct { config - mutation *PetMutation - hooks []Hook - conflict []sql.ConflictOption + mutation *PetMutation + hooks []Hook + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // SetAge sets the "age" field. @@ -224,6 +225,7 @@ func (_c *PetCreate) createSpec() (*Pet, *sqlgraph.CreateSpec) { _node = &Pet{config: _c.config} _spec = sqlgraph.NewCreateSpec(pet.Table, sqlgraph.NewFieldSpec(pet.FieldID, field.TypeInt)) ) + _spec.RetryConfig = _c.retryConfig _spec.OnConflict = _c.conflict if value, ok := _c.mutation.Age(); ok { _spec.SetField(pet.FieldAge, field.TypeFloat64, value) @@ -286,6 +288,13 @@ func (_c *PetCreate) createSpec() (*Pet, *sqlgraph.CreateSpec) { return _node, _spec } +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *PetCreate) WithRetryOptions(opts ...any) *PetCreate { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // @@ -619,9 +628,10 @@ func (u *PetUpsertOne) IDX(ctx context.Context) int { // PetCreateBulk is the builder for creating many Pet entities in bulk. type PetCreateBulk struct { config - err error - builders []*PetCreate - conflict []sql.ConflictOption + err error + builders []*PetCreate + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Save creates the Pet entities in the database. @@ -651,6 +661,7 @@ func (_c *PetCreateBulk) Save(ctx context.Context) ([]*Pet, error) { _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig spec.OnConflict = _c.conflict // Invoke the actual operation on the latest mutation in the chain. if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { @@ -706,6 +717,13 @@ func (_c *PetCreateBulk) ExecX(ctx context.Context) { } } +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *PetCreateBulk) WithRetryOptions(opts ...any) *PetCreateBulk { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // diff --git a/entc/integration/ent/pet_delete.go b/entc/integration/ent/pet_delete.go index 431bea2dff..5980b6b33f 100644 --- a/entc/integration/ent/pet_delete.go +++ b/entc/integration/ent/pet_delete.go @@ -19,8 +19,9 @@ import ( // PetDelete is the builder for deleting a Pet entity. type PetDelete struct { config - hooks []Hook - mutation *PetMutation + hooks []Hook + mutation *PetMutation + retryConfig sql.RetryConfig } // Where appends a list predicates to the PetDelete builder. @@ -45,6 +46,7 @@ func (_d *PetDelete) ExecX(ctx context.Context) int { func (_d *PetDelete) sqlExec(ctx context.Context) (int, error) { _spec := sqlgraph.NewDeleteSpec(pet.Table, sqlgraph.NewFieldSpec(pet.FieldID, field.TypeInt)) + _spec.RetryConfig = _d.retryConfig if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -60,6 +62,13 @@ func (_d *PetDelete) sqlExec(ctx context.Context) (int, error) { return affected, err } +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *PetDelete) WithRetryOptions(opts ...any) *PetDelete { + _d.retryConfig.Options = opts + return _d +} + // PetDeleteOne is the builder for deleting a single Pet entity. type PetDeleteOne struct { _d *PetDelete diff --git a/entc/integration/ent/pet_query.go b/entc/integration/ent/pet_query.go index 05f3de79a1..079c842357 100644 --- a/entc/integration/ent/pet_query.go +++ b/entc/integration/ent/pet_query.go @@ -24,14 +24,15 @@ import ( // PetQuery is the builder for querying Pet entities. type PetQuery struct { config - ctx *QueryContext - order []pet.OrderOption - inters []Interceptor - predicates []predicate.Pet - withTeam *UserQuery - withOwner *UserQuery - withFKs bool - modifiers []func(*sql.Selector) + ctx *QueryContext + order []pet.OrderOption + inters []Interceptor + predicates []predicate.Pet + withTeam *UserQuery + withOwner *UserQuery + withFKs bool + modifiers []func(*sql.Selector) + retryConfig sql.RetryConfig // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -437,6 +438,7 @@ func (_q *PetQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Pet, err if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig for i := range hooks { hooks[i](ctx, _spec) } @@ -536,6 +538,7 @@ func (_q *PetQuery) sqlCount(ctx context.Context) (int, error) { if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig _spec.Node.Columns = _q.ctx.Fields if len(_q.ctx.Fields) > 0 { _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique @@ -650,6 +653,13 @@ func (_q *PetQuery) Modify(modifiers ...func(s *sql.Selector)) *PetSelect { return _q.Select() } +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *PetQuery) WithRetryOptions(opts ...any) *PetQuery { + _q.retryConfig.Options = opts + return _q +} + // PetGroupBy is the group-by builder for Pet entities. type PetGroupBy struct { selector diff --git a/entc/integration/ent/pet_update.go b/entc/integration/ent/pet_update.go index 121a891571..2e25572f65 100644 --- a/entc/integration/ent/pet_update.go +++ b/entc/integration/ent/pet_update.go @@ -24,9 +24,10 @@ import ( // PetUpdate is the builder for updating Pet entities. type PetUpdate struct { config - hooks []Hook - mutation *PetMutation - modifiers []func(*sql.UpdateBuilder) + hooks []Hook + mutation *PetMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Where appends a list predicates to the PetUpdate builder. @@ -232,6 +233,13 @@ func (_u *PetUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *PetUpdate return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *PetUpdate) WithRetryOptions(opts ...any) *PetUpdate { + _u.retryConfig.Options = opts + return _u +} + func (_u *PetUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec := sqlgraph.NewUpdateSpec(pet.Table, pet.Columns, sqlgraph.NewFieldSpec(pet.FieldID, field.TypeInt)) if ps := _u.mutation.predicates; len(ps) > 0 { @@ -330,8 +338,9 @@ func (_u *PetUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -345,10 +354,11 @@ func (_u *PetUpdate) sqlSave(ctx context.Context) (_node int, err error) { // PetUpdateOne is the builder for updating a single Pet entity. type PetUpdateOne struct { config - fields []string - hooks []Hook - mutation *PetMutation - modifiers []func(*sql.UpdateBuilder) + fields []string + hooks []Hook + mutation *PetMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // SetAge sets the "age" field. @@ -561,6 +571,13 @@ func (_u *PetUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *PetUpda return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *PetUpdateOne) WithRetryOptions(opts ...any) *PetUpdateOne { + _u.retryConfig.Options = opts + return _u +} + func (_u *PetUpdateOne) sqlSave(ctx context.Context) (_node *Pet, err error) { _spec := sqlgraph.NewUpdateSpec(pet.Table, pet.Columns, sqlgraph.NewFieldSpec(pet.FieldID, field.TypeInt)) id, ok := _u.mutation.ID() @@ -676,11 +693,12 @@ func (_u *PetUpdateOne) sqlSave(ctx context.Context) (_node *Pet, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig _node = &Pet{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/ent/schema/fieldtype.go b/entc/integration/ent/schema/fieldtype.go index 7ca26242d6..44fd5d3189 100644 --- a/entc/integration/ent/schema/fieldtype.go +++ b/entc/integration/ent/schema/fieldtype.go @@ -116,6 +116,7 @@ func (FieldType) Fields() []ent.Field { //nolint:funlen dialect.Postgres: "varchar", dialect.MySQL: "varchar(255)", dialect.SQLite: "varchar(255)", + dialect.YDB: "Utf8", }). Optional(). Default(DefaultLink()), @@ -124,6 +125,7 @@ func (FieldType) Fields() []ent.Field { //nolint:funlen dialect.Postgres: "varchar", dialect.MySQL: "varchar(255)", dialect.SQLite: "varchar(255)", + dialect.YDB: "Utf8", }). Optional(). Default(DefaultLink), @@ -143,6 +145,7 @@ func (FieldType) Fields() []ent.Field { //nolint:funlen dialect.Postgres: "text[]", dialect.SQLite: "json", dialect.MySQL: "blob", + dialect.YDB: "Utf8", }), field.String("password"). Optional(). @@ -289,7 +292,10 @@ func (FieldType) Fields() []ent.Field { //nolint:funlen }), field.Int("big_int"). Optional(). - GoType(BigInt{}), + GoType(BigInt{}). + SchemaType(map[string]string{ + dialect.YDB: "Utf8", + }), field.Other("password_other", Password("")). Optional(). Sensitive(). @@ -297,6 +303,7 @@ func (FieldType) Fields() []ent.Field { //nolint:funlen dialect.MySQL: "char(32)", dialect.SQLite: "char(32)", dialect.Postgres: "varchar", + dialect.YDB: "Utf8", }), } } diff --git a/entc/integration/ent/spec_create.go b/entc/integration/ent/spec_create.go index 0d561c1d0b..912f417eab 100644 --- a/entc/integration/ent/spec_create.go +++ b/entc/integration/ent/spec_create.go @@ -21,9 +21,10 @@ import ( // SpecCreate is the builder for creating a Spec entity. type SpecCreate struct { config - mutation *SpecMutation - hooks []Hook - conflict []sql.ConflictOption + mutation *SpecMutation + hooks []Hook + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // AddCardIDs adds the "card" edge to the Card entity by IDs. @@ -101,6 +102,7 @@ func (_c *SpecCreate) createSpec() (*Spec, *sqlgraph.CreateSpec) { _node = &Spec{config: _c.config} _spec = sqlgraph.NewCreateSpec(spec.Table, sqlgraph.NewFieldSpec(spec.FieldID, field.TypeInt)) ) + _spec.RetryConfig = _c.retryConfig _spec.OnConflict = _c.conflict if nodes := _c.mutation.CardIDs(); len(nodes) > 0 { edge := &sqlgraph.EdgeSpec{ @@ -121,6 +123,13 @@ func (_c *SpecCreate) createSpec() (*Spec, *sqlgraph.CreateSpec) { return _node, _spec } +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *SpecCreate) WithRetryOptions(opts ...any) *SpecCreate { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // @@ -240,9 +249,10 @@ func (u *SpecUpsertOne) IDX(ctx context.Context) int { // SpecCreateBulk is the builder for creating many Spec entities in bulk. type SpecCreateBulk struct { config - err error - builders []*SpecCreate - conflict []sql.ConflictOption + err error + builders []*SpecCreate + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Save creates the Spec entities in the database. @@ -271,6 +281,7 @@ func (_c *SpecCreateBulk) Save(ctx context.Context) ([]*Spec, error) { _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig spec.OnConflict = _c.conflict // Invoke the actual operation on the latest mutation in the chain. if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { @@ -326,6 +337,13 @@ func (_c *SpecCreateBulk) ExecX(ctx context.Context) { } } +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *SpecCreateBulk) WithRetryOptions(opts ...any) *SpecCreateBulk { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // diff --git a/entc/integration/ent/spec_delete.go b/entc/integration/ent/spec_delete.go index 038590621b..9d82b2738a 100644 --- a/entc/integration/ent/spec_delete.go +++ b/entc/integration/ent/spec_delete.go @@ -19,8 +19,9 @@ import ( // SpecDelete is the builder for deleting a Spec entity. type SpecDelete struct { config - hooks []Hook - mutation *SpecMutation + hooks []Hook + mutation *SpecMutation + retryConfig sql.RetryConfig } // Where appends a list predicates to the SpecDelete builder. @@ -45,6 +46,7 @@ func (_d *SpecDelete) ExecX(ctx context.Context) int { func (_d *SpecDelete) sqlExec(ctx context.Context) (int, error) { _spec := sqlgraph.NewDeleteSpec(spec.Table, sqlgraph.NewFieldSpec(spec.FieldID, field.TypeInt)) + _spec.RetryConfig = _d.retryConfig if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -60,6 +62,13 @@ func (_d *SpecDelete) sqlExec(ctx context.Context) (int, error) { return affected, err } +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *SpecDelete) WithRetryOptions(opts ...any) *SpecDelete { + _d.retryConfig.Options = opts + return _d +} + // SpecDeleteOne is the builder for deleting a single Spec entity. type SpecDeleteOne struct { _d *SpecDelete diff --git a/entc/integration/ent/spec_query.go b/entc/integration/ent/spec_query.go index 6940136f97..e9a30d2e32 100644 --- a/entc/integration/ent/spec_query.go +++ b/entc/integration/ent/spec_query.go @@ -32,6 +32,7 @@ type SpecQuery struct { withCard *CardQuery modifiers []func(*sql.Selector) withNamedCard map[string]*CardQuery + retryConfig sql.RetryConfig // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -373,6 +374,7 @@ func (_q *SpecQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Spec, e if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig for i := range hooks { hooks[i](ctx, _spec) } @@ -466,6 +468,7 @@ func (_q *SpecQuery) sqlCount(ctx context.Context) (int, error) { if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig _spec.Node.Columns = _q.ctx.Fields if len(_q.ctx.Fields) > 0 { _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique @@ -594,6 +597,13 @@ func (_q *SpecQuery) WithNamedCard(name string, opts ...func(*CardQuery)) *SpecQ return _q } +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *SpecQuery) WithRetryOptions(opts ...any) *SpecQuery { + _q.retryConfig.Options = opts + return _q +} + // SpecGroupBy is the group-by builder for Spec entities. type SpecGroupBy struct { selector diff --git a/entc/integration/ent/spec_update.go b/entc/integration/ent/spec_update.go index c9df3fbecc..4273961e5e 100644 --- a/entc/integration/ent/spec_update.go +++ b/entc/integration/ent/spec_update.go @@ -22,9 +22,10 @@ import ( // SpecUpdate is the builder for updating Spec entities. type SpecUpdate struct { config - hooks []Hook - mutation *SpecMutation - modifiers []func(*sql.UpdateBuilder) + hooks []Hook + mutation *SpecMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Where appends a list predicates to the SpecUpdate builder. @@ -107,6 +108,13 @@ func (_u *SpecUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *SpecUpdat return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *SpecUpdate) WithRetryOptions(opts ...any) *SpecUpdate { + _u.retryConfig.Options = opts + return _u +} + func (_u *SpecUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec := sqlgraph.NewUpdateSpec(spec.Table, spec.Columns, sqlgraph.NewFieldSpec(spec.FieldID, field.TypeInt)) if ps := _u.mutation.predicates; len(ps) > 0 { @@ -162,8 +170,9 @@ func (_u *SpecUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{spec.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -177,10 +186,11 @@ func (_u *SpecUpdate) sqlSave(ctx context.Context) (_node int, err error) { // SpecUpdateOne is the builder for updating a single Spec entity. type SpecUpdateOne struct { config - fields []string - hooks []Hook - mutation *SpecMutation - modifiers []func(*sql.UpdateBuilder) + fields []string + hooks []Hook + mutation *SpecMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // AddCardIDs adds the "card" edge to the Card entity by IDs. @@ -270,6 +280,13 @@ func (_u *SpecUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *SpecUp return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *SpecUpdateOne) WithRetryOptions(opts ...any) *SpecUpdateOne { + _u.retryConfig.Options = opts + return _u +} + func (_u *SpecUpdateOne) sqlSave(ctx context.Context) (_node *Spec, err error) { _spec := sqlgraph.NewUpdateSpec(spec.Table, spec.Columns, sqlgraph.NewFieldSpec(spec.FieldID, field.TypeInt)) id, ok := _u.mutation.ID() @@ -342,11 +359,12 @@ func (_u *SpecUpdateOne) sqlSave(ctx context.Context) (_node *Spec, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig _node = &Spec{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{spec.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/ent/task_create.go b/entc/integration/ent/task_create.go index e99ff466c7..2477a0d4ff 100644 --- a/entc/integration/ent/task_create.go +++ b/entc/integration/ent/task_create.go @@ -22,9 +22,10 @@ import ( // TaskCreate is the builder for creating a Task entity. type TaskCreate struct { config - mutation *TaskMutation - hooks []Hook - conflict []sql.ConflictOption + mutation *TaskMutation + hooks []Hook + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // SetPriority sets the "priority" field. @@ -227,6 +228,7 @@ func (_c *TaskCreate) createSpec() (*Task, *sqlgraph.CreateSpec) { _node = &Task{config: _c.config} _spec = sqlgraph.NewCreateSpec(enttask.Table, sqlgraph.NewFieldSpec(enttask.FieldID, field.TypeInt)) ) + _spec.RetryConfig = _c.retryConfig _spec.OnConflict = _c.conflict if value, ok := _c.mutation.Priority(); ok { _spec.SetField(enttask.FieldPriority, field.TypeInt, value) @@ -263,6 +265,13 @@ func (_c *TaskCreate) createSpec() (*Task, *sqlgraph.CreateSpec) { return _node, _spec } +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *TaskCreate) WithRetryOptions(opts ...any) *TaskCreate { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // @@ -679,9 +688,10 @@ func (u *TaskUpsertOne) IDX(ctx context.Context) int { // TaskCreateBulk is the builder for creating many Task entities in bulk. type TaskCreateBulk struct { config - err error - builders []*TaskCreate - conflict []sql.ConflictOption + err error + builders []*TaskCreate + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Save creates the Task entities in the database. @@ -711,6 +721,7 @@ func (_c *TaskCreateBulk) Save(ctx context.Context) ([]*Task, error) { _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig spec.OnConflict = _c.conflict // Invoke the actual operation on the latest mutation in the chain. if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { @@ -766,6 +777,13 @@ func (_c *TaskCreateBulk) ExecX(ctx context.Context) { } } +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *TaskCreateBulk) WithRetryOptions(opts ...any) *TaskCreateBulk { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // diff --git a/entc/integration/ent/task_delete.go b/entc/integration/ent/task_delete.go index 21b49cae9d..f5e4556c00 100644 --- a/entc/integration/ent/task_delete.go +++ b/entc/integration/ent/task_delete.go @@ -20,8 +20,9 @@ import ( // TaskDelete is the builder for deleting a Task entity. type TaskDelete struct { config - hooks []Hook - mutation *TaskMutation + hooks []Hook + mutation *TaskMutation + retryConfig sql.RetryConfig } // Where appends a list predicates to the TaskDelete builder. @@ -46,6 +47,7 @@ func (_d *TaskDelete) ExecX(ctx context.Context) int { func (_d *TaskDelete) sqlExec(ctx context.Context) (int, error) { _spec := sqlgraph.NewDeleteSpec(enttask.Table, sqlgraph.NewFieldSpec(enttask.FieldID, field.TypeInt)) + _spec.RetryConfig = _d.retryConfig if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -61,6 +63,13 @@ func (_d *TaskDelete) sqlExec(ctx context.Context) (int, error) { return affected, err } +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *TaskDelete) WithRetryOptions(opts ...any) *TaskDelete { + _d.retryConfig.Options = opts + return _d +} + // TaskDeleteOne is the builder for deleting a single Task entity. type TaskDeleteOne struct { _d *TaskDelete diff --git a/entc/integration/ent/task_query.go b/entc/integration/ent/task_query.go index 389a3b75ef..275f112f6a 100644 --- a/entc/integration/ent/task_query.go +++ b/entc/integration/ent/task_query.go @@ -23,11 +23,12 @@ import ( // TaskQuery is the builder for querying Task entities. type TaskQuery struct { config - ctx *QueryContext - order []enttask.OrderOption - inters []Interceptor - predicates []predicate.Task - modifiers []func(*sql.Selector) + ctx *QueryContext + order []enttask.OrderOption + inters []Interceptor + predicates []predicate.Task + modifiers []func(*sql.Selector) + retryConfig sql.RetryConfig // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -353,6 +354,7 @@ func (_q *TaskQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Task, e if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig for i := range hooks { hooks[i](ctx, _spec) } @@ -370,6 +372,7 @@ func (_q *TaskQuery) sqlCount(ctx context.Context) (int, error) { if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig _spec.Node.Columns = _q.ctx.Fields if len(_q.ctx.Fields) > 0 { _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique @@ -484,6 +487,13 @@ func (_q *TaskQuery) Modify(modifiers ...func(s *sql.Selector)) *TaskSelect { return _q.Select() } +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *TaskQuery) WithRetryOptions(opts ...any) *TaskQuery { + _q.retryConfig.Options = opts + return _q +} + // TaskGroupBy is the group-by builder for Task entities. type TaskGroupBy struct { selector diff --git a/entc/integration/ent/task_update.go b/entc/integration/ent/task_update.go index 7f82b65f37..408311b561 100644 --- a/entc/integration/ent/task_update.go +++ b/entc/integration/ent/task_update.go @@ -22,9 +22,10 @@ import ( // TaskUpdate is the builder for updating Task entities. type TaskUpdate struct { config - hooks []Hook - mutation *TaskMutation - modifiers []func(*sql.UpdateBuilder) + hooks []Hook + mutation *TaskMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Where appends a list predicates to the TaskUpdate builder. @@ -227,6 +228,13 @@ func (_u *TaskUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *TaskUpdat return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *TaskUpdate) WithRetryOptions(opts ...any) *TaskUpdate { + _u.retryConfig.Options = opts + return _u +} + func (_u *TaskUpdate) sqlSave(ctx context.Context) (_node int, err error) { if err := _u.check(); err != nil { return _node, err @@ -285,8 +293,9 @@ func (_u *TaskUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(enttask.FieldOp, field.TypeString, value) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{enttask.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -300,10 +309,11 @@ func (_u *TaskUpdate) sqlSave(ctx context.Context) (_node int, err error) { // TaskUpdateOne is the builder for updating a single Task entity. type TaskUpdateOne struct { config - fields []string - hooks []Hook - mutation *TaskMutation - modifiers []func(*sql.UpdateBuilder) + fields []string + hooks []Hook + mutation *TaskMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // SetPriority sets the "priority" field. @@ -513,6 +523,13 @@ func (_u *TaskUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *TaskUp return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *TaskUpdateOne) WithRetryOptions(opts ...any) *TaskUpdateOne { + _u.retryConfig.Options = opts + return _u +} + func (_u *TaskUpdateOne) sqlSave(ctx context.Context) (_node *Task, err error) { if err := _u.check(); err != nil { return _node, err @@ -588,11 +605,12 @@ func (_u *TaskUpdateOne) sqlSave(ctx context.Context) (_node *Task, err error) { _spec.SetField(enttask.FieldOp, field.TypeString, value) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig _node = &Task{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{enttask.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/ent/user_create.go b/entc/integration/ent/user_create.go index 098bc1e6e8..8daaae3572 100644 --- a/entc/integration/ent/user_create.go +++ b/entc/integration/ent/user_create.go @@ -24,9 +24,10 @@ import ( // UserCreate is the builder for creating a User entity. type UserCreate struct { config - mutation *UserMutation - hooks []Hook - conflict []sql.ConflictOption + mutation *UserMutation + hooks []Hook + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // SetOptionalInt sets the "optional_int" field. @@ -473,6 +474,7 @@ func (_c *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) { _node = &User{config: _c.config} _spec = sqlgraph.NewCreateSpec(user.Table, sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt)) ) + _spec.RetryConfig = _c.retryConfig _spec.OnConflict = _c.conflict if value, ok := _c.mutation.OptionalInt(); ok { _spec.SetField(user.FieldOptionalInt, field.TypeInt, value) @@ -703,6 +705,13 @@ func (_c *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) { return _node, _spec } +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *UserCreate) WithRetryOptions(opts ...any) *UserCreate { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // @@ -1270,9 +1279,10 @@ func (u *UserUpsertOne) IDX(ctx context.Context) int { // UserCreateBulk is the builder for creating many User entities in bulk. type UserCreateBulk struct { config - err error - builders []*UserCreate - conflict []sql.ConflictOption + err error + builders []*UserCreate + retryConfig sql.RetryConfig + conflict []sql.ConflictOption } // Save creates the User entities in the database. @@ -1302,6 +1312,7 @@ func (_c *UserCreateBulk) Save(ctx context.Context) ([]*User, error) { _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) } else { spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig spec.OnConflict = _c.conflict // Invoke the actual operation on the latest mutation in the chain. if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { @@ -1357,6 +1368,13 @@ func (_c *UserCreateBulk) ExecX(ctx context.Context) { } } +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *UserCreateBulk) WithRetryOptions(opts ...any) *UserCreateBulk { + _c.retryConfig.Options = opts + return _c +} + // OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause // of the `INSERT` statement. For example: // diff --git a/entc/integration/ent/user_delete.go b/entc/integration/ent/user_delete.go index a5c500abfa..51f59cf9f4 100644 --- a/entc/integration/ent/user_delete.go +++ b/entc/integration/ent/user_delete.go @@ -19,8 +19,9 @@ import ( // UserDelete is the builder for deleting a User entity. type UserDelete struct { config - hooks []Hook - mutation *UserMutation + hooks []Hook + mutation *UserMutation + retryConfig sql.RetryConfig } // Where appends a list predicates to the UserDelete builder. @@ -45,6 +46,7 @@ func (_d *UserDelete) ExecX(ctx context.Context) int { func (_d *UserDelete) sqlExec(ctx context.Context) (int, error) { _spec := sqlgraph.NewDeleteSpec(user.Table, sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt)) + _spec.RetryConfig = _d.retryConfig if ps := _d.mutation.predicates; len(ps) > 0 { _spec.Predicate = func(selector *sql.Selector) { for i := range ps { @@ -60,6 +62,13 @@ func (_d *UserDelete) sqlExec(ctx context.Context) (int, error) { return affected, err } +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *UserDelete) WithRetryOptions(opts ...any) *UserDelete { + _d.retryConfig.Options = opts + return _d +} + // UserDeleteOne is the builder for deleting a single User entity. type UserDeleteOne struct { _d *UserDelete diff --git a/entc/integration/ent/user_query.go b/entc/integration/ent/user_query.go index 7781c3fa13..5bb10ff36d 100644 --- a/entc/integration/ent/user_query.go +++ b/entc/integration/ent/user_query.go @@ -52,6 +52,7 @@ type UserQuery struct { withNamedFollowers map[string]*UserQuery withNamedFollowing map[string]*UserQuery withNamedChildren map[string]*UserQuery + retryConfig sql.RetryConfig // intermediate query (i.e. traversal path). sql *sql.Selector path func(context.Context) (*sql.Selector, error) @@ -772,6 +773,7 @@ func (_q *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, e if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig for i := range hooks { hooks[i](ctx, _spec) } @@ -1409,6 +1411,7 @@ func (_q *UserQuery) sqlCount(ctx context.Context) (int, error) { if len(_q.modifiers) > 0 { _spec.Modifiers = _q.modifiers } + _spec.RetryConfig = _q.retryConfig _spec.Node.Columns = _q.ctx.Fields if len(_q.ctx.Fields) > 0 { _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique @@ -1621,6 +1624,13 @@ func (_q *UserQuery) WithNamedChildren(name string, opts ...func(*UserQuery)) *U return _q } +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *UserQuery) WithRetryOptions(opts ...any) *UserQuery { + _q.retryConfig.Options = opts + return _q +} + // UserGroupBy is the group-by builder for User entities. type UserGroupBy struct { selector diff --git a/entc/integration/ent/user_update.go b/entc/integration/ent/user_update.go index 126b7d2861..d6020c711d 100644 --- a/entc/integration/ent/user_update.go +++ b/entc/integration/ent/user_update.go @@ -25,9 +25,10 @@ import ( // UserUpdate is the builder for updating User entities. type UserUpdate struct { config - hooks []Hook - mutation *UserMutation - modifiers []func(*sql.UpdateBuilder) + hooks []Hook + mutation *UserMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // Where appends a list predicates to the UserUpdate builder. @@ -677,6 +678,13 @@ func (_u *UserUpdate) Modify(modifiers ...func(u *sql.UpdateBuilder)) *UserUpdat return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *UserUpdate) WithRetryOptions(opts ...any) *UserUpdate { + _u.retryConfig.Options = opts + return _u +} + func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { if err := _u.check(); err != nil { return _node, err @@ -1187,8 +1195,9 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -1202,10 +1211,11 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { // UserUpdateOne is the builder for updating a single User entity. type UserUpdateOne struct { config - fields []string - hooks []Hook - mutation *UserMutation - modifiers []func(*sql.UpdateBuilder) + fields []string + hooks []Hook + mutation *UserMutation + modifiers []func(*sql.UpdateBuilder) + retryConfig sql.RetryConfig } // SetOptionalInt sets the "optional_int" field. @@ -1862,6 +1872,13 @@ func (_u *UserUpdateOne) Modify(modifiers ...func(u *sql.UpdateBuilder)) *UserUp return _u } +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *UserUpdateOne) WithRetryOptions(opts ...any) *UserUpdateOne { + _u.retryConfig.Options = opts + return _u +} + func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { if err := _u.check(); err != nil { return _node, err @@ -2389,11 +2406,12 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } _spec.AddModifiers(_u.modifiers...) + _spec.RetryConfig = _u.retryConfig _node = &User{config: _u.config} _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/go.mod b/entc/integration/go.mod index e631fae3f5..3f342129a9 100644 --- a/entc/integration/go.mod +++ b/entc/integration/go.mod @@ -1,8 +1,6 @@ module entgo.io/ent/entc/integration -go 1.24 - -toolchain go1.24.0 +go 1.24.13 replace entgo.io/ent => ../../ @@ -11,11 +9,11 @@ require ( ariga.io/atlas-go-sdk v0.6.9 entgo.io/ent v0.0.0-00010101000000-000000000000 github.com/go-sql-driver/mysql v1.7.0 - github.com/google/uuid v1.3.0 + github.com/google/uuid v1.6.0 github.com/lib/pq v1.10.7 github.com/mattn/go-sqlite3 v1.14.28 - github.com/stretchr/testify v1.8.4 - golang.org/x/sync v0.11.0 + github.com/stretchr/testify v1.11.1 + golang.org/x/sync v0.19.0 ) require ( @@ -24,8 +22,10 @@ require ( github.com/bmatcuk/doublestar v1.3.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-openapi/inflect v0.19.0 // indirect - github.com/google/go-cmp v0.6.0 // indirect + github.com/golang-jwt/jwt/v4 v4.5.2 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/hashicorp/hcl/v2 v2.18.1 // indirect + github.com/jonboulle/clockwork v0.5.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect @@ -33,10 +33,19 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect - github.com/stretchr/objx v0.5.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect + github.com/ydb-platform/ydb-go-genproto v0.0.0-20251222105147-0bf751469a4a // indirect + github.com/ydb-platform/ydb-go-sdk/v3 v3.125.4 // indirect github.com/zclconf/go-cty v1.14.4 // indirect github.com/zclconf/go-cty-yaml v1.1.0 // indirect - golang.org/x/mod v0.24.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/mod v0.30.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/text v0.32.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/grpc v1.78.0 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) + +replace ariga.io/atlas => github.com/ydb-platform/ariga-atlas v0.0.1 diff --git a/entc/integration/go.sum b/entc/integration/go.sum index f9069a0a13..a18cb0780d 100644 --- a/entc/integration/go.sum +++ b/entc/integration/go.sum @@ -1,33 +1,85 @@ -ariga.io/atlas v0.36.2-0.20250730182955-2c6300d0a3e1 h1:NPPfBaVZgz4LKBCIc0FbMogCjvXN+yGf7CZwotOwJo8= -ariga.io/atlas v0.36.2-0.20250730182955-2c6300d0a3e1/go.mod h1:Ex5l1xHsnWQUc3wYnrJ9gD7RUEzG76P7ZRQp8wNr0wc= ariga.io/atlas-go-sdk v0.6.9 h1:G5OajpcSIrLRMz8VfmMdfkNptlGstiK0zQ0dtuZWBaE= ariga.io/atlas-go-sdk v0.6.9/go.mod h1:cFq7bnvHgKTWHCsU46mtkGxdl41rx2o7SjaLoh6cO8M= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0= github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= +github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/hcl/v2 v2.18.1 h1:6nxnOJFku1EuSawSD81fuviYUV8DxFr3fp2dUi3ZYSo= github.com/hashicorp/hcl/v2 v2.18.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I= +github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= @@ -49,38 +101,135 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rekby/fixenv v0.6.1 h1:jUFiSPpajT4WY2cYuc++7Y1zWrnCxnovGCIX72PZniM= +github.com/rekby/fixenv v0.6.1/go.mod h1:/b5LRc06BYJtslRtHKxsPWFT/ySpHV+rWvzTg+XWk4c= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/ydb-platform/ariga-atlas v0.0.1 h1:atWj2dpOKWIZ6sR0NVQrZDIJ40k85gkZ/7D7opqlCW0= +github.com/ydb-platform/ariga-atlas v0.0.1/go.mod h1:t5BRX5MhK+I0vLdUMeUBOz1x2uNP/FYejPLUBcsCWcw= +github.com/ydb-platform/ydb-go-genproto v0.0.0-20251222105147-0bf751469a4a h1:nRqONRrMFulP2bTWM2RRnPM1VDhWuBZg4ULXkG4xXdk= +github.com/ydb-platform/ydb-go-genproto v0.0.0-20251222105147-0bf751469a4a/go.mod h1:Er+FePu1dNUieD+XTMDduGpQuCPssK5Q4BjF+IIXJ3I= +github.com/ydb-platform/ydb-go-sdk/v3 v3.125.4 h1:GAC7qeNgsibEJkUVzV4z06aBnHR4jqfXsFiQtrY40gI= +github.com/ydb-platform/ydb-go-sdk/v3 v3.125.4/go.mod h1:stS1mQYjbJvwwYaYzKyFY9eMiuVXWWXQA6T+SpOLg9c= github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= github.com/zclconf/go-cty-yaml v1.1.0 h1:nP+jp0qPHv2IhUVqmQSzjvqAWcObN0KBkUl2rWBdig0= github.com/zclconf/go-cty-yaml v1.1.0/go.mod h1:9YLUH4g7lOhVWqUbctnVlZ5KLpg7JAprQNgxSZ1Gyxs= -golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= -golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= +golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= +google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/entc/integration/hooks/ent/card_update.go b/entc/integration/hooks/ent/card_update.go index 20a7366810..1d2377e8fb 100644 --- a/entc/integration/hooks/ent/card_update.go +++ b/entc/integration/hooks/ent/card_update.go @@ -215,7 +215,7 @@ func (_u *CardUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{card.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -449,7 +449,7 @@ func (_u *CardUpdateOne) sqlSave(ctx context.Context) (_node *Card, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{card.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/hooks/ent/client.go b/entc/integration/hooks/ent/client.go index a8e9f11de8..4b4c2dd21a 100644 --- a/entc/integration/hooks/ent/client.go +++ b/entc/integration/hooks/ent/client.go @@ -112,7 +112,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/entc/integration/hooks/ent/pet_update.go b/entc/integration/hooks/ent/pet_update.go index 26a02eec54..4c895a0bd1 100644 --- a/entc/integration/hooks/ent/pet_update.go +++ b/entc/integration/hooks/ent/pet_update.go @@ -181,7 +181,7 @@ func (_u *PetUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -381,7 +381,7 @@ func (_u *PetUpdateOne) sqlSave(ctx context.Context) (_node *Pet, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/hooks/ent/user_update.go b/entc/integration/hooks/ent/user_update.go index 2964b4129c..193cd31944 100644 --- a/entc/integration/hooks/ent/user_update.go +++ b/entc/integration/hooks/ent/user_update.go @@ -495,7 +495,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -1009,7 +1009,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/idtype/ent/client.go b/entc/integration/idtype/ent/client.go index 18cfcf6566..54927ecec6 100644 --- a/entc/integration/idtype/ent/client.go +++ b/entc/integration/idtype/ent/client.go @@ -104,7 +104,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/entc/integration/idtype/ent/user_update.go b/entc/integration/idtype/ent/user_update.go index 1aecd20142..0ff440e743 100644 --- a/entc/integration/idtype/ent/user_update.go +++ b/entc/integration/idtype/ent/user_update.go @@ -306,7 +306,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -633,7 +633,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/integration_test.go b/entc/integration/integration_test.go index 091c125ecf..2044e9fc03 100644 --- a/entc/integration/integration_test.go +++ b/entc/integration/integration_test.go @@ -132,6 +132,29 @@ func TestPostgres(t *testing.T) { } } +func TestYDB(t *testing.T) { + t.Parallel() + + ydbOpts := enttest.WithMigrateOptions( + migrate.WithDropIndex(true), + migrate.WithDropColumn(true), + migrate.WithForeignKeys(false), + sqlschema.WithSkipChanges(sqlschema.ModifyColumn), + ) + + client := enttest.Open(t, dialect.YDB, "grpc://localhost:2136/local", ydbOpts) + client = client.Debug() + defer client.Close() + + for _, tt := range tests { + name := runtime.FuncForPC(reflect.ValueOf(tt).Pointer()).Name() + t.Run(name[strings.LastIndex(name, ".")+1:], func(t *testing.T) { + drop(t, client) + tt(t, client) + }) + } +} + var ( opts = enttest.WithMigrateOptions( migrate.WithDropIndex(true), @@ -328,13 +351,17 @@ func Sanity(t *testing.T, client *ent.Client) { } func Upsert(t *testing.T, client *ent.Client) { + // YDB's UPSERT has different semantics. + // it only resolves conflicts on primary key and replaces the entire row. + skip(t, "YDB") + ctx := context.Background() u := client.User.Create().SetName("Ariel").SetAge(30).SetPhone("0000").SaveX(ctx) require.Equal(t, "static", u.Address, "address was set by default func") err := client.User.Create().SetName("Mashraki").SetAge(30).SetPhone("0000").Exec(ctx) require.True(t, ent.IsConstraintError(err), "phone field is unique") err = client.User.Create().SetName("Mashraki").SetAge(30).SetPhone("0000").OnConflict().Exec(ctx) - require.EqualError(t, err, "ent: missing options for UserCreate.OnConflict") + require.ErrorContains(t, err, "ent: missing options for UserCreate.OnConflict") client.User.Create(). SetName("Mashraki"). @@ -740,8 +767,21 @@ func Select(t *testing.T, client *ent.Client) { // Append the "users_count" column to the selected columns. AppendSelect( sql.As(sql.Count(t.C(group.UsersPrimaryKey[1])), "users_count"), - ). - GroupBy(s.C(group.FieldID)) + ) + + // YDB requires all non-key and non-aggregated columns to be in GROUP BY + if s.Dialect() == dialect.YDB { + s.GroupBy( + s.C(group.FieldID), + s.C(group.FieldActive), + s.C(group.FieldExpire), + s.C(group.FieldType), + s.C(group.FieldMaxUsers), + s.C(group.FieldName), + ) + } else { + s.GroupBy(s.C(group.FieldID)) + } }). ScanX(ctx, &gs) require.Len(gs, 2) @@ -786,7 +826,7 @@ func Select(t *testing.T, client *ent.Client) { // Execute custom update modifier. client.User.Update(). Modify(func(u *sql.UpdateBuilder) { - u.Set(user.FieldName, sql.Expr(fmt.Sprintf("UPPER(%s)", user.FieldName))) + u.Set(user.FieldName, sql.UpperExpr(user.FieldName)) }). ExecX(ctx) require.True(allUpper(), "at names must be upper-cased") @@ -827,8 +867,11 @@ func Select(t *testing.T, client *ent.Client) { } // Order by random value should compile a valid query. - _, err = client.User.Query().Order(sql.OrderByRand()).All(ctx) - require.NoError(err) + // YDB doesn't support ORDER BY with constant expressions like Random(seed). + if client.Dialect() != dialect.YDB { + _, err = client.User.Query().Order(sql.OrderByRand()).All(ctx) + require.NoError(err) + } } func Aggregate(t *testing.T, client *ent.Client) { @@ -1069,8 +1112,12 @@ func Delete(t *testing.T, client *ent.Client) { info := client.GroupInfo.Create().SetDesc("group info").SaveX(ctx) hub := client.Group.Create().SetInfo(info).SetName("GitHub").SetExpire(time.Now().Add(time.Hour)).SaveX(ctx) - err = client.GroupInfo.DeleteOne(info).Exec(ctx) - require.True(ent.IsConstraintError(err)) + + // YDB doesn't have foreign keys constraints + if client.Dialect() != dialect.YDB { + err = client.GroupInfo.DeleteOne(info).Exec(ctx) + require.True(ent.IsConstraintError(err)) + } // Group.DeleteOneID(id).Where(...), is identical to Group.Delete().Where(group.ID(id), ...), // but, in case the OpDelete is not an allowed operation, the DeleteOne can be used with Where. @@ -1086,18 +1133,26 @@ func Delete(t *testing.T, client *ent.Client) { Where(group.ExpireLT(time.Now())). Exec(ctx) require.True(ent.IsNotFound(err)) + hub.Update().SetExpire(time.Now().Add(-time.Hour)).ExecX(ctx) + client.Group.DeleteOne(hub). Where(group.ExpireLT(time.Now())). ExecX(ctx) // The behavior described above it also applied to UpdateOne. - hub = client.Group.Create().SetInfo(info).SetName("GitHub").SetExpire(time.Now().Add(time.Hour)).SaveX(ctx) + hub = client.Group.Create(). + SetInfo(info). + SetName("GitHub"). + SetExpire(time.Now().Add(time.Hour)). + SaveX(ctx) + err = hub.Update(). SetActive(false). - SetExpire(time.Time{}). + SetExpire(time.Unix(0, 0)). Where(group.ExpireLT(time.Now())). // Expired. Exec(ctx) + require.True(ent.IsNotFound(err)) } @@ -1244,8 +1299,8 @@ func Relation(t *testing.T, client *ent.Client) { require.Error(err, "name validator failed") var checkerr schema.CheckError require.True(errors.As(err, &checkerr)) - require.EqualError(err, `ent: validator failed for field "Group.name": last name must begin with uppercase`) - require.EqualError(checkerr, "last name must begin with uppercase") + require.ErrorContains(err, `ent: validator failed for field "Group.name": last name must begin with uppercase`) + require.ErrorContains(checkerr, "last name must begin with uppercase") err = client.Group.Create().SetInfo(info).SetType("pass").SetName("Github20").SetExpire(time.Now().Add(time.Hour)).Exec(ctx) require.Error(err, "name validator failed") err = client.Group.Create().SetInfo(info).SetType("pass").SetName("Github").SetMaxUsers(-1).SetExpire(time.Now().Add(time.Hour)).Exec(ctx) @@ -1255,15 +1310,15 @@ func Relation(t *testing.T, client *ent.Client) { err = client.Group.UpdateOne(grp).SetMaxUsers(-10).Exec(ctx) require.Error(err, "max_users validator failed") _, err = client.Group.Query().Select("unknown_field").String(ctx) - require.EqualError(err, "ent: invalid field \"unknown_field\" for query") + require.ErrorContains(err, "ent: invalid field \"unknown_field\" for query") _, err = client.Group.Query().GroupBy("unknown_field").String(ctx) - require.EqualError(err, "ent: invalid field \"unknown_field\" for query") + require.ErrorContains(err, "ent: invalid field \"unknown_field\" for query") _, err = client.User.Query().Order(ent.Asc("invalid")).Only(ctx) - require.EqualError(err, "ent: unknown column \"invalid\" for table \"users\"") + require.ErrorContains(err, "ent: unknown column \"invalid\" for table \"users\"") _, err = client.User.Query().Order(ent.Asc("invalid")).QueryFollowing().Only(ctx) - require.EqualError(err, "ent: unknown column \"invalid\" for table \"users\"") + require.ErrorContains(err, "ent: unknown column \"invalid\" for table \"users\"") _, err = client.User.Query().GroupBy("name").Aggregate(ent.Sum("invalid")).String(ctx) - require.EqualError(err, "ent: unknown column \"invalid\" for table \"users\"") + require.ErrorContains(err, "ent: unknown column \"invalid\" for table \"users\"") t.Log("query using edge-with predicate") require.Len(usr.QueryGroups().Where(group.HasInfoWith(groupinfo.Desc("group info"))).AllX(ctx), 1) @@ -1625,13 +1680,22 @@ func UniqueConstraint(t *testing.T, client *ent.Client) { cm1 := client.Comment.Create().SetUniqueInt(42).SetUniqueFloat(math.Pi).SaveX(ctx) err = client.Comment.Create().SetUniqueInt(42).SetUniqueFloat(math.E).Exec(ctx) require.Error(err) - err = client.Comment.Create().SetUniqueInt(7).SetUniqueFloat(math.Pi).Exec(ctx) - require.Error(err) + + // YDB doesn't support unique indexes on float columns. + if client.Dialect() != dialect.YDB { + err = client.Comment.Create().SetUniqueInt(7).SetUniqueFloat(math.Pi).Exec(ctx) + require.Error(err) + } + client.Comment.Create().SetUniqueInt(7).SetUniqueFloat(math.E).ExecX(ctx) err = cm1.Update().SetUniqueInt(7).Exec(ctx) require.Error(err) - err = cm1.Update().SetUniqueFloat(math.E).Exec(ctx) - require.Error(err) + + // YDB doesn't support unique indexes on float columns. + if client.Dialect() != dialect.YDB { + err = cm1.Update().SetUniqueFloat(math.E).Exec(ctx) + require.Error(err) + } t.Log("unique constraint on time fields") now := time.Now() @@ -1666,7 +1730,7 @@ func Tx(t *testing.T, client *ent.Client) { m.On("onRollback", nil).Once() defer m.AssertExpectations(t) tx.OnRollback(m.rHook()) - tx.Node.Create().ExecX(ctx) + tx.Node.Create().SetValue(0).ExecX(ctx) require.NoError(t, tx.Rollback()) require.Zero(t, client.Node.Query().CountX(ctx), "rollback should discard all changes") }) @@ -1683,13 +1747,13 @@ func Tx(t *testing.T, client *ent.Client) { return err }) }) - nde := tx.Node.Create().SaveX(ctx) + node := tx.Node.Create().SetValue(0).SaveX(ctx) require.NoError(t, tx.Commit()) require.Error(t, tx.Commit(), "should return an error on the second call") require.NotZero(t, client.Node.Query().CountX(ctx), "commit should save all changes") - _, err = nde.QueryNext().Count(ctx) + _, err = node.QueryNext().Count(ctx) require.Error(t, err, "should not be able to query after tx was closed") - require.Zero(t, nde.Unwrap().QueryNext().CountX(ctx), "should be able to query the entity after wrap") + require.Zero(t, node.Unwrap().QueryNext().CountX(ctx), "should be able to query the entity after wrap") }) t.Run("Nested", func(t *testing.T) { tx, err := client.Tx(ctx) @@ -1703,8 +1767,19 @@ func Tx(t *testing.T, client *ent.Client) { require.NoError(t, tx.Rollback()) }) t.Run("TxOptions Rollback", func(t *testing.T) { - skip(t, "SQLite") - tx, err := client.BeginTx(ctx, &sql.TxOptions{ReadOnly: true}) + skip(t, "SQLite", "YDB") + + var txOptions sql.TxOptions + if client.Dialect() == dialect.YDB { + txOptions = sql.TxOptions{ + Isolation: stdsql.LevelSnapshot, + ReadOnly: true, + } + } else { + txOptions = sql.TxOptions{ReadOnly: true} + } + + tx, err := client.BeginTx(ctx, &txOptions) require.NoError(t, err) var m mocker m.On("onRollback", nil).Once() @@ -1721,10 +1796,38 @@ func Tx(t *testing.T, client *ent.Client) { require.Error(t, err, "expect creation to fail in read-only tx") require.NoError(t, tx.Rollback()) }) + t.Run("YDB TxOptions Rollback", func(t *testing.T) { + if client.Dialect() != dialect.YDB { + t.Skip("YDB-specific test") + } + + tx, err := client.BeginTx(ctx, &sql.TxOptions{ + Isolation: stdsql.LevelSnapshot, + ReadOnly: true, + }) + require.NoError(t, err) + + err = tx.Item.Create().Exec(ctx) + require.Error(t, err, "expect creation to fail in read-only tx") + + // YDB implicitly invalidates transaction so Rollback() should return err + err = tx.Rollback() + require.Error(t, err) + require.Contains(t, err.Error(), "Transaction not found") + }) t.Run("TxOptions Commit", func(t *testing.T) { skip(t, "SQLite") - tx, err := client.BeginTx(ctx, &sql.TxOptions{Isolation: stdsql.LevelReadCommitted}) + + var txOptions sql.TxOptions + if client.Dialect() == dialect.YDB { + txOptions = sql.TxOptions{Isolation: stdsql.LevelSerializable} + } else { + txOptions = sql.TxOptions{Isolation: stdsql.LevelReadCommitted} + } + + tx, err := client.BeginTx(ctx, &txOptions) require.NoError(t, err) + var m mocker m.On("onCommit", nil).Once() defer m.AssertExpectations(t) @@ -2164,12 +2267,29 @@ func NoSchemaChanges(t *testing.T, client *ent.Client) { }) tables, err := sqlschema.CopyTables(migrate.Tables) require.NoError(t, err) + + opts := []sqlschema.MigrateOption{ + migrate.WithDropIndex(true), + migrate.WithDropColumn(true), + } + if strings.Contains(t.Name(), "YDB") { + opts = append( + opts, + migrate.WithForeignKeys(false), + sqlschema.WithSkipChanges(sqlschema.ModifyColumn), + ) + } + err = migrate.Create( context.Background(), - migrate.NewSchema(&sqlschema.WriteDriver{Writer: w, Driver: client.Driver()}), + migrate.NewSchema( + &sqlschema.WriteDriver{ + Driver: client.Driver(), + Writer: w, + }, + ), tables, - migrate.WithDropIndex(true), - migrate.WithDropColumn(true), + opts..., ) require.NoError(t, err) } @@ -2326,6 +2446,8 @@ func CreateBulk(t *testing.T, client *ent.Client) { } func ConstraintChecks(t *testing.T, client *ent.Client) { + skip(t, "YDB") + var cerr *ent.ConstraintError err := client.Pet.Create().SetName("orphan").SetOwnerID(0).Exec(context.Background()) require.True(t, errors.As(err, &cerr)) @@ -2340,7 +2462,7 @@ func ConstraintChecks(t *testing.T, client *ent.Client) { } func Lock(t *testing.T, client *ent.Client) { - skip(t, "SQLite", "MySQL/5", "Maria/10.2") + skip(t, "SQLite", "MySQL/5", "Maria/10.2", "YDB") ctx := context.Background() xabi := client.Pet.Create().SetName("Xabi").SaveX(ctx) @@ -2399,6 +2521,7 @@ func Lock(t *testing.T, client *ent.Client) { } func ExtValueScan(t *testing.T, client *ent.Client) { + skip(t, "YDB") ctx := context.Background() u, err := url.Parse("https://entgo.io") require.NoError(t, err) diff --git a/entc/integration/json/ent/client.go b/entc/integration/json/ent/client.go index 36ba6679f9..2bf861dbb5 100644 --- a/entc/integration/json/ent/client.go +++ b/entc/integration/json/ent/client.go @@ -103,7 +103,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/entc/integration/json/ent/user_update.go b/entc/integration/json/ent/user_update.go index a9c6c5c68c..840aef8a1c 100644 --- a/entc/integration/json/ent/user_update.go +++ b/entc/integration/json/ent/user_update.go @@ -441,7 +441,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { } _spec.AddModifiers(_u.modifiers...) if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -898,7 +898,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/migrate/entv1/car_update.go b/entc/integration/migrate/entv1/car_update.go index f2f677ae90..f3c207af5c 100644 --- a/entc/integration/migrate/entv1/car_update.go +++ b/entc/integration/migrate/entv1/car_update.go @@ -128,7 +128,7 @@ func (_u *CarUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{car.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -276,7 +276,7 @@ func (_u *CarUpdateOne) sqlSave(ctx context.Context) (_node *Car, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{car.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/migrate/entv1/client.go b/entc/integration/migrate/entv1/client.go index d3cae2b84f..f8ca5ecbc1 100644 --- a/entc/integration/migrate/entv1/client.go +++ b/entc/integration/migrate/entv1/client.go @@ -116,7 +116,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/entc/integration/migrate/entv1/conversion_update.go b/entc/integration/migrate/entv1/conversion_update.go index dae6d6d908..b374661d00 100644 --- a/entc/integration/migrate/entv1/conversion_update.go +++ b/entc/integration/migrate/entv1/conversion_update.go @@ -387,7 +387,7 @@ func (_u *ConversionUpdate) sqlSave(ctx context.Context) (_node int, err error) _spec.ClearField(conversion.FieldUint64ToString, field.TypeUint64) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{conversion.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -795,7 +795,7 @@ func (_u *ConversionUpdateOne) sqlSave(ctx context.Context) (_node *Conversion, _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{conversion.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/migrate/entv1/customtype_update.go b/entc/integration/migrate/entv1/customtype_update.go index b2440d4cca..58b17c87a9 100644 --- a/entc/integration/migrate/entv1/customtype_update.go +++ b/entc/integration/migrate/entv1/customtype_update.go @@ -99,7 +99,7 @@ func (_u *CustomTypeUpdate) sqlSave(ctx context.Context) (_node int, err error) _spec.ClearField(customtype.FieldCustom, field.TypeString) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{customtype.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -219,7 +219,7 @@ func (_u *CustomTypeUpdateOne) sqlSave(ctx context.Context) (_node *CustomType, _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{customtype.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/migrate/entv1/user_update.go b/entc/integration/migrate/entv1/user_update.go index 8d8ab0e41c..1663c6fd5f 100644 --- a/entc/integration/migrate/entv1/user_update.go +++ b/entc/integration/migrate/entv1/user_update.go @@ -623,7 +623,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -1266,7 +1266,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/migrate/entv2/blog_create.go b/entc/integration/migrate/entv2/blog_create.go index c1a2ad5f45..39e9ddbbaa 100644 --- a/entc/integration/migrate/entv2/blog_create.go +++ b/entc/integration/migrate/entv2/blog_create.go @@ -87,7 +87,7 @@ func (_c *BlogCreate) ExecX(ctx context.Context) { // check runs all checks and user-defined validators on the builder. func (_c *BlogCreate) check() error { switch _c.driver.Dialect() { - case dialect.MySQL, dialect.SQLite: + case dialect.MySQL, dialect.SQLite, dialect.YDB: if _, ok := _c.mutation.Oid(); !ok { return &ValidationError{Name: "oid", err: errors.New(`entv2: missing required field "Blog.oid"`)} } diff --git a/entc/integration/migrate/entv2/blog_update.go b/entc/integration/migrate/entv2/blog_update.go index 7316741baf..41971b661f 100644 --- a/entc/integration/migrate/entv2/blog_update.go +++ b/entc/integration/migrate/entv2/blog_update.go @@ -182,7 +182,7 @@ func (_u *BlogUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{blog.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -384,7 +384,7 @@ func (_u *BlogUpdateOne) sqlSave(ctx context.Context) (_node *Blog, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{blog.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/migrate/entv2/car_update.go b/entc/integration/migrate/entv2/car_update.go index 8f8d659c30..95a4febce4 100644 --- a/entc/integration/migrate/entv2/car_update.go +++ b/entc/integration/migrate/entv2/car_update.go @@ -157,7 +157,7 @@ func (_u *CarUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{car.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -334,7 +334,7 @@ func (_u *CarUpdateOne) sqlSave(ctx context.Context) (_node *Car, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{car.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/migrate/entv2/client.go b/entc/integration/migrate/entv2/client.go index ed15ab6937..24e0f7b29c 100644 --- a/entc/integration/migrate/entv2/client.go +++ b/entc/integration/migrate/entv2/client.go @@ -136,7 +136,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/entc/integration/migrate/entv2/conversion_update.go b/entc/integration/migrate/entv2/conversion_update.go index 49386998a8..dc93925e3c 100644 --- a/entc/integration/migrate/entv2/conversion_update.go +++ b/entc/integration/migrate/entv2/conversion_update.go @@ -307,7 +307,7 @@ func (_u *ConversionUpdate) sqlSave(ctx context.Context) (_node int, err error) _spec.ClearField(conversion.FieldUint64ToString, field.TypeString) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{conversion.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -635,7 +635,7 @@ func (_u *ConversionUpdateOne) sqlSave(ctx context.Context) (_node *Conversion, _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{conversion.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/migrate/entv2/customtype_update.go b/entc/integration/migrate/entv2/customtype_update.go index 917529dba2..a0d90094ff 100644 --- a/entc/integration/migrate/entv2/customtype_update.go +++ b/entc/integration/migrate/entv2/customtype_update.go @@ -152,7 +152,7 @@ func (_u *CustomTypeUpdate) sqlSave(ctx context.Context) (_node int, err error) _spec.ClearField(customtype.FieldTz3, field.TypeTime) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{customtype.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -324,7 +324,7 @@ func (_u *CustomTypeUpdateOne) sqlSave(ctx context.Context) (_node *CustomType, _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{customtype.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/migrate/entv2/group_update.go b/entc/integration/migrate/entv2/group_update.go index 256ab44faf..3b3e0a72dc 100644 --- a/entc/integration/migrate/entv2/group_update.go +++ b/entc/integration/migrate/entv2/group_update.go @@ -73,7 +73,7 @@ func (_u *GroupUpdate) sqlSave(ctx context.Context) (_node int, err error) { } } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -167,7 +167,7 @@ func (_u *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error) _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/migrate/entv2/media_update.go b/entc/integration/migrate/entv2/media_update.go index ed0ea4ea73..6f20c61800 100644 --- a/entc/integration/migrate/entv2/media_update.go +++ b/entc/integration/migrate/entv2/media_update.go @@ -151,7 +151,7 @@ func (_u *MediaUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.ClearField(media.FieldText, field.TypeString) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{media.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -323,7 +323,7 @@ func (_u *MediaUpdateOne) sqlSave(ctx context.Context) (_node *Media, err error) _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{media.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/migrate/entv2/pet_update.go b/entc/integration/migrate/entv2/pet_update.go index 40df7a4714..330b9e6cf0 100644 --- a/entc/integration/migrate/entv2/pet_update.go +++ b/entc/integration/migrate/entv2/pet_update.go @@ -154,7 +154,7 @@ func (_u *PetUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -328,7 +328,7 @@ func (_u *PetUpdateOne) sqlSave(ctx context.Context) (_node *Pet, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/migrate/entv2/user_update.go b/entc/integration/migrate/entv2/user_update.go index b5e57efb88..cbe351c7d0 100644 --- a/entc/integration/migrate/entv2/user_update.go +++ b/entc/integration/migrate/entv2/user_update.go @@ -770,7 +770,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -1557,7 +1557,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/migrate/entv2/zoo_update.go b/entc/integration/migrate/entv2/zoo_update.go index 41ae967e3c..790d2e6187 100644 --- a/entc/integration/migrate/entv2/zoo_update.go +++ b/entc/integration/migrate/entv2/zoo_update.go @@ -73,7 +73,7 @@ func (_u *ZooUpdate) sqlSave(ctx context.Context) (_node int, err error) { } } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{zoo.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -167,7 +167,7 @@ func (_u *ZooUpdateOne) sqlSave(ctx context.Context) (_node *Zoo, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{zoo.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/migrate/migrate_test.go b/entc/integration/migrate/migrate_test.go index c4c0b3b59e..7816f9ae8f 100644 --- a/entc/integration/migrate/migrate_test.go +++ b/entc/integration/migrate/migrate_test.go @@ -856,7 +856,11 @@ func fillNulls(dbdialect string) schema.ApplyHook { // There are three ways to UPDATE the NULL values to "Unknown" in this stage. // Append a custom migrate.Change to the plan, execute an SQL statement directly // on the dialect.ExecQuerier, or use the ent.Client used by the project. - drv := sql.NewDriver(dbdialect, sql.Conn{ExecQuerier: conn.(*sql.Tx)}) + drv := sql.NewDriver( + dbdialect, + sql.Conn{ExecQuerier: conn.(*sql.Tx)}, + sql.NewRetryExecutor(dbdialect, nil), + ) client := entv2.NewClient(entv2.Driver(drv)) if err := client.User. Update(). diff --git a/entc/integration/migrate/versioned/client.go b/entc/integration/migrate/versioned/client.go index d745e43d82..5583848196 100644 --- a/entc/integration/migrate/versioned/client.go +++ b/entc/integration/migrate/versioned/client.go @@ -107,7 +107,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/entc/integration/migrate/versioned/group_update.go b/entc/integration/migrate/versioned/group_update.go index b639195a98..fe7f83aa5a 100644 --- a/entc/integration/migrate/versioned/group_update.go +++ b/entc/integration/migrate/versioned/group_update.go @@ -90,7 +90,7 @@ func (_u *GroupUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(group.FieldName, field.TypeString, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -201,7 +201,7 @@ func (_u *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error) _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/migrate/versioned/user_update.go b/entc/integration/migrate/versioned/user_update.go index ffb0ff85c3..58eac24b62 100644 --- a/entc/integration/migrate/versioned/user_update.go +++ b/entc/integration/migrate/versioned/user_update.go @@ -156,7 +156,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.ClearField(user.FieldAddress, field.TypeString) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -333,7 +333,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/multischema/ent/client.go b/entc/integration/multischema/ent/client.go index 50c593dd0b..dc40291cbf 100644 --- a/entc/integration/multischema/ent/client.go +++ b/entc/integration/multischema/ent/client.go @@ -128,7 +128,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/entc/integration/multischema/ent/friendship_update.go b/entc/integration/multischema/ent/friendship_update.go index 66dde137ed..5692c086ce 100644 --- a/entc/integration/multischema/ent/friendship_update.go +++ b/entc/integration/multischema/ent/friendship_update.go @@ -143,7 +143,7 @@ func (_u *FriendshipUpdate) sqlSave(ctx context.Context) (_node int, err error) ctx = internal.NewSchemaConfigContext(ctx, _u.schemaConfig) _spec.AddModifiers(_u.modifiers...) if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{friendship.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -305,7 +305,7 @@ func (_u *FriendshipUpdateOne) sqlSave(ctx context.Context) (_node *Friendship, _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{friendship.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/multischema/ent/group_update.go b/entc/integration/multischema/ent/group_update.go index 88e8c5d53f..1a9e29a891 100644 --- a/entc/integration/multischema/ent/group_update.go +++ b/entc/integration/multischema/ent/group_update.go @@ -186,7 +186,7 @@ func (_u *GroupUpdate) sqlSave(ctx context.Context) (_node int, err error) { ctx = internal.NewSchemaConfigContext(ctx, _u.schemaConfig) _spec.AddModifiers(_u.modifiers...) if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -391,7 +391,7 @@ func (_u *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error) _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/multischema/ent/parent_update.go b/entc/integration/multischema/ent/parent_update.go index 94ad8d241b..88c39d5a31 100644 --- a/entc/integration/multischema/ent/parent_update.go +++ b/entc/integration/multischema/ent/parent_update.go @@ -115,7 +115,7 @@ func (_u *ParentUpdate) sqlSave(ctx context.Context) (_node int, err error) { ctx = internal.NewSchemaConfigContext(ctx, _u.schemaConfig) _spec.AddModifiers(_u.modifiers...) if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{parent.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -250,7 +250,7 @@ func (_u *ParentUpdateOne) sqlSave(ctx context.Context) (_node *Parent, err erro _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{parent.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/multischema/ent/pet_update.go b/entc/integration/multischema/ent/pet_update.go index 2748bf6db3..6f66938b24 100644 --- a/entc/integration/multischema/ent/pet_update.go +++ b/entc/integration/multischema/ent/pet_update.go @@ -164,7 +164,7 @@ func (_u *PetUpdate) sqlSave(ctx context.Context) (_node int, err error) { ctx = internal.NewSchemaConfigContext(ctx, _u.schemaConfig) _spec.AddModifiers(_u.modifiers...) if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -347,7 +347,7 @@ func (_u *PetUpdateOne) sqlSave(ctx context.Context) (_node *Pet, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/multischema/ent/user_update.go b/entc/integration/multischema/ent/user_update.go index 645d4f4006..f79e0467c4 100644 --- a/entc/integration/multischema/ent/user_update.go +++ b/entc/integration/multischema/ent/user_update.go @@ -717,7 +717,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { ctx = internal.NewSchemaConfigContext(ctx, _u.schemaConfig) _spec.AddModifiers(_u.modifiers...) if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -1450,7 +1450,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/multischema/versioned/client.go b/entc/integration/multischema/versioned/client.go index 95f3b4cbc3..5c487bf289 100644 --- a/entc/integration/multischema/versioned/client.go +++ b/entc/integration/multischema/versioned/client.go @@ -121,7 +121,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/entc/integration/multischema/versioned/friendship_update.go b/entc/integration/multischema/versioned/friendship_update.go index e457f36f90..65088a2de2 100644 --- a/entc/integration/multischema/versioned/friendship_update.go +++ b/entc/integration/multischema/versioned/friendship_update.go @@ -143,7 +143,7 @@ func (_u *FriendshipUpdate) sqlSave(ctx context.Context) (_node int, err error) ctx = internal.NewSchemaConfigContext(ctx, _u.schemaConfig) _spec.AddModifiers(_u.modifiers...) if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{friendship.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -305,7 +305,7 @@ func (_u *FriendshipUpdateOne) sqlSave(ctx context.Context) (_node *Friendship, _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{friendship.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/multischema/versioned/group_update.go b/entc/integration/multischema/versioned/group_update.go index cabcc525c8..0e53fb3edf 100644 --- a/entc/integration/multischema/versioned/group_update.go +++ b/entc/integration/multischema/versioned/group_update.go @@ -186,7 +186,7 @@ func (_u *GroupUpdate) sqlSave(ctx context.Context) (_node int, err error) { ctx = internal.NewSchemaConfigContext(ctx, _u.schemaConfig) _spec.AddModifiers(_u.modifiers...) if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -391,7 +391,7 @@ func (_u *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error) _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/multischema/versioned/pet_update.go b/entc/integration/multischema/versioned/pet_update.go index 8558b557c8..a5dc00c714 100644 --- a/entc/integration/multischema/versioned/pet_update.go +++ b/entc/integration/multischema/versioned/pet_update.go @@ -164,7 +164,7 @@ func (_u *PetUpdate) sqlSave(ctx context.Context) (_node int, err error) { ctx = internal.NewSchemaConfigContext(ctx, _u.schemaConfig) _spec.AddModifiers(_u.modifiers...) if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -347,7 +347,7 @@ func (_u *PetUpdateOne) sqlSave(ctx context.Context) (_node *Pet, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/multischema/versioned/user_update.go b/entc/integration/multischema/versioned/user_update.go index 6f03c5080f..fae66e6e56 100644 --- a/entc/integration/multischema/versioned/user_update.go +++ b/entc/integration/multischema/versioned/user_update.go @@ -620,7 +620,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { ctx = internal.NewSchemaConfigContext(ctx, _u.schemaConfig) _spec.AddModifiers(_u.modifiers...) if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -1257,7 +1257,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/privacy/ent/client.go b/entc/integration/privacy/ent/client.go index 47091c9b3a..1b04e73291 100644 --- a/entc/integration/privacy/ent/client.go +++ b/entc/integration/privacy/ent/client.go @@ -122,7 +122,7 @@ func HTTPClient(v *http.Client) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/entc/integration/privacy/ent/task_update.go b/entc/integration/privacy/ent/task_update.go index 1b4d68bbec..da1538b263 100644 --- a/entc/integration/privacy/ent/task_update.go +++ b/entc/integration/privacy/ent/task_update.go @@ -315,7 +315,7 @@ func (_u *TaskUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{task.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -648,7 +648,7 @@ func (_u *TaskUpdateOne) sqlSave(ctx context.Context) (_node *Task, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{task.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/privacy/ent/team_update.go b/entc/integration/privacy/ent/team_update.go index 14ec9bc5f0..27e0f4d31e 100644 --- a/entc/integration/privacy/ent/team_update.go +++ b/entc/integration/privacy/ent/team_update.go @@ -267,7 +267,7 @@ func (_u *TeamUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{team.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -553,7 +553,7 @@ func (_u *TeamUpdateOne) sqlSave(ctx context.Context) (_node *Team, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{team.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/privacy/ent/user_update.go b/entc/integration/privacy/ent/user_update.go index 39dcf6f7a9..9077f2b0ec 100644 --- a/entc/integration/privacy/ent/user_update.go +++ b/entc/integration/privacy/ent/user_update.go @@ -273,7 +273,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -565,7 +565,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/relation_test.go b/entc/integration/relation_test.go index 9350d6d060..9c852230f8 100644 --- a/entc/integration/relation_test.go +++ b/entc/integration/relation_test.go @@ -10,6 +10,7 @@ import ( "testing" "time" + "entgo.io/ent/dialect" "entgo.io/ent/entc/integration/ent" "entgo.io/ent/entc/integration/ent/card" "entgo.io/ent/entc/integration/ent/group" @@ -166,6 +167,12 @@ func O2OSameType(t *testing.T, client *ent.Client) { require.Equal(2, client.Node.Query().CountX(ctx), "linked-list should have 2 nodes") t.Log("delete assoc should delete inverse edge") + + // YDB doesn't have FK constraints, manually clear reference before delete. + if client.Dialect() == dialect.YDB { + sec.Update().ClearPrev().ExecX(ctx) + } + client.Node.DeleteOne(head).ExecX(ctx) require.Zero(sec.QueryPrev().CountX(ctx), "second node should be the head now") require.Zero(sec.QueryNext().CountX(ctx), "second node should be the head now") @@ -245,16 +252,24 @@ func O2OSameType(t *testing.T, client *ent.Client) { require.Zero(head.QueryNext().QueryNext().Where(node.ValueGT(10)).QueryNext().QueryNext().QueryNext().CountX(ctx)) t.Log("delete all nodes except the head") + + // YDB doesn't have FK constraints, clear stale reference before delete. + if client.Dialect() == dialect.YDB { + head.Update().ClearNext().ExecX(ctx) + } + client.Node.Delete().Where(node.ValueGT(1)).ExecX(ctx) head = client.Node.Query().OnlyX(ctx) - t.Log("node points to itself (circular linked-list with 1 node)") - head.Update().SetNext(head).SaveX(ctx) - require.Equal(head.ID, head.QueryPrev().OnlyIDX(ctx)) - require.Equal(head.ID, head.QueryNext().OnlyIDX(ctx)) - head.Update().ClearNext().SaveX(ctx) - require.Zero(head.QueryPrev().CountX(ctx)) - require.Zero(head.QueryNext().CountX(ctx)) + if client.Dialect() != dialect.YDB { + t.Log("node points to itself (circular linked-list with 1 node)") + head.Update().SetNext(head).SaveX(ctx) + require.Equal(head.ID, head.QueryPrev().OnlyIDX(ctx)) + require.Equal(head.ID, head.QueryNext().OnlyIDX(ctx)) + head.Update().ClearNext().SaveX(ctx) + require.Zero(head.QueryPrev().CountX(ctx)) + require.Zero(head.QueryNext().CountX(ctx)) + } } // Demonstrate a O2O relation between two instances of the same type, where the relation @@ -785,6 +800,12 @@ func M2MSelfRef(t *testing.T, client *ent.Client) { require.Equal(2, client.User.Query().Where(user.HasFriends()).CountX(ctx)) t.Log("delete inverse should delete association") + + // YDB doesn't have FK constraints, manually clear references before delete. + if client.Dialect() == dialect.YDB { + bar.Update().ClearFriends().ExecX(ctx) + } + client.User.DeleteOne(bar).ExecX(ctx) require.False(foo.QueryFriends().ExistX(ctx)) require.Zero(client.User.Query().Where(user.HasFriends()).CountX(ctx)) @@ -925,6 +946,12 @@ func M2MSameType(t *testing.T, client *ent.Client) { require.Equal(1, client.User.Query().Where(user.HasFollowing()).CountX(ctx)) t.Log("delete inverse should delete association") + + // YDB doesn't have FK constraints, manually clear M2M references before delete. + if client.Dialect() == dialect.YDB { + bar.Update().ClearFollowing().ExecX(ctx) + } + client.User.DeleteOne(bar).ExecX(ctx) require.False(foo.QueryFollowers().ExistX(ctx)) require.Zero(client.User.Query().Where(user.HasFollowers()).CountX(ctx)) @@ -1067,6 +1094,12 @@ func M2MTwoTypes(t *testing.T, client *ent.Client) { require.Equal(1, hub.QueryUsers().CountX(ctx)) t.Log("delete inverse should delete association") + + // YDB doesn't have FK constraints, manually clear M2M references before delete. + if client.Dialect() == dialect.YDB { + hub.Update().ClearUsers().ExecX(ctx) + } + client.Group.DeleteOne(hub).ExecX(ctx) require.False(foo.QueryGroups().ExistX(ctx)) require.Zero(client.User.Query().Where(user.HasGroups()).CountX(ctx)) @@ -1082,6 +1115,12 @@ func M2MTwoTypes(t *testing.T, client *ent.Client) { require.Equal(1, client.Group.Query().Where(group.HasUsers()).CountX(ctx)) t.Log("delete assoc should delete inverse as well") + + // YDB doesn't have FK constraints, manually clear M2M references before delete. + if client.Dialect() == dialect.YDB { + foo.Update().ClearGroups().ExecX(ctx) + } + client.User.DeleteOne(foo).ExecX(ctx) require.False(hub.QueryUsers().ExistX(ctx)) require.Zero(client.User.Query().Where(user.HasGroups()).CountX(ctx)) diff --git a/entc/integration/template/ent/client.go b/entc/integration/template/ent/client.go index e15974b4c6..53b649d131 100644 --- a/entc/integration/template/ent/client.go +++ b/entc/integration/template/ent/client.go @@ -126,7 +126,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/entc/integration/template/ent/group_update.go b/entc/integration/template/ent/group_update.go index d6c4a378d9..171d46aeda 100644 --- a/entc/integration/template/ent/group_update.go +++ b/entc/integration/template/ent/group_update.go @@ -100,7 +100,7 @@ func (_u *GroupUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.AddField(group.FieldMaxUsers, field.TypeInt, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -221,7 +221,7 @@ func (_u *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error) _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/template/ent/pet_update.go b/entc/integration/template/ent/pet_update.go index e6ce0b1534..99b4f4ebca 100644 --- a/entc/integration/template/ent/pet_update.go +++ b/entc/integration/template/ent/pet_update.go @@ -182,7 +182,7 @@ func (_u *PetUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -383,7 +383,7 @@ func (_u *PetUpdateOne) sqlSave(ctx context.Context) (_node *Pet, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/template/ent/user_update.go b/entc/integration/template/ent/user_update.go index 2568ab7fc4..41785f204b 100644 --- a/entc/integration/template/ent/user_update.go +++ b/entc/integration/template/ent/user_update.go @@ -253,7 +253,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -526,7 +526,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/entc/integration/type_test.go b/entc/integration/type_test.go index 62c0693d1a..611a441ddb 100644 --- a/entc/integration/type_test.go +++ b/entc/integration/type_test.go @@ -13,6 +13,7 @@ import ( "testing" "time" + "entgo.io/ent/dialect" "entgo.io/ent/dialect/sql" "entgo.io/ent/entc/integration/ent" "entgo.io/ent/entc/integration/ent/fieldtype" @@ -105,7 +106,7 @@ func Types(t *testing.T, client *ent.Client) { require.Equal(role.Admin, ft.Role) require.Equal(role.High, ft.Priority) require.NoError(err) - dt, err := time.Parse(time.RFC3339, "1906-01-02T00:00:00+00:00") + dt, err := time.Parse(time.RFC3339, "1976-01-02T00:00:00+00:00") require.NoError(err) require.Equal(schema.Pair{K: []byte("K"), V: []byte("V")}, ft.Pair) require.Equal(&schema.Pair{K: []byte("K"), V: []byte("V")}, ft.NilPair) @@ -120,12 +121,15 @@ func Types(t *testing.T, client *ent.Client) { require.Equal("127.0.0.1", ft.LinkOtherFunc.String()) require.False(ft.DeletedAt.Time.IsZero()) - ft = client.FieldType.UpdateOne(ft).AddOptionalUint64(10).SaveX(ctx) - require.EqualValues(10, ft.OptionalUint64) - ft = client.FieldType.UpdateOne(ft).AddOptionalUint64(20).SetOptionalUint64(5).SaveX(ctx) - require.EqualValues(5, ft.OptionalUint64) - ft = client.FieldType.UpdateOne(ft).AddOptionalUint64(-5).SaveX(ctx) - require.Zero(ft.OptionalUint64) + // YDB: Add operations on unsigned fields use int64 values, but YDB requires exact type match. + if client.Dialect() != dialect.YDB { + ft = client.FieldType.UpdateOne(ft).AddOptionalUint64(10).SaveX(ctx) + require.EqualValues(10, ft.OptionalUint64) + ft = client.FieldType.UpdateOne(ft).AddOptionalUint64(20).SetOptionalUint64(5).SaveX(ctx) + require.EqualValues(5, ft.OptionalUint64) + ft = client.FieldType.UpdateOne(ft).AddOptionalUint64(-5).SaveX(ctx) + require.Zero(ft.OptionalUint64) + } err = client.FieldType.Create(). SetInt(1). @@ -136,6 +140,7 @@ func Types(t *testing.T, client *ent.Client) { SetRawData(make([]byte, 40)). Exec(ctx) require.Error(err, "MaxLen validator should reject this operation") + err = client.FieldType.Create(). SetInt(1). SetInt8(8). @@ -145,7 +150,8 @@ func Types(t *testing.T, client *ent.Client) { SetRawData(make([]byte, 2)). Exec(ctx) require.Error(err, "MinLen validator should reject this operation") - ft = ft.Update(). + + ftUpdate := ft.Update(). SetInt(1). SetInt8(math.MaxInt8). SetInt16(math.MaxInt16). @@ -173,9 +179,13 @@ func Types(t *testing.T, client *ent.Client) { SetMAC(schema.MAC{HardwareAddr: mac}). SetPair(schema.Pair{K: []byte("K1"), V: []byte("V1")}). SetNilPair(&schema.Pair{K: []byte("K1"), V: []byte("V1")}). - SetStringArray([]string{"qux"}). - AddBigInt(bigint). - SaveX(ctx) + SetStringArray([]string{"qux"}) + + // YDB: big_int is stored as Utf8, so Add operation doesn't work + if client.Dialect() != dialect.YDB { + ftUpdate.AddBigInt(bigint) + } + ft = ftUpdate.SaveX(ctx) require.Equal(int8(math.MaxInt8), ft.OptionalInt8) require.Equal(int16(math.MaxInt16), ft.OptionalInt16) @@ -204,7 +214,11 @@ func Types(t *testing.T, client *ent.Client) { require.EqualValues([]string{"qux"}, ft.StringArray) require.Nil(ft.NillableUUID) require.Equal(uuid.UUID{}, ft.OptionalUUID) - require.Equal("2000", ft.BigInt.String()) + + if client.Dialect() != dialect.YDB { + require.Equal("2000", ft.BigInt.String()) + } + require.EqualValues(100, ft.Int64, "UpdateDefault sets the value to 100") require.EqualValues(100, ft.Duration, "UpdateDefault sets the value to 100ns") require.False(ft.DeletedAt.Time.IsZero()) @@ -215,6 +229,7 @@ func Types(t *testing.T, client *ent.Client) { client.Task.Create().SetPriority(task.PriorityHigh), ).Exec(ctx) require.NoError(err) + err = client.Task.Create().SetPriority(task.Priority(10)).Exec(ctx) require.Error(err) diff --git a/examples/compositetypes/ent/client.go b/examples/compositetypes/ent/client.go index fb5d416157..111ea08388 100644 --- a/examples/compositetypes/ent/client.go +++ b/examples/compositetypes/ent/client.go @@ -99,7 +99,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/compositetypes/ent/user_update.go b/examples/compositetypes/ent/user_update.go index 94ae237943..c912340f5a 100644 --- a/examples/compositetypes/ent/user_update.go +++ b/examples/compositetypes/ent/user_update.go @@ -79,7 +79,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(user.FieldAddress, field.TypeString, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -182,7 +182,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/domaintypes/ent/client.go b/examples/domaintypes/ent/client.go index 205c437fad..2cdd5ab688 100644 --- a/examples/domaintypes/ent/client.go +++ b/examples/domaintypes/ent/client.go @@ -99,7 +99,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/domaintypes/ent/user_update.go b/examples/domaintypes/ent/user_update.go index 0d5c45d56b..54dd7440c3 100644 --- a/examples/domaintypes/ent/user_update.go +++ b/examples/domaintypes/ent/user_update.go @@ -86,7 +86,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(user.FieldPostalCode, field.TypeString, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -197,7 +197,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/edgeindex/ent/city_update.go b/examples/edgeindex/ent/city_update.go index 8c699557a0..3312f09b2b 100644 --- a/examples/edgeindex/ent/city_update.go +++ b/examples/edgeindex/ent/city_update.go @@ -172,7 +172,7 @@ func (_u *CityUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{city.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -364,7 +364,7 @@ func (_u *CityUpdateOne) sqlSave(ctx context.Context) (_node *City, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{city.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/edgeindex/ent/client.go b/examples/edgeindex/ent/client.go index d076f8201d..e29d298e53 100644 --- a/examples/edgeindex/ent/client.go +++ b/examples/edgeindex/ent/client.go @@ -108,7 +108,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/edgeindex/ent/street_update.go b/examples/edgeindex/ent/street_update.go index a873b6a451..0ffeda9aae 100644 --- a/examples/edgeindex/ent/street_update.go +++ b/examples/edgeindex/ent/street_update.go @@ -145,7 +145,7 @@ func (_u *StreetUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{street.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -310,7 +310,7 @@ func (_u *StreetUpdateOne) sqlSave(ctx context.Context) (_node *Street, err erro _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{street.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/encryptfield/ent/client.go b/examples/encryptfield/ent/client.go index 0d9cfbde4c..d6b576a4a4 100644 --- a/examples/encryptfield/ent/client.go +++ b/examples/encryptfield/ent/client.go @@ -112,7 +112,7 @@ func SecretsKeeper(v *secrets.Keeper) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/encryptfield/ent/user_update.go b/examples/encryptfield/ent/user_update.go index feb05ea113..b14269ec6a 100644 --- a/examples/encryptfield/ent/user_update.go +++ b/examples/encryptfield/ent/user_update.go @@ -116,7 +116,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(user.FieldNickname, field.TypeString, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -253,7 +253,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/entcpkg/ent/client.go b/examples/entcpkg/ent/client.go index dfde64daa0..b7b79e5e99 100644 --- a/examples/entcpkg/ent/client.go +++ b/examples/entcpkg/ent/client.go @@ -122,7 +122,7 @@ func Writer(v io.Writer) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/entcpkg/ent/user_update.go b/examples/entcpkg/ent/user_update.go index b261f4dad6..b3431f8d3c 100644 --- a/examples/entcpkg/ent/user_update.go +++ b/examples/entcpkg/ent/user_update.go @@ -135,7 +135,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.ClearField(user.FieldAge, field.TypeInt) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -291,7 +291,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/enumtypes/ent/client.go b/examples/enumtypes/ent/client.go index 0b08f4cfc8..49481310f8 100644 --- a/examples/enumtypes/ent/client.go +++ b/examples/enumtypes/ent/client.go @@ -99,7 +99,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/enumtypes/ent/user_update.go b/examples/enumtypes/ent/user_update.go index ceea7339a1..f27d6958f7 100644 --- a/examples/enumtypes/ent/user_update.go +++ b/examples/enumtypes/ent/user_update.go @@ -99,7 +99,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(user.FieldStatus, field.TypeEnum, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -223,7 +223,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/extensions/ent/client.go b/examples/extensions/ent/client.go index b02d53c6ec..7779fa3a25 100644 --- a/examples/extensions/ent/client.go +++ b/examples/extensions/ent/client.go @@ -99,7 +99,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/extensions/ent/user_update.go b/examples/extensions/ent/user_update.go index 8bf932553b..7590d70ad4 100644 --- a/examples/extensions/ent/user_update.go +++ b/examples/extensions/ent/user_update.go @@ -78,7 +78,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(user.FieldLocation, field.TypeBytes, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -181,7 +181,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/fs/ent/client.go b/examples/fs/ent/client.go index 31c33c4669..e4e3ccc00a 100644 --- a/examples/fs/ent/client.go +++ b/examples/fs/ent/client.go @@ -104,7 +104,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/fs/ent/file_update.go b/examples/fs/ent/file_update.go index 93f62564ff..9b5fd09b92 100644 --- a/examples/fs/ent/file_update.go +++ b/examples/fs/ent/file_update.go @@ -248,7 +248,7 @@ func (_u *FileUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{file.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -517,7 +517,7 @@ func (_u *FileUpdateOne) sqlSave(ctx context.Context) (_node *File, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{file.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/functionalidx/ent/client.go b/examples/functionalidx/ent/client.go index 678aa3dfb7..4252d58b29 100644 --- a/examples/functionalidx/ent/client.go +++ b/examples/functionalidx/ent/client.go @@ -99,7 +99,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/functionalidx/ent/user_update.go b/examples/functionalidx/ent/user_update.go index 98c80838b0..4a8bfdaec7 100644 --- a/examples/functionalidx/ent/user_update.go +++ b/examples/functionalidx/ent/user_update.go @@ -86,7 +86,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(user.FieldName, field.TypeString, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -197,7 +197,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/go.mod b/examples/go.mod index 345c216eaa..c4d345a263 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -1,8 +1,6 @@ module entgo.io/ent/examples -go 1.24 - -toolchain go1.24.0 +go 1.24.13 replace entgo.io/ent => ../ @@ -10,10 +8,11 @@ require ( ariga.io/atlas v0.36.2-0.20250730182955-2c6300d0a3e1 ariga.io/atlas-go-sdk v0.6.9 entgo.io/ent v0.0.0-00010101000000-000000000000 - github.com/google/uuid v1.3.0 + github.com/google/uuid v1.6.0 github.com/lib/pq v1.10.7 github.com/mattn/go-sqlite3 v1.14.28 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.11.1 + github.com/ydb-platform/ydb-go-sdk/v3 v3.125.4 gocloud.dev v0.28.0 ) @@ -23,25 +22,30 @@ require ( github.com/bmatcuk/doublestar v1.3.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-openapi/inflect v0.19.0 // indirect + github.com/golang-jwt/jwt/v4 v4.5.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/googleapis/gax-go/v2 v2.7.0 // indirect github.com/hashicorp/hcl/v2 v2.18.1 // indirect + github.com/jonboulle/clockwork v0.5.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/ydb-platform/ydb-go-genproto v0.0.0-20251222105147-0bf751469a4a // indirect github.com/zclconf/go-cty v1.14.4 // indirect github.com/zclconf/go-cty-yaml v1.1.0 // indirect go.opencensus.io v0.24.0 // indirect - golang.org/x/crypto v0.3.0 // indirect - golang.org/x/mod v0.24.0 // indirect - golang.org/x/net v0.6.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/crypto v0.46.0 // indirect + golang.org/x/mod v0.30.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/sync v0.19.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/text v0.32.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/api v0.103.0 // indirect google.golang.org/genproto v0.0.0-20221201204527-e3fa12d562f3 // indirect - google.golang.org/grpc v1.51.0 // indirect - google.golang.org/protobuf v1.28.1 // indirect + google.golang.org/grpc v1.78.0 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) + +replace ariga.io/atlas => github.com/ydb-platform/ariga-atlas v0.0.1 diff --git a/examples/go.sum b/examples/go.sum index 87bdf12f86..0d320bb6ae 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -1,5 +1,3 @@ -ariga.io/atlas v0.36.2-0.20250730182955-2c6300d0a3e1 h1:NPPfBaVZgz4LKBCIc0FbMogCjvXN+yGf7CZwotOwJo8= -ariga.io/atlas v0.36.2-0.20250730182955-2c6300d0a3e1/go.mod h1:Ex5l1xHsnWQUc3wYnrJ9gD7RUEzG76P7ZRQp8wNr0wc= ariga.io/atlas-go-sdk v0.6.9 h1:G5OajpcSIrLRMz8VfmMdfkNptlGstiK0zQ0dtuZWBaE= ariga.io/atlas-go-sdk v0.6.9/go.mod h1:cFq7bnvHgKTWHCsU46mtkGxdl41rx2o7SjaLoh6cO8M= bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= @@ -124,8 +122,9 @@ cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARy cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= -cloud.google.com/go/compute/metadata v0.2.2 h1:aWKAjYaBaOSrpKl57+jnS/3fJRQnxL7TvR/u1VVbt6k= cloud.google.com/go/compute/metadata v0.2.2/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= +cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= +cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY= cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck= cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg= @@ -851,7 +850,10 @@ github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= @@ -952,6 +954,8 @@ github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzw github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= +github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -988,8 +992,9 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -1013,8 +1018,8 @@ github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= @@ -1054,8 +1059,9 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8= github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU= github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= @@ -1232,6 +1238,8 @@ github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52Cu github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I= +github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -1554,6 +1562,8 @@ github.com/prometheus/prometheus v0.40.5/go.mod h1:bxgdmtoSNLmmIVPGmeTJ3OiP67Vmu github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rakyll/embedmd v0.0.0-20171029212350-c8060a0752a2/go.mod h1:7jOTMgqac46PZcF54q6l2hkLEG8op93fZu61KmxWDV4= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rekby/fixenv v0.6.1 h1:jUFiSPpajT4WY2cYuc++7Y1zWrnCxnovGCIX72PZniM= +github.com/rekby/fixenv v0.6.1/go.mod h1:/b5LRc06BYJtslRtHKxsPWFT/ySpHV+rWvzTg+XWk4c= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -1642,8 +1652,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= @@ -1685,6 +1695,12 @@ github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/ydb-platform/ariga-atlas v0.0.1 h1:atWj2dpOKWIZ6sR0NVQrZDIJ40k85gkZ/7D7opqlCW0= +github.com/ydb-platform/ariga-atlas v0.0.1/go.mod h1:t5BRX5MhK+I0vLdUMeUBOz1x2uNP/FYejPLUBcsCWcw= +github.com/ydb-platform/ydb-go-genproto v0.0.0-20251222105147-0bf751469a4a h1:nRqONRrMFulP2bTWM2RRnPM1VDhWuBZg4ULXkG4xXdk= +github.com/ydb-platform/ydb-go-genproto v0.0.0-20251222105147-0bf751469a4a/go.mod h1:Er+FePu1dNUieD+XTMDduGpQuCPssK5Q4BjF+IIXJ3I= +github.com/ydb-platform/ydb-go-sdk/v3 v3.125.4 h1:GAC7qeNgsibEJkUVzV4z06aBnHR4jqfXsFiQtrY40gI= +github.com/ydb-platform/ydb-go-sdk/v3 v3.125.4/go.mod h1:stS1mQYjbJvwwYaYzKyFY9eMiuVXWWXQA6T+SpOLg9c= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1732,6 +1748,8 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0/go.mod h1:vEhqr0m4eTc+DWxfsXoXue2GBgV2uUwVznkGIHW/e5w= @@ -1743,6 +1761,8 @@ go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVj go.opentelemetry.io/otel v1.6.0/go.mod h1:bfJD2DZVw0LBxghOTlgnlI0CV3hLDu9XF/QKOUXMTQQ= go.opentelemetry.io/otel v1.6.1/go.mod h1:blzUabWHkX6LJewxvadmzafgh/wnvBSDBdOuwkAtrWQ= go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.6.1/go.mod h1:NEu79Xo32iVb+0gVNV8PMd7GoWqnyDXRlj04yFjqz40= @@ -1759,18 +1779,26 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.11.1/go.mod h go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= go.opentelemetry.io/otel/metric v0.28.0/go.mod h1:TrzsfQAmQaB1PDcdhBauLMk7nyyg9hm+GoQq/ekE9Iw= go.opentelemetry.io/otel/metric v0.33.0/go.mod h1:QlTYc+EnYNq/M2mNk1qDDMRLpqCOj2f/r5c7Fd5FYaI= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs= go.opentelemetry.io/otel/sdk v1.6.1/go.mod h1:IVYrddmFZ+eJqu2k38qD3WezFR2pymCzm8tdxyh3R4E= go.opentelemetry.io/otel/sdk v1.11.1/go.mod h1:/l3FE4SupHJ12TduVjUkZtlfFqDCQJlOlithYrdktys= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk= go.opentelemetry.io/otel/trace v1.6.0/go.mod h1:qs7BrU5cZ8dXQHBGxHMOxwME/27YH2qEp4/+tZLLwJE= go.opentelemetry.io/otel/trace v1.6.1/go.mod h1:RkFRM1m0puWIq10oxImnGEduNBzxiN7TXluRBtE+5j0= go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ= go.opentelemetry.io/proto/otlp v0.12.1/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= @@ -1788,6 +1816,8 @@ go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -1838,8 +1868,9 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20221012134737-56aed061732a/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -golang.org/x/crypto v0.3.0 h1:a06MkbcxBrEFc0w0QIZWXrH/9cCX6KJyWbBOIwAn+7A= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= +golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1881,8 +1912,8 @@ golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= -golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= -golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= +golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1966,8 +1997,8 @@ golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfS golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= -golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1996,8 +2027,9 @@ golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= -golang.org/x/oauth2 v0.2.0 h1:GtQkldQ9m7yvzCL1V+LrYow3Khe0eJH0w7RbX/VbaIU= golang.org/x/oauth2 v0.2.0/go.mod h1:Cwn6afJ8jrQwYMxQDTpISoXmXW9I6qF6vDeuuoX3Ibs= +golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY= +golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -2014,6 +2046,8 @@ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -2164,8 +2198,8 @@ golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -2186,8 +2220,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -2296,6 +2330,8 @@ golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNq golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= @@ -2530,8 +2566,9 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= +google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= +google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -2547,8 +2584,9 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/examples/jsonencode/ent/card_update.go b/examples/jsonencode/ent/card_update.go index 8bf90f7a58..10e9beae09 100644 --- a/examples/jsonencode/ent/card_update.go +++ b/examples/jsonencode/ent/card_update.go @@ -90,7 +90,7 @@ func (_u *CardUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(card.FieldNumber, field.TypeString, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{card.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -201,7 +201,7 @@ func (_u *CardUpdateOne) sqlSave(ctx context.Context) (_node *Card, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{card.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/jsonencode/ent/client.go b/examples/jsonencode/ent/client.go index 77ee8dfb9e..22d485921d 100644 --- a/examples/jsonencode/ent/client.go +++ b/examples/jsonencode/ent/client.go @@ -112,7 +112,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/jsonencode/ent/pet_update.go b/examples/jsonencode/ent/pet_update.go index eae40a1039..9a382820b5 100644 --- a/examples/jsonencode/ent/pet_update.go +++ b/examples/jsonencode/ent/pet_update.go @@ -183,7 +183,7 @@ func (_u *PetUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -386,7 +386,7 @@ func (_u *PetUpdateOne) sqlSave(ctx context.Context) (_node *Pet, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/jsonencode/ent/user_update.go b/examples/jsonencode/ent/user_update.go index fd527dc2b1..55b27fdebd 100644 --- a/examples/jsonencode/ent/user_update.go +++ b/examples/jsonencode/ent/user_update.go @@ -199,7 +199,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -418,7 +418,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/m2m2types/ent/client.go b/examples/m2m2types/ent/client.go index 9704c44664..006739841f 100644 --- a/examples/m2m2types/ent/client.go +++ b/examples/m2m2types/ent/client.go @@ -108,7 +108,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/m2m2types/ent/group_update.go b/examples/m2m2types/ent/group_update.go index 36b5fffafc..ebf7f7560e 100644 --- a/examples/m2m2types/ent/group_update.go +++ b/examples/m2m2types/ent/group_update.go @@ -172,7 +172,7 @@ func (_u *GroupUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -364,7 +364,7 @@ func (_u *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error) _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/m2m2types/ent/user_update.go b/examples/m2m2types/ent/user_update.go index 3c64135966..f438a108a4 100644 --- a/examples/m2m2types/ent/user_update.go +++ b/examples/m2m2types/ent/user_update.go @@ -199,7 +199,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -418,7 +418,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/m2mbidi/ent/client.go b/examples/m2mbidi/ent/client.go index 51bb71efca..33bd37734d 100644 --- a/examples/m2mbidi/ent/client.go +++ b/examples/m2mbidi/ent/client.go @@ -104,7 +104,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/m2mbidi/ent/user_update.go b/examples/m2mbidi/ent/user_update.go index e4ed61b23f..ecb52cf9bd 100644 --- a/examples/m2mbidi/ent/user_update.go +++ b/examples/m2mbidi/ent/user_update.go @@ -198,7 +198,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -417,7 +417,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/m2mrecur/ent/client.go b/examples/m2mrecur/ent/client.go index 9ee17212e3..cfe203599c 100644 --- a/examples/m2mrecur/ent/client.go +++ b/examples/m2mrecur/ent/client.go @@ -104,7 +104,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/m2mrecur/ent/user_update.go b/examples/m2mrecur/ent/user_update.go index 16b2e8b7d5..e459d45ee1 100644 --- a/examples/m2mrecur/ent/user_update.go +++ b/examples/m2mrecur/ent/user_update.go @@ -279,7 +279,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -579,7 +579,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/migration/ent/card_update.go b/examples/migration/ent/card_update.go index 56b6590815..1e1c0b3126 100644 --- a/examples/migration/ent/card_update.go +++ b/examples/migration/ent/card_update.go @@ -299,7 +299,7 @@ func (_u *CardUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{card.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -616,7 +616,7 @@ func (_u *CardUpdateOne) sqlSave(ctx context.Context) (_node *Card, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{card.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/migration/ent/client.go b/examples/migration/ent/client.go index b9391670bd..1c9e618d05 100644 --- a/examples/migration/ent/client.go +++ b/examples/migration/ent/client.go @@ -125,7 +125,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/migration/ent/payment_update.go b/examples/migration/ent/payment_update.go index 2a317186ae..b7790634bd 100644 --- a/examples/migration/ent/payment_update.go +++ b/examples/migration/ent/payment_update.go @@ -250,7 +250,7 @@ func (_u *PaymentUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{payment.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -519,7 +519,7 @@ func (_u *PaymentUpdateOne) sqlSave(ctx context.Context) (_node *Payment, err er _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{payment.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/migration/ent/pet_update.go b/examples/migration/ent/pet_update.go index 3d47cb2cab..68826c8c76 100644 --- a/examples/migration/ent/pet_update.go +++ b/examples/migration/ent/pet_update.go @@ -268,7 +268,7 @@ func (_u *PetUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -555,7 +555,7 @@ func (_u *PetUpdateOne) sqlSave(ctx context.Context) (_node *Pet, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/migration/ent/session_update.go b/examples/migration/ent/session_update.go index dc0387bc66..9107139bc3 100644 --- a/examples/migration/ent/session_update.go +++ b/examples/migration/ent/session_update.go @@ -240,7 +240,7 @@ func (_u *SessionUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{session.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -498,7 +498,7 @@ func (_u *SessionUpdateOne) sqlSave(ctx context.Context) (_node *Session, err er _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{session.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/migration/ent/sessiondevice_update.go b/examples/migration/ent/sessiondevice_update.go index 6402849898..10cb43d66c 100644 --- a/examples/migration/ent/sessiondevice_update.go +++ b/examples/migration/ent/sessiondevice_update.go @@ -274,7 +274,7 @@ func (_u *SessionDeviceUpdate) sqlSave(ctx context.Context) (_node int, err erro _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{sessiondevice.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -566,7 +566,7 @@ func (_u *SessionDeviceUpdateOne) sqlSave(ctx context.Context) (_node *SessionDe _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{sessiondevice.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/migration/ent/user_update.go b/examples/migration/ent/user_update.go index bda5dc1b95..b1d57b99e2 100644 --- a/examples/migration/ent/user_update.go +++ b/examples/migration/ent/user_update.go @@ -246,7 +246,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -511,7 +511,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/o2m2types/ent/client.go b/examples/o2m2types/ent/client.go index fcd9f865a4..b40c9d15af 100644 --- a/examples/o2m2types/ent/client.go +++ b/examples/o2m2types/ent/client.go @@ -108,7 +108,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/o2m2types/ent/pet_update.go b/examples/o2m2types/ent/pet_update.go index a484ea730b..c7a7268749 100644 --- a/examples/o2m2types/ent/pet_update.go +++ b/examples/o2m2types/ent/pet_update.go @@ -145,7 +145,7 @@ func (_u *PetUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -310,7 +310,7 @@ func (_u *PetUpdateOne) sqlSave(ctx context.Context) (_node *Pet, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/o2m2types/ent/user_update.go b/examples/o2m2types/ent/user_update.go index 408e640503..10f36051e2 100644 --- a/examples/o2m2types/ent/user_update.go +++ b/examples/o2m2types/ent/user_update.go @@ -199,7 +199,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -418,7 +418,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/o2mrecur/ent/client.go b/examples/o2mrecur/ent/client.go index 534ef5bc91..d9af9f9fe0 100644 --- a/examples/o2mrecur/ent/client.go +++ b/examples/o2mrecur/ent/client.go @@ -104,7 +104,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/o2mrecur/ent/node_update.go b/examples/o2mrecur/ent/node_update.go index 7813961463..8ae3520f69 100644 --- a/examples/o2mrecur/ent/node_update.go +++ b/examples/o2mrecur/ent/node_update.go @@ -241,7 +241,7 @@ func (_u *NodeUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{node.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -503,7 +503,7 @@ func (_u *NodeUpdateOne) sqlSave(ctx context.Context) (_node *Node, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{node.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/o2o2types/ent/card_update.go b/examples/o2o2types/ent/card_update.go index d216f6d845..ac75d00515 100644 --- a/examples/o2o2types/ent/card_update.go +++ b/examples/o2o2types/ent/card_update.go @@ -166,7 +166,7 @@ func (_u *CardUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{card.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -351,7 +351,7 @@ func (_u *CardUpdateOne) sqlSave(ctx context.Context) (_node *Card, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{card.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/o2o2types/ent/client.go b/examples/o2o2types/ent/client.go index 6c036fd847..47eeb4ff79 100644 --- a/examples/o2o2types/ent/client.go +++ b/examples/o2o2types/ent/client.go @@ -108,7 +108,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/o2o2types/ent/user_update.go b/examples/o2o2types/ent/user_update.go index 8a5a8920c0..e76a716526 100644 --- a/examples/o2o2types/ent/user_update.go +++ b/examples/o2o2types/ent/user_update.go @@ -172,7 +172,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -364,7 +364,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/o2obidi/ent/client.go b/examples/o2obidi/ent/client.go index 688c30f135..7bf54a7b49 100644 --- a/examples/o2obidi/ent/client.go +++ b/examples/o2obidi/ent/client.go @@ -104,7 +104,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/o2obidi/ent/user_update.go b/examples/o2obidi/ent/user_update.go index 3657ededa7..c0962e0d75 100644 --- a/examples/o2obidi/ent/user_update.go +++ b/examples/o2obidi/ent/user_update.go @@ -171,7 +171,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -363,7 +363,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/o2orecur/ent/client.go b/examples/o2orecur/ent/client.go index da01648ece..d59c8fb164 100644 --- a/examples/o2orecur/ent/client.go +++ b/examples/o2orecur/ent/client.go @@ -104,7 +104,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/o2orecur/ent/node_update.go b/examples/o2orecur/ent/node_update.go index db6e813034..cc0133510b 100644 --- a/examples/o2orecur/ent/node_update.go +++ b/examples/o2orecur/ent/node_update.go @@ -214,7 +214,7 @@ func (_u *NodeUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{node.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -449,7 +449,7 @@ func (_u *NodeUpdateOne) sqlSave(ctx context.Context) (_node *Node, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{node.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/privacyadmin/ent/client.go b/examples/privacyadmin/ent/client.go index 5d39e39555..56563164ba 100644 --- a/examples/privacyadmin/ent/client.go +++ b/examples/privacyadmin/ent/client.go @@ -103,7 +103,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/privacyadmin/ent/user_update.go b/examples/privacyadmin/ent/user_update.go index 526e1fd08c..ccf51929e1 100644 --- a/examples/privacyadmin/ent/user_update.go +++ b/examples/privacyadmin/ent/user_update.go @@ -90,7 +90,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(user.FieldName, field.TypeString, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -201,7 +201,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/privacytenant/ent/client.go b/examples/privacytenant/ent/client.go index 1cc37d7a01..7cfa81c1e6 100644 --- a/examples/privacytenant/ent/client.go +++ b/examples/privacytenant/ent/client.go @@ -112,7 +112,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/privacytenant/ent/group_update.go b/examples/privacytenant/ent/group_update.go index b4ffba47d1..d02fc9eb11 100644 --- a/examples/privacytenant/ent/group_update.go +++ b/examples/privacytenant/ent/group_update.go @@ -183,7 +183,7 @@ func (_u *GroupUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -386,7 +386,7 @@ func (_u *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error) _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/privacytenant/ent/tenant_update.go b/examples/privacytenant/ent/tenant_update.go index e46a1cd759..a33d88454d 100644 --- a/examples/privacytenant/ent/tenant_update.go +++ b/examples/privacytenant/ent/tenant_update.go @@ -103,7 +103,7 @@ func (_u *TenantUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(tenant.FieldName, field.TypeString, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{tenant.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -227,7 +227,7 @@ func (_u *TenantUpdateOne) sqlSave(ctx context.Context) (_node *Tenant, err erro _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{tenant.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/privacytenant/ent/user_update.go b/examples/privacytenant/ent/user_update.go index d489b9798d..453e2e1b21 100644 --- a/examples/privacytenant/ent/user_update.go +++ b/examples/privacytenant/ent/user_update.go @@ -213,7 +213,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -445,7 +445,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/rls/ent/client.go b/examples/rls/ent/client.go index 2a22d9a75c..9b9f04b01d 100644 --- a/examples/rls/ent/client.go +++ b/examples/rls/ent/client.go @@ -103,7 +103,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/rls/ent/tenant_update.go b/examples/rls/ent/tenant_update.go index ffd43c936b..1fd12dafce 100644 --- a/examples/rls/ent/tenant_update.go +++ b/examples/rls/ent/tenant_update.go @@ -86,7 +86,7 @@ func (_u *TenantUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(tenant.FieldName, field.TypeString, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{tenant.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -197,7 +197,7 @@ func (_u *TenantUpdateOne) sqlSave(ctx context.Context) (_node *Tenant, err erro _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{tenant.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/rls/ent/user_update.go b/examples/rls/ent/user_update.go index febb12153f..1be46f91b1 100644 --- a/examples/rls/ent/user_update.go +++ b/examples/rls/ent/user_update.go @@ -113,7 +113,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.AddField(user.FieldTenantID, field.TypeInt, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -251,7 +251,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/start/ent/car_update.go b/examples/start/ent/car_update.go index cff4720038..81160059ca 100644 --- a/examples/start/ent/car_update.go +++ b/examples/start/ent/car_update.go @@ -163,7 +163,7 @@ func (_u *CarUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{car.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -345,7 +345,7 @@ func (_u *CarUpdateOne) sqlSave(ctx context.Context) (_node *Car, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{car.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/start/ent/client.go b/examples/start/ent/client.go index b74da8d2dd..87fe18a838 100644 --- a/examples/start/ent/client.go +++ b/examples/start/ent/client.go @@ -112,7 +112,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/start/ent/group_update.go b/examples/start/ent/group_update.go index 6c7ac2484e..8172853be3 100644 --- a/examples/start/ent/group_update.go +++ b/examples/start/ent/group_update.go @@ -185,7 +185,7 @@ func (_u *GroupUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -390,7 +390,7 @@ func (_u *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error) _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/start/ent/user_update.go b/examples/start/ent/user_update.go index 62bc3fa48a..22fdbd3673 100644 --- a/examples/start/ent/user_update.go +++ b/examples/start/ent/user_update.go @@ -294,7 +294,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -607,7 +607,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/traversal/ent/client.go b/examples/traversal/ent/client.go index bfffe379e9..8cdf6e4df4 100644 --- a/examples/traversal/ent/client.go +++ b/examples/traversal/ent/client.go @@ -112,7 +112,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/traversal/ent/group_update.go b/examples/traversal/ent/group_update.go index f3f03010c2..79b7d56527 100644 --- a/examples/traversal/ent/group_update.go +++ b/examples/traversal/ent/group_update.go @@ -226,7 +226,7 @@ func (_u *GroupUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -472,7 +472,7 @@ func (_u *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error) _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{group.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/traversal/ent/pet_update.go b/examples/traversal/ent/pet_update.go index 887c4616ed..0bb15d2fa1 100644 --- a/examples/traversal/ent/pet_update.go +++ b/examples/traversal/ent/pet_update.go @@ -226,7 +226,7 @@ func (_u *PetUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -472,7 +472,7 @@ func (_u *PetUpdateOne) sqlSave(ctx context.Context) (_node *Pet, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/traversal/ent/user_update.go b/examples/traversal/ent/user_update.go index 918a18c783..6a52c2e60b 100644 --- a/examples/traversal/ent/user_update.go +++ b/examples/traversal/ent/user_update.go @@ -443,7 +443,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.Edges.Add = append(_spec.Edges.Add, edge) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -905,7 +905,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/triggers/ent/client.go b/examples/triggers/ent/client.go index 0d84c8e66b..d746d4c277 100644 --- a/examples/triggers/ent/client.go +++ b/examples/triggers/ent/client.go @@ -103,7 +103,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/triggers/ent/user_update.go b/examples/triggers/ent/user_update.go index b52b5c1cf7..2e60ec9618 100644 --- a/examples/triggers/ent/user_update.go +++ b/examples/triggers/ent/user_update.go @@ -86,7 +86,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(user.FieldName, field.TypeString, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -197,7 +197,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/triggers/ent/userauditlog_update.go b/examples/triggers/ent/userauditlog_update.go index 87c1e8a233..2a50a3b97e 100644 --- a/examples/triggers/ent/userauditlog_update.go +++ b/examples/triggers/ent/userauditlog_update.go @@ -155,7 +155,7 @@ func (_u *UserAuditLogUpdate) sqlSave(ctx context.Context) (_node int, err error _spec.ClearField(userauditlog.FieldNewValue, field.TypeString) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{userauditlog.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -335,7 +335,7 @@ func (_u *UserAuditLogUpdateOne) sqlSave(ctx context.Context) (_node *UserAuditL _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{userauditlog.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/version/ent/client.go b/examples/version/ent/client.go index a7e19b5699..36254a4059 100644 --- a/examples/version/ent/client.go +++ b/examples/version/ent/client.go @@ -103,7 +103,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/version/ent/user_update.go b/examples/version/ent/user_update.go index 7d2e021e88..1c639856ff 100644 --- a/examples/version/ent/user_update.go +++ b/examples/version/ent/user_update.go @@ -130,7 +130,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(user.FieldStatus, field.TypeEnum, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -281,7 +281,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/viewcomposite/ent/client.go b/examples/viewcomposite/ent/client.go index 826fed061d..6506dc312c 100644 --- a/examples/viewcomposite/ent/client.go +++ b/examples/viewcomposite/ent/client.go @@ -109,7 +109,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/viewcomposite/ent/pet_update.go b/examples/viewcomposite/ent/pet_update.go index c183e086a1..e2206af2c9 100644 --- a/examples/viewcomposite/ent/pet_update.go +++ b/examples/viewcomposite/ent/pet_update.go @@ -86,7 +86,7 @@ func (_u *PetUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(pet.FieldName, field.TypeString, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -197,7 +197,7 @@ func (_u *PetUpdateOne) sqlSave(ctx context.Context) (_node *Pet, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/viewcomposite/ent/user_update.go b/examples/viewcomposite/ent/user_update.go index 7dfa709faa..edfa9a7bf8 100644 --- a/examples/viewcomposite/ent/user_update.go +++ b/examples/viewcomposite/ent/user_update.go @@ -120,7 +120,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(user.FieldPrivateInfo, field.TypeString, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -265,7 +265,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/viewschema/ent/client.go b/examples/viewschema/ent/client.go index 4144b1d068..4f90deb307 100644 --- a/examples/viewschema/ent/client.go +++ b/examples/viewschema/ent/client.go @@ -109,7 +109,7 @@ func Driver(driver dialect.Driver) Option { // Optional parameters can be added for configuring the client. func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { switch driverName { - case dialect.MySQL, dialect.Postgres, dialect.SQLite: + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: drv, err := sql.Open(driverName, dataSourceName) if err != nil { return nil, err diff --git a/examples/viewschema/ent/pet_update.go b/examples/viewschema/ent/pet_update.go index 804ca24d9e..10b318abf9 100644 --- a/examples/viewschema/ent/pet_update.go +++ b/examples/viewschema/ent/pet_update.go @@ -86,7 +86,7 @@ func (_u *PetUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(pet.FieldName, field.TypeString, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -197,7 +197,7 @@ func (_u *PetUpdateOne) sqlSave(ctx context.Context) (_node *Pet, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{pet.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/viewschema/ent/user_update.go b/examples/viewschema/ent/user_update.go index 350c21b3f3..309f92cf5c 100644 --- a/examples/viewschema/ent/user_update.go +++ b/examples/viewschema/ent/user_update.go @@ -120,7 +120,7 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) { _spec.SetField(user.FieldPrivateInfo, field.TypeString, value) } if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} @@ -265,7 +265,7 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { _spec.Assign = _node.assignValues _spec.ScanValues = _node.scanValues if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { + if sqlgraph.IsNotFound(err) { err = &NotFoundError{user.Label} } else if sqlgraph.IsConstraintError(err) { err = &ConstraintError{msg: err.Error(), wrap: err} diff --git a/examples/ydb/README.md b/examples/ydb/README.md new file mode 100644 index 0000000000..81a1dee2b8 --- /dev/null +++ b/examples/ydb/README.md @@ -0,0 +1,59 @@ +# YDB Example + +This example demonstrates how to use ent with [YDB](https://ydb.tech/) database. + +## Prerequisites + +- Running YDB instance (local or remote) +- Go 1.22+ + +## Running YDB Locally + +You can run YDB locally using Docker: + +```bash +docker run -d --rm --name ydb-local \ + -p 2135:2135 -p 2136:2136 -p 8765:8765 \ + -e GRPC_TLS_PORT=2135 \ + -e GRPC_PORT=2136 \ + -e MON_PORT=8765 \ + -e YDB_USE_IN_MEMORY_PDISKS=true \ + cr.yandex/yc/yandex-docker-local-ydb:latest +``` + +## Key Features Demonstrated + +1. **YDB Driver** - Using the ent YDB driver with ydb-go-sdk +2. **Automatic Retries** - Using `WithRetryOptions()` for YDB-specific retry handling +3. **Schema Creation** - Creating tables in YDB using ent migrations +4. **CRUD Operations** - Create, Read, Update, Delete operations with YDB + +## Schema + +This example uses a simple TV series database with three entities: + +- **Series** - TV series (title, info, release date) +- **Season** - Seasons of a series (title, first/last aired dates) +- **Episode** - Episodes in a season (title, air date, duration) + +## Retry Handling + +YDB requires special retry handling for transient errors. The ent YDB driver +automatically handles retries using ydb-go-sdk's retry package. You can +customize retry behavior using `WithRetryOptions()`: + +```go +// Create with custom retry options +_, err := client.Series.Create(). + SetTitle("The Expanse"). + SetInfo("Humanity has colonized the solar system"). + SetReleaseDate(time.Date(2015, 12, 14, 0, 0, 0, 0, time.UTC)). + WithRetryOptions(retry.WithIdempotent(true)). + Save(ctx) + +// Query with retry options +series, err := client.Series.Query(). + Where(series.TitleContains("Expanse")). + WithRetryOptions(retry.WithIdempotent(true)). + All(ctx) +``` diff --git a/examples/ydb/ent/client.go b/examples/ydb/ent/client.go new file mode 100644 index 0000000000..a261dc8fb0 --- /dev/null +++ b/examples/ydb/ent/client.go @@ -0,0 +1,695 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "log" + "reflect" + + "entgo.io/ent" + "entgo.io/ent/examples/ydb/ent/migrate" + + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/examples/ydb/ent/episode" + "entgo.io/ent/examples/ydb/ent/season" + "entgo.io/ent/examples/ydb/ent/series" +) + +// Client is the client that holds all ent builders. +type Client struct { + config + // Schema is the client for creating, migrating and dropping schema. + Schema *migrate.Schema + // Episode is the client for interacting with the Episode builders. + Episode *EpisodeClient + // Season is the client for interacting with the Season builders. + Season *SeasonClient + // Series is the client for interacting with the Series builders. + Series *SeriesClient +} + +// NewClient creates a new client configured with the given options. +func NewClient(opts ...Option) *Client { + client := &Client{config: newConfig(opts...)} + client.init() + return client +} + +func (c *Client) init() { + c.Schema = migrate.NewSchema(c.driver) + c.Episode = NewEpisodeClient(c.config) + c.Season = NewSeasonClient(c.config) + c.Series = NewSeriesClient(c.config) +} + +type ( + // config is the configuration for the client and its builder. + config struct { + // driver used for executing database requests. + driver dialect.Driver + // debug enable a debug logging. + debug bool + // log used for logging on debug mode. + log func(...any) + // hooks to execute on mutations. + hooks *hooks + // interceptors to execute on queries. + inters *inters + } + // Option function to configure the client. + Option func(*config) +) + +// newConfig creates a new config for the client. +func newConfig(opts ...Option) config { + cfg := config{log: log.Println, hooks: &hooks{}, inters: &inters{}} + cfg.options(opts...) + return cfg +} + +// options applies the options on the config object. +func (c *config) options(opts ...Option) { + for _, opt := range opts { + opt(c) + } + if c.debug { + c.driver = dialect.Debug(c.driver, c.log) + } +} + +// Debug enables debug logging on the ent.Driver. +func Debug() Option { + return func(c *config) { + c.debug = true + } +} + +// Log sets the logging function for debug mode. +func Log(fn func(...any)) Option { + return func(c *config) { + c.log = fn + } +} + +// Driver configures the client driver. +func Driver(driver dialect.Driver) Option { + return func(c *config) { + c.driver = driver + } +} + +// Open opens a database/sql.DB specified by the driver name and +// the data source name, and returns a new client attached to it. +// Optional parameters can be added for configuring the client. +func Open(driverName, dataSourceName string, options ...Option) (*Client, error) { + switch driverName { + case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB: + drv, err := sql.Open(driverName, dataSourceName) + if err != nil { + return nil, err + } + return NewClient(append(options, Driver(drv))...), nil + default: + return nil, fmt.Errorf("unsupported driver: %q", driverName) + } +} + +// ErrTxStarted is returned when trying to start a new transaction from a transactional client. +var ErrTxStarted = errors.New("ent: cannot start a transaction within a transaction") + +// Tx returns a new transactional client. The provided context +// is used until the transaction is committed or rolled back. +func (c *Client) Tx(ctx context.Context) (*Tx, error) { + if _, ok := c.driver.(*txDriver); ok { + return nil, ErrTxStarted + } + tx, err := newTx(ctx, c.driver) + if err != nil { + return nil, fmt.Errorf("ent: starting a transaction: %w", err) + } + cfg := c.config + cfg.driver = tx + return &Tx{ + ctx: ctx, + config: cfg, + Episode: NewEpisodeClient(cfg), + Season: NewSeasonClient(cfg), + Series: NewSeriesClient(cfg), + }, nil +} + +// BeginTx returns a transactional client with specified options. +func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) { + if _, ok := c.driver.(*txDriver); ok { + return nil, errors.New("ent: cannot start a transaction within a transaction") + } + tx, err := c.driver.(interface { + BeginTx(context.Context, *sql.TxOptions) (dialect.Tx, error) + }).BeginTx(ctx, opts) + if err != nil { + return nil, fmt.Errorf("ent: starting a transaction: %w", err) + } + cfg := c.config + cfg.driver = &txDriver{tx: tx, drv: c.driver} + return &Tx{ + ctx: ctx, + config: cfg, + Episode: NewEpisodeClient(cfg), + Season: NewSeasonClient(cfg), + Series: NewSeriesClient(cfg), + }, nil +} + +// Debug returns a new debug-client. It's used to get verbose logging on specific operations. +// +// client.Debug(). +// Episode. +// Query(). +// Count(ctx) +func (c *Client) Debug() *Client { + if c.debug { + return c + } + cfg := c.config + cfg.driver = dialect.Debug(c.driver, c.log) + client := &Client{config: cfg} + client.init() + return client +} + +// Close closes the database connection and prevents new queries from starting. +func (c *Client) Close() error { + return c.driver.Close() +} + +// Use adds the mutation hooks to all the entity clients. +// In order to add hooks to a specific client, call: `client.Node.Use(...)`. +func (c *Client) Use(hooks ...Hook) { + c.Episode.Use(hooks...) + c.Season.Use(hooks...) + c.Series.Use(hooks...) +} + +// Intercept adds the query interceptors to all the entity clients. +// In order to add interceptors to a specific client, call: `client.Node.Intercept(...)`. +func (c *Client) Intercept(interceptors ...Interceptor) { + c.Episode.Intercept(interceptors...) + c.Season.Intercept(interceptors...) + c.Series.Intercept(interceptors...) +} + +// Mutate implements the ent.Mutator interface. +func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) { + switch m := m.(type) { + case *EpisodeMutation: + return c.Episode.mutate(ctx, m) + case *SeasonMutation: + return c.Season.mutate(ctx, m) + case *SeriesMutation: + return c.Series.mutate(ctx, m) + default: + return nil, fmt.Errorf("ent: unknown mutation type %T", m) + } +} + +// EpisodeClient is a client for the Episode schema. +type EpisodeClient struct { + config +} + +// NewEpisodeClient returns a client for the Episode from the given config. +func NewEpisodeClient(c config) *EpisodeClient { + return &EpisodeClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `episode.Hooks(f(g(h())))`. +func (c *EpisodeClient) Use(hooks ...Hook) { + c.hooks.Episode = append(c.hooks.Episode, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `episode.Intercept(f(g(h())))`. +func (c *EpisodeClient) Intercept(interceptors ...Interceptor) { + c.inters.Episode = append(c.inters.Episode, interceptors...) +} + +// Create returns a builder for creating a Episode entity. +func (c *EpisodeClient) Create() *EpisodeCreate { + mutation := newEpisodeMutation(c.config, OpCreate) + return &EpisodeCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of Episode entities. +func (c *EpisodeClient) CreateBulk(builders ...*EpisodeCreate) *EpisodeCreateBulk { + return &EpisodeCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *EpisodeClient) MapCreateBulk(slice any, setFunc func(*EpisodeCreate, int)) *EpisodeCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &EpisodeCreateBulk{err: fmt.Errorf("calling to EpisodeClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*EpisodeCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &EpisodeCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for Episode. +func (c *EpisodeClient) Update() *EpisodeUpdate { + mutation := newEpisodeMutation(c.config, OpUpdate) + return &EpisodeUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *EpisodeClient) UpdateOne(_m *Episode) *EpisodeUpdateOne { + mutation := newEpisodeMutation(c.config, OpUpdateOne, withEpisode(_m)) + return &EpisodeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *EpisodeClient) UpdateOneID(id int64) *EpisodeUpdateOne { + mutation := newEpisodeMutation(c.config, OpUpdateOne, withEpisodeID(id)) + return &EpisodeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for Episode. +func (c *EpisodeClient) Delete() *EpisodeDelete { + mutation := newEpisodeMutation(c.config, OpDelete) + return &EpisodeDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *EpisodeClient) DeleteOne(_m *Episode) *EpisodeDeleteOne { + return c.DeleteOneID(_m.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *EpisodeClient) DeleteOneID(id int64) *EpisodeDeleteOne { + builder := c.Delete().Where(episode.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &EpisodeDeleteOne{builder} +} + +// Query returns a query builder for Episode. +func (c *EpisodeClient) Query() *EpisodeQuery { + return &EpisodeQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeEpisode}, + inters: c.Interceptors(), + } +} + +// Get returns a Episode entity by its id. +func (c *EpisodeClient) Get(ctx context.Context, id int64) (*Episode, error) { + return c.Query().Where(episode.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *EpisodeClient) GetX(ctx context.Context, id int64) *Episode { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// QuerySeason queries the season edge of a Episode. +func (c *EpisodeClient) QuerySeason(_m *Episode) *SeasonQuery { + query := (&SeasonClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := _m.ID + step := sqlgraph.NewStep( + sqlgraph.From(episode.Table, episode.FieldID, id), + sqlgraph.To(season.Table, season.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, episode.SeasonTable, episode.SeasonColumn), + ) + fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// Hooks returns the client hooks. +func (c *EpisodeClient) Hooks() []Hook { + return c.hooks.Episode +} + +// Interceptors returns the client interceptors. +func (c *EpisodeClient) Interceptors() []Interceptor { + return c.inters.Episode +} + +func (c *EpisodeClient) mutate(ctx context.Context, m *EpisodeMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&EpisodeCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&EpisodeUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&EpisodeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&EpisodeDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown Episode mutation op: %q", m.Op()) + } +} + +// SeasonClient is a client for the Season schema. +type SeasonClient struct { + config +} + +// NewSeasonClient returns a client for the Season from the given config. +func NewSeasonClient(c config) *SeasonClient { + return &SeasonClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `season.Hooks(f(g(h())))`. +func (c *SeasonClient) Use(hooks ...Hook) { + c.hooks.Season = append(c.hooks.Season, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `season.Intercept(f(g(h())))`. +func (c *SeasonClient) Intercept(interceptors ...Interceptor) { + c.inters.Season = append(c.inters.Season, interceptors...) +} + +// Create returns a builder for creating a Season entity. +func (c *SeasonClient) Create() *SeasonCreate { + mutation := newSeasonMutation(c.config, OpCreate) + return &SeasonCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of Season entities. +func (c *SeasonClient) CreateBulk(builders ...*SeasonCreate) *SeasonCreateBulk { + return &SeasonCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *SeasonClient) MapCreateBulk(slice any, setFunc func(*SeasonCreate, int)) *SeasonCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &SeasonCreateBulk{err: fmt.Errorf("calling to SeasonClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*SeasonCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &SeasonCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for Season. +func (c *SeasonClient) Update() *SeasonUpdate { + mutation := newSeasonMutation(c.config, OpUpdate) + return &SeasonUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *SeasonClient) UpdateOne(_m *Season) *SeasonUpdateOne { + mutation := newSeasonMutation(c.config, OpUpdateOne, withSeason(_m)) + return &SeasonUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *SeasonClient) UpdateOneID(id int64) *SeasonUpdateOne { + mutation := newSeasonMutation(c.config, OpUpdateOne, withSeasonID(id)) + return &SeasonUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for Season. +func (c *SeasonClient) Delete() *SeasonDelete { + mutation := newSeasonMutation(c.config, OpDelete) + return &SeasonDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *SeasonClient) DeleteOne(_m *Season) *SeasonDeleteOne { + return c.DeleteOneID(_m.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *SeasonClient) DeleteOneID(id int64) *SeasonDeleteOne { + builder := c.Delete().Where(season.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &SeasonDeleteOne{builder} +} + +// Query returns a query builder for Season. +func (c *SeasonClient) Query() *SeasonQuery { + return &SeasonQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeSeason}, + inters: c.Interceptors(), + } +} + +// Get returns a Season entity by its id. +func (c *SeasonClient) Get(ctx context.Context, id int64) (*Season, error) { + return c.Query().Where(season.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *SeasonClient) GetX(ctx context.Context, id int64) *Season { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// QuerySeries queries the series edge of a Season. +func (c *SeasonClient) QuerySeries(_m *Season) *SeriesQuery { + query := (&SeriesClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := _m.ID + step := sqlgraph.NewStep( + sqlgraph.From(season.Table, season.FieldID, id), + sqlgraph.To(series.Table, series.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, season.SeriesTable, season.SeriesColumn), + ) + fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// QueryEpisodes queries the episodes edge of a Season. +func (c *SeasonClient) QueryEpisodes(_m *Season) *EpisodeQuery { + query := (&EpisodeClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := _m.ID + step := sqlgraph.NewStep( + sqlgraph.From(season.Table, season.FieldID, id), + sqlgraph.To(episode.Table, episode.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, season.EpisodesTable, season.EpisodesColumn), + ) + fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// Hooks returns the client hooks. +func (c *SeasonClient) Hooks() []Hook { + return c.hooks.Season +} + +// Interceptors returns the client interceptors. +func (c *SeasonClient) Interceptors() []Interceptor { + return c.inters.Season +} + +func (c *SeasonClient) mutate(ctx context.Context, m *SeasonMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&SeasonCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&SeasonUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&SeasonUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&SeasonDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown Season mutation op: %q", m.Op()) + } +} + +// SeriesClient is a client for the Series schema. +type SeriesClient struct { + config +} + +// NewSeriesClient returns a client for the Series from the given config. +func NewSeriesClient(c config) *SeriesClient { + return &SeriesClient{config: c} +} + +// Use adds a list of mutation hooks to the hooks stack. +// A call to `Use(f, g, h)` equals to `series.Hooks(f(g(h())))`. +func (c *SeriesClient) Use(hooks ...Hook) { + c.hooks.Series = append(c.hooks.Series, hooks...) +} + +// Intercept adds a list of query interceptors to the interceptors stack. +// A call to `Intercept(f, g, h)` equals to `series.Intercept(f(g(h())))`. +func (c *SeriesClient) Intercept(interceptors ...Interceptor) { + c.inters.Series = append(c.inters.Series, interceptors...) +} + +// Create returns a builder for creating a Series entity. +func (c *SeriesClient) Create() *SeriesCreate { + mutation := newSeriesMutation(c.config, OpCreate) + return &SeriesCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// CreateBulk returns a builder for creating a bulk of Series entities. +func (c *SeriesClient) CreateBulk(builders ...*SeriesCreate) *SeriesCreateBulk { + return &SeriesCreateBulk{config: c.config, builders: builders} +} + +// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates +// a builder and applies setFunc on it. +func (c *SeriesClient) MapCreateBulk(slice any, setFunc func(*SeriesCreate, int)) *SeriesCreateBulk { + rv := reflect.ValueOf(slice) + if rv.Kind() != reflect.Slice { + return &SeriesCreateBulk{err: fmt.Errorf("calling to SeriesClient.MapCreateBulk with wrong type %T, need slice", slice)} + } + builders := make([]*SeriesCreate, rv.Len()) + for i := 0; i < rv.Len(); i++ { + builders[i] = c.Create() + setFunc(builders[i], i) + } + return &SeriesCreateBulk{config: c.config, builders: builders} +} + +// Update returns an update builder for Series. +func (c *SeriesClient) Update() *SeriesUpdate { + mutation := newSeriesMutation(c.config, OpUpdate) + return &SeriesUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOne returns an update builder for the given entity. +func (c *SeriesClient) UpdateOne(_m *Series) *SeriesUpdateOne { + mutation := newSeriesMutation(c.config, OpUpdateOne, withSeries(_m)) + return &SeriesUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// UpdateOneID returns an update builder for the given id. +func (c *SeriesClient) UpdateOneID(id int64) *SeriesUpdateOne { + mutation := newSeriesMutation(c.config, OpUpdateOne, withSeriesID(id)) + return &SeriesUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// Delete returns a delete builder for Series. +func (c *SeriesClient) Delete() *SeriesDelete { + mutation := newSeriesMutation(c.config, OpDelete) + return &SeriesDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} +} + +// DeleteOne returns a builder for deleting the given entity. +func (c *SeriesClient) DeleteOne(_m *Series) *SeriesDeleteOne { + return c.DeleteOneID(_m.ID) +} + +// DeleteOneID returns a builder for deleting the given entity by its id. +func (c *SeriesClient) DeleteOneID(id int64) *SeriesDeleteOne { + builder := c.Delete().Where(series.ID(id)) + builder.mutation.id = &id + builder.mutation.op = OpDeleteOne + return &SeriesDeleteOne{builder} +} + +// Query returns a query builder for Series. +func (c *SeriesClient) Query() *SeriesQuery { + return &SeriesQuery{ + config: c.config, + ctx: &QueryContext{Type: TypeSeries}, + inters: c.Interceptors(), + } +} + +// Get returns a Series entity by its id. +func (c *SeriesClient) Get(ctx context.Context, id int64) (*Series, error) { + return c.Query().Where(series.ID(id)).Only(ctx) +} + +// GetX is like Get, but panics if an error occurs. +func (c *SeriesClient) GetX(ctx context.Context, id int64) *Series { + obj, err := c.Get(ctx, id) + if err != nil { + panic(err) + } + return obj +} + +// QuerySeasons queries the seasons edge of a Series. +func (c *SeriesClient) QuerySeasons(_m *Series) *SeasonQuery { + query := (&SeasonClient{config: c.config}).Query() + query.path = func(context.Context) (fromV *sql.Selector, _ error) { + id := _m.ID + step := sqlgraph.NewStep( + sqlgraph.From(series.Table, series.FieldID, id), + sqlgraph.To(season.Table, season.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, series.SeasonsTable, series.SeasonsColumn), + ) + fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step) + return fromV, nil + } + return query +} + +// Hooks returns the client hooks. +func (c *SeriesClient) Hooks() []Hook { + return c.hooks.Series +} + +// Interceptors returns the client interceptors. +func (c *SeriesClient) Interceptors() []Interceptor { + return c.inters.Series +} + +func (c *SeriesClient) mutate(ctx context.Context, m *SeriesMutation) (Value, error) { + switch m.Op() { + case OpCreate: + return (&SeriesCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdate: + return (&SeriesUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpUpdateOne: + return (&SeriesUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) + case OpDelete, OpDeleteOne: + return (&SeriesDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) + default: + return nil, fmt.Errorf("ent: unknown Series mutation op: %q", m.Op()) + } +} + +// hooks and interceptors per client, for fast access. +type ( + hooks struct { + Episode, Season, Series []ent.Hook + } + inters struct { + Episode, Season, Series []ent.Interceptor + } +) diff --git a/examples/ydb/ent/ent.go b/examples/ydb/ent/ent.go new file mode 100644 index 0000000000..26efa85eae --- /dev/null +++ b/examples/ydb/ent/ent.go @@ -0,0 +1,616 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "reflect" + "sync" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/examples/ydb/ent/episode" + "entgo.io/ent/examples/ydb/ent/season" + "entgo.io/ent/examples/ydb/ent/series" +) + +// ent aliases to avoid import conflicts in user's code. +type ( + Op = ent.Op + Hook = ent.Hook + Value = ent.Value + Query = ent.Query + QueryContext = ent.QueryContext + Querier = ent.Querier + QuerierFunc = ent.QuerierFunc + Interceptor = ent.Interceptor + InterceptFunc = ent.InterceptFunc + Traverser = ent.Traverser + TraverseFunc = ent.TraverseFunc + Policy = ent.Policy + Mutator = ent.Mutator + Mutation = ent.Mutation + MutateFunc = ent.MutateFunc +) + +type clientCtxKey struct{} + +// FromContext returns a Client stored inside a context, or nil if there isn't one. +func FromContext(ctx context.Context) *Client { + c, _ := ctx.Value(clientCtxKey{}).(*Client) + return c +} + +// NewContext returns a new context with the given Client attached. +func NewContext(parent context.Context, c *Client) context.Context { + return context.WithValue(parent, clientCtxKey{}, c) +} + +type txCtxKey struct{} + +// TxFromContext returns a Tx stored inside a context, or nil if there isn't one. +func TxFromContext(ctx context.Context) *Tx { + tx, _ := ctx.Value(txCtxKey{}).(*Tx) + return tx +} + +// NewTxContext returns a new context with the given Tx attached. +func NewTxContext(parent context.Context, tx *Tx) context.Context { + return context.WithValue(parent, txCtxKey{}, tx) +} + +// OrderFunc applies an ordering on the sql selector. +// Deprecated: Use Asc/Desc functions or the package builders instead. +type OrderFunc func(*sql.Selector) + +var ( + initCheck sync.Once + columnCheck sql.ColumnCheck +) + +// checkColumn checks if the column exists in the given table. +func checkColumn(t, c string) error { + initCheck.Do(func() { + columnCheck = sql.NewColumnCheck(map[string]func(string) bool{ + episode.Table: episode.ValidColumn, + season.Table: season.ValidColumn, + series.Table: series.ValidColumn, + }) + }) + return columnCheck(t, c) +} + +// Asc applies the given fields in ASC order. +func Asc(fields ...string) func(*sql.Selector) { + return func(s *sql.Selector) { + for _, f := range fields { + if err := checkColumn(s.TableName(), f); err != nil { + s.AddError(&ValidationError{Name: f, err: fmt.Errorf("ent: %w", err)}) + } + s.OrderBy(sql.Asc(s.C(f))) + } + } +} + +// Desc applies the given fields in DESC order. +func Desc(fields ...string) func(*sql.Selector) { + return func(s *sql.Selector) { + for _, f := range fields { + if err := checkColumn(s.TableName(), f); err != nil { + s.AddError(&ValidationError{Name: f, err: fmt.Errorf("ent: %w", err)}) + } + s.OrderBy(sql.Desc(s.C(f))) + } + } +} + +// AggregateFunc applies an aggregation step on the group-by traversal/selector. +type AggregateFunc func(*sql.Selector) string + +// As is a pseudo aggregation function for renaming another other functions with custom names. For example: +// +// GroupBy(field1, field2). +// Aggregate(ent.As(ent.Sum(field1), "sum_field1"), (ent.As(ent.Sum(field2), "sum_field2")). +// Scan(ctx, &v) +func As(fn AggregateFunc, end string) AggregateFunc { + return func(s *sql.Selector) string { + return sql.As(fn(s), end) + } +} + +// Count applies the "count" aggregation function on each group. +func Count() AggregateFunc { + return func(s *sql.Selector) string { + return sql.Count("*") + } +} + +// Max applies the "max" aggregation function on the given field of each group. +func Max(field string) AggregateFunc { + return func(s *sql.Selector) string { + if err := checkColumn(s.TableName(), field); err != nil { + s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)}) + return "" + } + return sql.Max(s.C(field)) + } +} + +// Mean applies the "mean" aggregation function on the given field of each group. +func Mean(field string) AggregateFunc { + return func(s *sql.Selector) string { + if err := checkColumn(s.TableName(), field); err != nil { + s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)}) + return "" + } + return sql.Avg(s.C(field)) + } +} + +// Min applies the "min" aggregation function on the given field of each group. +func Min(field string) AggregateFunc { + return func(s *sql.Selector) string { + if err := checkColumn(s.TableName(), field); err != nil { + s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)}) + return "" + } + return sql.Min(s.C(field)) + } +} + +// Sum applies the "sum" aggregation function on the given field of each group. +func Sum(field string) AggregateFunc { + return func(s *sql.Selector) string { + if err := checkColumn(s.TableName(), field); err != nil { + s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)}) + return "" + } + return sql.Sum(s.C(field)) + } +} + +// ValidationError returns when validating a field or edge fails. +type ValidationError struct { + Name string // Field or edge name. + err error +} + +// Error implements the error interface. +func (e *ValidationError) Error() string { + return e.err.Error() +} + +// Unwrap implements the errors.Wrapper interface. +func (e *ValidationError) Unwrap() error { + return e.err +} + +// IsValidationError returns a boolean indicating whether the error is a validation error. +func IsValidationError(err error) bool { + if err == nil { + return false + } + var e *ValidationError + return errors.As(err, &e) +} + +// NotFoundError returns when trying to fetch a specific entity and it was not found in the database. +type NotFoundError struct { + label string +} + +// Error implements the error interface. +func (e *NotFoundError) Error() string { + return "ent: " + e.label + " not found" +} + +// IsNotFound returns a boolean indicating whether the error is a not found error. +func IsNotFound(err error) bool { + if err == nil { + return false + } + var e *NotFoundError + return errors.As(err, &e) +} + +// MaskNotFound masks not found error. +func MaskNotFound(err error) error { + if IsNotFound(err) { + return nil + } + return err +} + +// NotSingularError returns when trying to fetch a singular entity and more then one was found in the database. +type NotSingularError struct { + label string +} + +// Error implements the error interface. +func (e *NotSingularError) Error() string { + return "ent: " + e.label + " not singular" +} + +// IsNotSingular returns a boolean indicating whether the error is a not singular error. +func IsNotSingular(err error) bool { + if err == nil { + return false + } + var e *NotSingularError + return errors.As(err, &e) +} + +// NotLoadedError returns when trying to get a node that was not loaded by the query. +type NotLoadedError struct { + edge string +} + +// Error implements the error interface. +func (e *NotLoadedError) Error() string { + return "ent: " + e.edge + " edge was not loaded" +} + +// IsNotLoaded returns a boolean indicating whether the error is a not loaded error. +func IsNotLoaded(err error) bool { + if err == nil { + return false + } + var e *NotLoadedError + return errors.As(err, &e) +} + +// ConstraintError returns when trying to create/update one or more entities and +// one or more of their constraints failed. For example, violation of edge or +// field uniqueness. +type ConstraintError struct { + msg string + wrap error +} + +// Error implements the error interface. +func (e ConstraintError) Error() string { + return "ent: constraint failed: " + e.msg +} + +// Unwrap implements the errors.Wrapper interface. +func (e *ConstraintError) Unwrap() error { + return e.wrap +} + +// IsConstraintError returns a boolean indicating whether the error is a constraint failure. +func IsConstraintError(err error) bool { + if err == nil { + return false + } + var e *ConstraintError + return errors.As(err, &e) +} + +// selector embedded by the different Select/GroupBy builders. +type selector struct { + label string + flds *[]string + fns []AggregateFunc + scan func(context.Context, any) error +} + +// ScanX is like Scan, but panics if an error occurs. +func (s *selector) ScanX(ctx context.Context, v any) { + if err := s.scan(ctx, v); err != nil { + panic(err) + } +} + +// Strings returns list of strings from a selector. It is only allowed when selecting one field. +func (s *selector) Strings(ctx context.Context) ([]string, error) { + if len(*s.flds) > 1 { + return nil, errors.New("ent: Strings is not achievable when selecting more than 1 field") + } + var v []string + if err := s.scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// StringsX is like Strings, but panics if an error occurs. +func (s *selector) StringsX(ctx context.Context) []string { + v, err := s.Strings(ctx) + if err != nil { + panic(err) + } + return v +} + +// String returns a single string from a selector. It is only allowed when selecting one field. +func (s *selector) String(ctx context.Context) (_ string, err error) { + var v []string + if v, err = s.Strings(ctx); err != nil { + return + } + switch len(v) { + case 1: + return v[0], nil + case 0: + err = &NotFoundError{s.label} + default: + err = fmt.Errorf("ent: Strings returned %d results when one was expected", len(v)) + } + return +} + +// StringX is like String, but panics if an error occurs. +func (s *selector) StringX(ctx context.Context) string { + v, err := s.String(ctx) + if err != nil { + panic(err) + } + return v +} + +// Ints returns list of ints from a selector. It is only allowed when selecting one field. +func (s *selector) Ints(ctx context.Context) ([]int, error) { + if len(*s.flds) > 1 { + return nil, errors.New("ent: Ints is not achievable when selecting more than 1 field") + } + var v []int + if err := s.scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// IntsX is like Ints, but panics if an error occurs. +func (s *selector) IntsX(ctx context.Context) []int { + v, err := s.Ints(ctx) + if err != nil { + panic(err) + } + return v +} + +// Int returns a single int from a selector. It is only allowed when selecting one field. +func (s *selector) Int(ctx context.Context) (_ int, err error) { + var v []int + if v, err = s.Ints(ctx); err != nil { + return + } + switch len(v) { + case 1: + return v[0], nil + case 0: + err = &NotFoundError{s.label} + default: + err = fmt.Errorf("ent: Ints returned %d results when one was expected", len(v)) + } + return +} + +// IntX is like Int, but panics if an error occurs. +func (s *selector) IntX(ctx context.Context) int { + v, err := s.Int(ctx) + if err != nil { + panic(err) + } + return v +} + +// Float64s returns list of float64s from a selector. It is only allowed when selecting one field. +func (s *selector) Float64s(ctx context.Context) ([]float64, error) { + if len(*s.flds) > 1 { + return nil, errors.New("ent: Float64s is not achievable when selecting more than 1 field") + } + var v []float64 + if err := s.scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// Float64sX is like Float64s, but panics if an error occurs. +func (s *selector) Float64sX(ctx context.Context) []float64 { + v, err := s.Float64s(ctx) + if err != nil { + panic(err) + } + return v +} + +// Float64 returns a single float64 from a selector. It is only allowed when selecting one field. +func (s *selector) Float64(ctx context.Context) (_ float64, err error) { + var v []float64 + if v, err = s.Float64s(ctx); err != nil { + return + } + switch len(v) { + case 1: + return v[0], nil + case 0: + err = &NotFoundError{s.label} + default: + err = fmt.Errorf("ent: Float64s returned %d results when one was expected", len(v)) + } + return +} + +// Float64X is like Float64, but panics if an error occurs. +func (s *selector) Float64X(ctx context.Context) float64 { + v, err := s.Float64(ctx) + if err != nil { + panic(err) + } + return v +} + +// Bools returns list of bools from a selector. It is only allowed when selecting one field. +func (s *selector) Bools(ctx context.Context) ([]bool, error) { + if len(*s.flds) > 1 { + return nil, errors.New("ent: Bools is not achievable when selecting more than 1 field") + } + var v []bool + if err := s.scan(ctx, &v); err != nil { + return nil, err + } + return v, nil +} + +// BoolsX is like Bools, but panics if an error occurs. +func (s *selector) BoolsX(ctx context.Context) []bool { + v, err := s.Bools(ctx) + if err != nil { + panic(err) + } + return v +} + +// Bool returns a single bool from a selector. It is only allowed when selecting one field. +func (s *selector) Bool(ctx context.Context) (_ bool, err error) { + var v []bool + if v, err = s.Bools(ctx); err != nil { + return + } + switch len(v) { + case 1: + return v[0], nil + case 0: + err = &NotFoundError{s.label} + default: + err = fmt.Errorf("ent: Bools returned %d results when one was expected", len(v)) + } + return +} + +// BoolX is like Bool, but panics if an error occurs. +func (s *selector) BoolX(ctx context.Context) bool { + v, err := s.Bool(ctx) + if err != nil { + panic(err) + } + return v +} + +// withHooks invokes the builder operation with the given hooks, if any. +func withHooks[V Value, M any, PM interface { + *M + Mutation +}](ctx context.Context, exec func(context.Context) (V, error), mutation PM, hooks []Hook) (value V, err error) { + if len(hooks) == 0 { + return exec(ctx) + } + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutationT, ok := any(m).(PM) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + // Set the mutation to the builder. + *mutation = *mutationT + return exec(ctx) + }) + for i := len(hooks) - 1; i >= 0; i-- { + if hooks[i] == nil { + return value, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)") + } + mut = hooks[i](mut) + } + v, err := mut.Mutate(ctx, mutation) + if err != nil { + return value, err + } + nv, ok := v.(V) + if !ok { + return value, fmt.Errorf("unexpected node type %T returned from %T", v, mutation) + } + return nv, nil +} + +// setContextOp returns a new context with the given QueryContext attached (including its op) in case it does not exist. +func setContextOp(ctx context.Context, qc *QueryContext, op string) context.Context { + if ent.QueryFromContext(ctx) == nil { + qc.Op = op + ctx = ent.NewQueryContext(ctx, qc) + } + return ctx +} + +func querierAll[V Value, Q interface { + sqlAll(context.Context, ...queryHook) (V, error) +}]() Querier { + return QuerierFunc(func(ctx context.Context, q Query) (Value, error) { + query, ok := q.(Q) + if !ok { + return nil, fmt.Errorf("unexpected query type %T", q) + } + return query.sqlAll(ctx) + }) +} + +func querierCount[Q interface { + sqlCount(context.Context) (int, error) +}]() Querier { + return QuerierFunc(func(ctx context.Context, q Query) (Value, error) { + query, ok := q.(Q) + if !ok { + return nil, fmt.Errorf("unexpected query type %T", q) + } + return query.sqlCount(ctx) + }) +} + +func withInterceptors[V Value](ctx context.Context, q Query, qr Querier, inters []Interceptor) (v V, err error) { + for i := len(inters) - 1; i >= 0; i-- { + qr = inters[i].Intercept(qr) + } + rv, err := qr.Query(ctx, q) + if err != nil { + return v, err + } + vt, ok := rv.(V) + if !ok { + return v, fmt.Errorf("unexpected type %T returned from %T. expected type: %T", vt, q, v) + } + return vt, nil +} + +func scanWithInterceptors[Q1 ent.Query, Q2 interface { + sqlScan(context.Context, Q1, any) error +}](ctx context.Context, rootQuery Q1, selectOrGroup Q2, inters []Interceptor, v any) error { + rv := reflect.ValueOf(v) + var qr Querier = QuerierFunc(func(ctx context.Context, q Query) (Value, error) { + query, ok := q.(Q1) + if !ok { + return nil, fmt.Errorf("unexpected query type %T", q) + } + if err := selectOrGroup.sqlScan(ctx, query, v); err != nil { + return nil, err + } + if k := rv.Kind(); k == reflect.Pointer && rv.Elem().CanInterface() { + return rv.Elem().Interface(), nil + } + return v, nil + }) + for i := len(inters) - 1; i >= 0; i-- { + qr = inters[i].Intercept(qr) + } + vv, err := qr.Query(ctx, rootQuery) + if err != nil { + return err + } + switch rv2 := reflect.ValueOf(vv); { + case rv.IsNil(), rv2.IsNil(), rv.Kind() != reflect.Pointer: + case rv.Type() == rv2.Type(): + rv.Elem().Set(rv2.Elem()) + case rv.Elem().Type() == rv2.Type(): + rv.Elem().Set(rv2) + } + return nil +} + +// queryHook describes an internal hook for the different sqlAll methods. +type queryHook func(context.Context, *sqlgraph.QuerySpec) diff --git a/examples/ydb/ent/entc.go b/examples/ydb/ent/entc.go new file mode 100644 index 0000000000..7ce29fc20e --- /dev/null +++ b/examples/ydb/ent/entc.go @@ -0,0 +1,31 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +//go:build ignore +// +build ignore + +package main + +import ( + "log" + + "entgo.io/ent/entc" + "entgo.io/ent/entc/gen" +) + +func main() { + err := entc.Generate("./schema", &gen.Config{ + Header: `// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT.`, + Features: []gen.Feature{ + gen.FeatureRetryOptions, + }, + }) + if err != nil { + log.Fatalf("running ent codegen: %v", err) + } +} diff --git a/examples/ydb/ent/enttest/enttest.go b/examples/ydb/ent/enttest/enttest.go new file mode 100644 index 0000000000..070a75c5b9 --- /dev/null +++ b/examples/ydb/ent/enttest/enttest.go @@ -0,0 +1,88 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package enttest + +import ( + "context" + + "entgo.io/ent/examples/ydb/ent" + // required by schema hooks. + _ "entgo.io/ent/examples/ydb/ent/runtime" + + "entgo.io/ent/dialect/sql/schema" + "entgo.io/ent/examples/ydb/ent/migrate" +) + +type ( + // TestingT is the interface that is shared between + // testing.T and testing.B and used by enttest. + TestingT interface { + FailNow() + Error(...any) + } + + // Option configures client creation. + Option func(*options) + + options struct { + opts []ent.Option + migrateOpts []schema.MigrateOption + } +) + +// WithOptions forwards options to client creation. +func WithOptions(opts ...ent.Option) Option { + return func(o *options) { + o.opts = append(o.opts, opts...) + } +} + +// WithMigrateOptions forwards options to auto migration. +func WithMigrateOptions(opts ...schema.MigrateOption) Option { + return func(o *options) { + o.migrateOpts = append(o.migrateOpts, opts...) + } +} + +func newOptions(opts []Option) *options { + o := &options{} + for _, opt := range opts { + opt(o) + } + return o +} + +// Open calls ent.Open and auto-run migration. +func Open(t TestingT, driverName, dataSourceName string, opts ...Option) *ent.Client { + o := newOptions(opts) + c, err := ent.Open(driverName, dataSourceName, o.opts...) + if err != nil { + t.Error(err) + t.FailNow() + } + migrateSchema(t, c, o) + return c +} + +// NewClient calls ent.NewClient and auto-run migration. +func NewClient(t TestingT, opts ...Option) *ent.Client { + o := newOptions(opts) + c := ent.NewClient(o.opts...) + migrateSchema(t, c, o) + return c +} +func migrateSchema(t TestingT, c *ent.Client, o *options) { + tables, err := schema.CopyTables(migrate.Tables) + if err != nil { + t.Error(err) + t.FailNow() + } + if err := migrate.Create(context.Background(), c.Schema, tables, o.migrateOpts...); err != nil { + t.Error(err) + t.FailNow() + } +} diff --git a/examples/ydb/ent/episode.go b/examples/ydb/ent/episode.go new file mode 100644 index 0000000000..dd6ec3dbdd --- /dev/null +++ b/examples/ydb/ent/episode.go @@ -0,0 +1,161 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "fmt" + "strings" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/examples/ydb/ent/episode" + "entgo.io/ent/examples/ydb/ent/season" +) + +// Episode is the model entity for the Episode schema. +type Episode struct { + config `json:"-"` + // ID of the ent. + ID int64 `json:"id,omitempty"` + // SeasonID holds the value of the "season_id" field. + SeasonID int64 `json:"season_id,omitempty"` + // Title holds the value of the "title" field. + Title string `json:"title,omitempty"` + // AirDate holds the value of the "air_date" field. + AirDate time.Time `json:"air_date,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the EpisodeQuery when eager-loading is set. + Edges EpisodeEdges `json:"edges"` + selectValues sql.SelectValues +} + +// EpisodeEdges holds the relations/edges for other nodes in the graph. +type EpisodeEdges struct { + // Season holds the value of the season edge. + Season *Season `json:"season,omitempty"` + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [1]bool +} + +// SeasonOrErr returns the Season value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e EpisodeEdges) SeasonOrErr() (*Season, error) { + if e.Season != nil { + return e.Season, nil + } else if e.loadedTypes[0] { + return nil, &NotFoundError{label: season.Label} + } + return nil, &NotLoadedError{edge: "season"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*Episode) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case episode.FieldID, episode.FieldSeasonID: + values[i] = new(sql.NullInt64) + case episode.FieldTitle: + values[i] = new(sql.NullString) + case episode.FieldAirDate: + values[i] = new(sql.NullTime) + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the Episode fields. +func (_m *Episode) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case episode.FieldID: + value, ok := values[i].(*sql.NullInt64) + if !ok { + return fmt.Errorf("unexpected type %T for field id", value) + } + _m.ID = int64(value.Int64) + case episode.FieldSeasonID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field season_id", values[i]) + } else if value.Valid { + _m.SeasonID = value.Int64 + } + case episode.FieldTitle: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field title", values[i]) + } else if value.Valid { + _m.Title = value.String + } + case episode.FieldAirDate: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field air_date", values[i]) + } else if value.Valid { + _m.AirDate = value.Time + } + default: + _m.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the Episode. +// This includes values selected through modifiers, order, etc. +func (_m *Episode) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + +// QuerySeason queries the "season" edge of the Episode entity. +func (_m *Episode) QuerySeason() *SeasonQuery { + return NewEpisodeClient(_m.config).QuerySeason(_m) +} + +// Update returns a builder for updating this Episode. +// Note that you need to call Episode.Unwrap() before calling this method if this Episode +// was returned from a transaction, and the transaction was committed or rolled back. +func (_m *Episode) Update() *EpisodeUpdateOne { + return NewEpisodeClient(_m.config).UpdateOne(_m) +} + +// Unwrap unwraps the Episode entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (_m *Episode) Unwrap() *Episode { + _tx, ok := _m.config.driver.(*txDriver) + if !ok { + panic("ent: Episode is not a transactional entity") + } + _m.config.driver = _tx.drv + return _m +} + +// String implements the fmt.Stringer. +func (_m *Episode) String() string { + var builder strings.Builder + builder.WriteString("Episode(") + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) + builder.WriteString("season_id=") + builder.WriteString(fmt.Sprintf("%v", _m.SeasonID)) + builder.WriteString(", ") + builder.WriteString("title=") + builder.WriteString(_m.Title) + builder.WriteString(", ") + builder.WriteString("air_date=") + builder.WriteString(_m.AirDate.Format(time.ANSIC)) + builder.WriteByte(')') + return builder.String() +} + +// Episodes is a parsable slice of Episode. +type Episodes []*Episode diff --git a/examples/ydb/ent/episode/episode.go b/examples/ydb/ent/episode/episode.go new file mode 100644 index 0000000000..be6e97858d --- /dev/null +++ b/examples/ydb/ent/episode/episode.go @@ -0,0 +1,96 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package episode + +import ( + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" +) + +const ( + // Label holds the string label denoting the episode type in the database. + Label = "episode" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldSeasonID holds the string denoting the season_id field in the database. + FieldSeasonID = "season_id" + // FieldTitle holds the string denoting the title field in the database. + FieldTitle = "title" + // FieldAirDate holds the string denoting the air_date field in the database. + FieldAirDate = "air_date" + // EdgeSeason holds the string denoting the season edge name in mutations. + EdgeSeason = "season" + // Table holds the table name of the episode in the database. + Table = "episodes" + // SeasonTable is the table that holds the season relation/edge. + SeasonTable = "episodes" + // SeasonInverseTable is the table name for the Season entity. + // It exists in this package in order to avoid circular dependency with the "season" package. + SeasonInverseTable = "seasons" + // SeasonColumn is the table column denoting the season relation/edge. + SeasonColumn = "season_id" +) + +// Columns holds all SQL columns for episode fields. +var Columns = []string{ + FieldID, + FieldSeasonID, + FieldTitle, + FieldAirDate, +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + return false +} + +var ( + // TitleValidator is a validator for the "title" field. It is called by the builders before save. + TitleValidator func(string) error +) + +// OrderOption defines the ordering options for the Episode queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// BySeasonID orders the results by the season_id field. +func BySeasonID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldSeasonID, opts...).ToFunc() +} + +// ByTitle orders the results by the title field. +func ByTitle(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldTitle, opts...).ToFunc() +} + +// ByAirDate orders the results by the air_date field. +func ByAirDate(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldAirDate, opts...).ToFunc() +} + +// BySeasonField orders the results by season field. +func BySeasonField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newSeasonStep(), sql.OrderByField(field, opts...)) + } +} +func newSeasonStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(SeasonInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, SeasonTable, SeasonColumn), + ) +} diff --git a/examples/ydb/ent/episode/where.go b/examples/ydb/ent/episode/where.go new file mode 100644 index 0000000000..2d93abb53e --- /dev/null +++ b/examples/ydb/ent/episode/where.go @@ -0,0 +1,238 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package episode + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/examples/ydb/ent/predicate" +) + +// ID filters vertices based on their ID field. +func ID(id int64) predicate.Episode { + return predicate.Episode(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id int64) predicate.Episode { + return predicate.Episode(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id int64) predicate.Episode { + return predicate.Episode(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...int64) predicate.Episode { + return predicate.Episode(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...int64) predicate.Episode { + return predicate.Episode(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id int64) predicate.Episode { + return predicate.Episode(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id int64) predicate.Episode { + return predicate.Episode(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id int64) predicate.Episode { + return predicate.Episode(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id int64) predicate.Episode { + return predicate.Episode(sql.FieldLTE(FieldID, id)) +} + +// SeasonID applies equality check predicate on the "season_id" field. It's identical to SeasonIDEQ. +func SeasonID(v int64) predicate.Episode { + return predicate.Episode(sql.FieldEQ(FieldSeasonID, v)) +} + +// Title applies equality check predicate on the "title" field. It's identical to TitleEQ. +func Title(v string) predicate.Episode { + return predicate.Episode(sql.FieldEQ(FieldTitle, v)) +} + +// AirDate applies equality check predicate on the "air_date" field. It's identical to AirDateEQ. +func AirDate(v time.Time) predicate.Episode { + return predicate.Episode(sql.FieldEQ(FieldAirDate, v)) +} + +// SeasonIDEQ applies the EQ predicate on the "season_id" field. +func SeasonIDEQ(v int64) predicate.Episode { + return predicate.Episode(sql.FieldEQ(FieldSeasonID, v)) +} + +// SeasonIDNEQ applies the NEQ predicate on the "season_id" field. +func SeasonIDNEQ(v int64) predicate.Episode { + return predicate.Episode(sql.FieldNEQ(FieldSeasonID, v)) +} + +// SeasonIDIn applies the In predicate on the "season_id" field. +func SeasonIDIn(vs ...int64) predicate.Episode { + return predicate.Episode(sql.FieldIn(FieldSeasonID, vs...)) +} + +// SeasonIDNotIn applies the NotIn predicate on the "season_id" field. +func SeasonIDNotIn(vs ...int64) predicate.Episode { + return predicate.Episode(sql.FieldNotIn(FieldSeasonID, vs...)) +} + +// TitleEQ applies the EQ predicate on the "title" field. +func TitleEQ(v string) predicate.Episode { + return predicate.Episode(sql.FieldEQ(FieldTitle, v)) +} + +// TitleNEQ applies the NEQ predicate on the "title" field. +func TitleNEQ(v string) predicate.Episode { + return predicate.Episode(sql.FieldNEQ(FieldTitle, v)) +} + +// TitleIn applies the In predicate on the "title" field. +func TitleIn(vs ...string) predicate.Episode { + return predicate.Episode(sql.FieldIn(FieldTitle, vs...)) +} + +// TitleNotIn applies the NotIn predicate on the "title" field. +func TitleNotIn(vs ...string) predicate.Episode { + return predicate.Episode(sql.FieldNotIn(FieldTitle, vs...)) +} + +// TitleGT applies the GT predicate on the "title" field. +func TitleGT(v string) predicate.Episode { + return predicate.Episode(sql.FieldGT(FieldTitle, v)) +} + +// TitleGTE applies the GTE predicate on the "title" field. +func TitleGTE(v string) predicate.Episode { + return predicate.Episode(sql.FieldGTE(FieldTitle, v)) +} + +// TitleLT applies the LT predicate on the "title" field. +func TitleLT(v string) predicate.Episode { + return predicate.Episode(sql.FieldLT(FieldTitle, v)) +} + +// TitleLTE applies the LTE predicate on the "title" field. +func TitleLTE(v string) predicate.Episode { + return predicate.Episode(sql.FieldLTE(FieldTitle, v)) +} + +// TitleContains applies the Contains predicate on the "title" field. +func TitleContains(v string) predicate.Episode { + return predicate.Episode(sql.FieldContains(FieldTitle, v)) +} + +// TitleHasPrefix applies the HasPrefix predicate on the "title" field. +func TitleHasPrefix(v string) predicate.Episode { + return predicate.Episode(sql.FieldHasPrefix(FieldTitle, v)) +} + +// TitleHasSuffix applies the HasSuffix predicate on the "title" field. +func TitleHasSuffix(v string) predicate.Episode { + return predicate.Episode(sql.FieldHasSuffix(FieldTitle, v)) +} + +// TitleEqualFold applies the EqualFold predicate on the "title" field. +func TitleEqualFold(v string) predicate.Episode { + return predicate.Episode(sql.FieldEqualFold(FieldTitle, v)) +} + +// TitleContainsFold applies the ContainsFold predicate on the "title" field. +func TitleContainsFold(v string) predicate.Episode { + return predicate.Episode(sql.FieldContainsFold(FieldTitle, v)) +} + +// AirDateEQ applies the EQ predicate on the "air_date" field. +func AirDateEQ(v time.Time) predicate.Episode { + return predicate.Episode(sql.FieldEQ(FieldAirDate, v)) +} + +// AirDateNEQ applies the NEQ predicate on the "air_date" field. +func AirDateNEQ(v time.Time) predicate.Episode { + return predicate.Episode(sql.FieldNEQ(FieldAirDate, v)) +} + +// AirDateIn applies the In predicate on the "air_date" field. +func AirDateIn(vs ...time.Time) predicate.Episode { + return predicate.Episode(sql.FieldIn(FieldAirDate, vs...)) +} + +// AirDateNotIn applies the NotIn predicate on the "air_date" field. +func AirDateNotIn(vs ...time.Time) predicate.Episode { + return predicate.Episode(sql.FieldNotIn(FieldAirDate, vs...)) +} + +// AirDateGT applies the GT predicate on the "air_date" field. +func AirDateGT(v time.Time) predicate.Episode { + return predicate.Episode(sql.FieldGT(FieldAirDate, v)) +} + +// AirDateGTE applies the GTE predicate on the "air_date" field. +func AirDateGTE(v time.Time) predicate.Episode { + return predicate.Episode(sql.FieldGTE(FieldAirDate, v)) +} + +// AirDateLT applies the LT predicate on the "air_date" field. +func AirDateLT(v time.Time) predicate.Episode { + return predicate.Episode(sql.FieldLT(FieldAirDate, v)) +} + +// AirDateLTE applies the LTE predicate on the "air_date" field. +func AirDateLTE(v time.Time) predicate.Episode { + return predicate.Episode(sql.FieldLTE(FieldAirDate, v)) +} + +// HasSeason applies the HasEdge predicate on the "season" edge. +func HasSeason() predicate.Episode { + return predicate.Episode(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, SeasonTable, SeasonColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasSeasonWith applies the HasEdge predicate on the "season" edge with a given conditions (other predicates). +func HasSeasonWith(preds ...predicate.Season) predicate.Episode { + return predicate.Episode(func(s *sql.Selector) { + step := newSeasonStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.Episode) predicate.Episode { + return predicate.Episode(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.Episode) predicate.Episode { + return predicate.Episode(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.Episode) predicate.Episode { + return predicate.Episode(sql.NotPredicates(p)) +} diff --git a/examples/ydb/ent/episode_create.go b/examples/ydb/ent/episode_create.go new file mode 100644 index 0000000000..8f2f4b2e7a --- /dev/null +++ b/examples/ydb/ent/episode_create.go @@ -0,0 +1,272 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/examples/ydb/ent/episode" + "entgo.io/ent/examples/ydb/ent/season" + "entgo.io/ent/schema/field" +) + +// EpisodeCreate is the builder for creating a Episode entity. +type EpisodeCreate struct { + config + mutation *EpisodeMutation + hooks []Hook + retryConfig sql.RetryConfig +} + +// SetSeasonID sets the "season_id" field. +func (_c *EpisodeCreate) SetSeasonID(v int64) *EpisodeCreate { + _c.mutation.SetSeasonID(v) + return _c +} + +// SetTitle sets the "title" field. +func (_c *EpisodeCreate) SetTitle(v string) *EpisodeCreate { + _c.mutation.SetTitle(v) + return _c +} + +// SetAirDate sets the "air_date" field. +func (_c *EpisodeCreate) SetAirDate(v time.Time) *EpisodeCreate { + _c.mutation.SetAirDate(v) + return _c +} + +// SetID sets the "id" field. +func (_c *EpisodeCreate) SetID(v int64) *EpisodeCreate { + _c.mutation.SetID(v) + return _c +} + +// SetSeason sets the "season" edge to the Season entity. +func (_c *EpisodeCreate) SetSeason(v *Season) *EpisodeCreate { + return _c.SetSeasonID(v.ID) +} + +// Mutation returns the EpisodeMutation object of the builder. +func (_c *EpisodeCreate) Mutation() *EpisodeMutation { + return _c.mutation +} + +// Save creates the Episode in the database. +func (_c *EpisodeCreate) Save(ctx context.Context) (*Episode, error) { + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (_c *EpisodeCreate) SaveX(ctx context.Context) *Episode { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *EpisodeCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *EpisodeCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_c *EpisodeCreate) check() error { + if _, ok := _c.mutation.SeasonID(); !ok { + return &ValidationError{Name: "season_id", err: errors.New(`ent: missing required field "Episode.season_id"`)} + } + if _, ok := _c.mutation.Title(); !ok { + return &ValidationError{Name: "title", err: errors.New(`ent: missing required field "Episode.title"`)} + } + if v, ok := _c.mutation.Title(); ok { + if err := episode.TitleValidator(v); err != nil { + return &ValidationError{Name: "title", err: fmt.Errorf(`ent: validator failed for field "Episode.title": %w`, err)} + } + } + if _, ok := _c.mutation.AirDate(); !ok { + return &ValidationError{Name: "air_date", err: errors.New(`ent: missing required field "Episode.air_date"`)} + } + if len(_c.mutation.SeasonIDs()) == 0 { + return &ValidationError{Name: "season", err: errors.New(`ent: missing required edge "Episode.season"`)} + } + return nil +} + +func (_c *EpisodeCreate) sqlSave(ctx context.Context) (*Episode, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + if _spec.ID.Value != _node.ID { + id := _spec.ID.Value.(int64) + _node.ID = int64(id) + } + _c.mutation.id = &_node.ID + _c.mutation.done = true + return _node, nil +} + +func (_c *EpisodeCreate) createSpec() (*Episode, *sqlgraph.CreateSpec) { + var ( + _node = &Episode{config: _c.config} + _spec = sqlgraph.NewCreateSpec(episode.Table, sqlgraph.NewFieldSpec(episode.FieldID, field.TypeInt64)) + ) + _spec.RetryConfig = _c.retryConfig + if id, ok := _c.mutation.ID(); ok { + _node.ID = id + _spec.ID.Value = id + } + if value, ok := _c.mutation.Title(); ok { + _spec.SetField(episode.FieldTitle, field.TypeString, value) + _node.Title = value + } + if value, ok := _c.mutation.AirDate(); ok { + _spec.SetField(episode.FieldAirDate, field.TypeTime, value) + _node.AirDate = value + } + if nodes := _c.mutation.SeasonIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: episode.SeasonTable, + Columns: []string{episode.SeasonColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(season.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.SeasonID = nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } + return _node, _spec +} + +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *EpisodeCreate) WithRetryOptions(opts ...any) *EpisodeCreate { + _c.retryConfig.Options = opts + return _c +} + +// EpisodeCreateBulk is the builder for creating many Episode entities in bulk. +type EpisodeCreateBulk struct { + config + err error + builders []*EpisodeCreate + retryConfig sql.RetryConfig +} + +// Save creates the Episode entities in the database. +func (_c *EpisodeCreateBulk) Save(ctx context.Context) ([]*Episode, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*Episode, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { + func(i int, root context.Context) { + builder := _c.builders[i] + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*EpisodeMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + if specs[i].ID.Value != nil && nodes[i].ID == 0 { + id := specs[i].ID.Value.(int64) + nodes[i].ID = int64(id) + } + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (_c *EpisodeCreateBulk) SaveX(ctx context.Context) []*Episode { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *EpisodeCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *EpisodeCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *EpisodeCreateBulk) WithRetryOptions(opts ...any) *EpisodeCreateBulk { + _c.retryConfig.Options = opts + return _c +} diff --git a/examples/ydb/ent/episode_delete.go b/examples/ydb/ent/episode_delete.go new file mode 100644 index 0000000000..240aac844f --- /dev/null +++ b/examples/ydb/ent/episode_delete.go @@ -0,0 +1,101 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/examples/ydb/ent/episode" + "entgo.io/ent/examples/ydb/ent/predicate" + "entgo.io/ent/schema/field" +) + +// EpisodeDelete is the builder for deleting a Episode entity. +type EpisodeDelete struct { + config + hooks []Hook + mutation *EpisodeMutation + retryConfig sql.RetryConfig +} + +// Where appends a list predicates to the EpisodeDelete builder. +func (_d *EpisodeDelete) Where(ps ...predicate.Episode) *EpisodeDelete { + _d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (_d *EpisodeDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *EpisodeDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (_d *EpisodeDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(episode.Table, sqlgraph.NewFieldSpec(episode.FieldID, field.TypeInt64)) + _spec.RetryConfig = _d.retryConfig + if ps := _d.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + _d.mutation.done = true + return affected, err +} + +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *EpisodeDelete) WithRetryOptions(opts ...any) *EpisodeDelete { + _d.retryConfig.Options = opts + return _d +} + +// EpisodeDeleteOne is the builder for deleting a single Episode entity. +type EpisodeDeleteOne struct { + _d *EpisodeDelete +} + +// Where appends a list predicates to the EpisodeDelete builder. +func (_d *EpisodeDeleteOne) Where(ps ...predicate.Episode) *EpisodeDeleteOne { + _d._d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query. +func (_d *EpisodeDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{episode.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *EpisodeDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/examples/ydb/ent/episode_query.go b/examples/ydb/ent/episode_query.go new file mode 100644 index 0000000000..162f0abf45 --- /dev/null +++ b/examples/ydb/ent/episode_query.go @@ -0,0 +1,620 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "fmt" + "math" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/examples/ydb/ent/episode" + "entgo.io/ent/examples/ydb/ent/predicate" + "entgo.io/ent/examples/ydb/ent/season" + "entgo.io/ent/schema/field" +) + +// EpisodeQuery is the builder for querying Episode entities. +type EpisodeQuery struct { + config + ctx *QueryContext + order []episode.OrderOption + inters []Interceptor + predicates []predicate.Episode + withSeason *SeasonQuery + retryConfig sql.RetryConfig + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the EpisodeQuery builder. +func (_q *EpisodeQuery) Where(ps ...predicate.Episode) *EpisodeQuery { + _q.predicates = append(_q.predicates, ps...) + return _q +} + +// Limit the number of records to be returned by this query. +func (_q *EpisodeQuery) Limit(limit int) *EpisodeQuery { + _q.ctx.Limit = &limit + return _q +} + +// Offset to start from. +func (_q *EpisodeQuery) Offset(offset int) *EpisodeQuery { + _q.ctx.Offset = &offset + return _q +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (_q *EpisodeQuery) Unique(unique bool) *EpisodeQuery { + _q.ctx.Unique = &unique + return _q +} + +// Order specifies how the records should be ordered. +func (_q *EpisodeQuery) Order(o ...episode.OrderOption) *EpisodeQuery { + _q.order = append(_q.order, o...) + return _q +} + +// QuerySeason chains the current query on the "season" edge. +func (_q *EpisodeQuery) QuerySeason() *SeasonQuery { + query := (&SeasonClient{config: _q.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + selector := _q.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(episode.Table, episode.FieldID, selector), + sqlgraph.To(season.Table, season.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, episode.SeasonTable, episode.SeasonColumn), + ) + fromU = sqlgraph.SetNeighbors(_q.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// First returns the first Episode entity from the query. +// Returns a *NotFoundError when no Episode was found. +func (_q *EpisodeQuery) First(ctx context.Context) (*Episode, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{episode.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (_q *EpisodeQuery) FirstX(ctx context.Context) *Episode { + node, err := _q.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first Episode ID from the query. +// Returns a *NotFoundError when no Episode ID was found. +func (_q *EpisodeQuery) FirstID(ctx context.Context) (id int64, err error) { + var ids []int64 + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{episode.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (_q *EpisodeQuery) FirstIDX(ctx context.Context) int64 { + id, err := _q.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single Episode entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one Episode entity is found. +// Returns a *NotFoundError when no Episode entities are found. +func (_q *EpisodeQuery) Only(ctx context.Context) (*Episode, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{episode.Label} + default: + return nil, &NotSingularError{episode.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (_q *EpisodeQuery) OnlyX(ctx context.Context) *Episode { + node, err := _q.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only Episode ID in the query. +// Returns a *NotSingularError when more than one Episode ID is found. +// Returns a *NotFoundError when no entities are found. +func (_q *EpisodeQuery) OnlyID(ctx context.Context) (id int64, err error) { + var ids []int64 + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{episode.Label} + default: + err = &NotSingularError{episode.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (_q *EpisodeQuery) OnlyIDX(ctx context.Context) int64 { + id, err := _q.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of Episodes. +func (_q *EpisodeQuery) All(ctx context.Context) ([]*Episode, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*Episode, *EpisodeQuery]() + return withInterceptors[[]*Episode](ctx, _q, qr, _q.inters) +} + +// AllX is like All, but panics if an error occurs. +func (_q *EpisodeQuery) AllX(ctx context.Context) []*Episode { + nodes, err := _q.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of Episode IDs. +func (_q *EpisodeQuery) IDs(ctx context.Context) (ids []int64, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(episode.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (_q *EpisodeQuery) IDsX(ctx context.Context) []int64 { + ids, err := _q.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (_q *EpisodeQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, _q, querierCount[*EpisodeQuery](), _q.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (_q *EpisodeQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (_q *EpisodeQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("ent: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (_q *EpisodeQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the EpisodeQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (_q *EpisodeQuery) Clone() *EpisodeQuery { + if _q == nil { + return nil + } + return &EpisodeQuery{ + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]episode.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.Episode{}, _q.predicates...), + withSeason: _q.withSeason.Clone(), + // clone intermediate query. + sql: _q.sql.Clone(), + path: _q.path, + } +} + +// WithSeason tells the query-builder to eager-load the nodes that are connected to +// the "season" edge. The optional arguments are used to configure the query builder of the edge. +func (_q *EpisodeQuery) WithSeason(opts ...func(*SeasonQuery)) *EpisodeQuery { + query := (&SeasonClient{config: _q.config}).Query() + for _, opt := range opts { + opt(query) + } + _q.withSeason = query + return _q +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// SeasonID int64 `json:"season_id,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.Episode.Query(). +// GroupBy(episode.FieldSeasonID). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +func (_q *EpisodeQuery) GroupBy(field string, fields ...string) *EpisodeGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &EpisodeGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields + grbuild.label = episode.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// SeasonID int64 `json:"season_id,omitempty"` +// } +// +// client.Episode.Query(). +// Select(episode.FieldSeasonID). +// Scan(ctx, &v) +func (_q *EpisodeQuery) Select(fields ...string) *EpisodeSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &EpisodeSelect{EpisodeQuery: _q} + sbuild.label = episode.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a EpisodeSelect configured with the given aggregations. +func (_q *EpisodeQuery) Aggregate(fns ...AggregateFunc) *EpisodeSelect { + return _q.Select().Aggregate(fns...) +} + +func (_q *EpisodeQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { + if !episode.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if _q.path != nil { + prev, err := _q.path(ctx) + if err != nil { + return err + } + _q.sql = prev + } + return nil +} + +func (_q *EpisodeQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Episode, error) { + var ( + nodes = []*Episode{} + _spec = _q.querySpec() + loadedTypes = [1]bool{ + _q.withSeason != nil, + } + ) + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*Episode).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &Episode{config: _q.config} + nodes = append(nodes, node) + node.Edges.loadedTypes = loadedTypes + return node.assignValues(columns, values) + } + _spec.RetryConfig = _q.retryConfig + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + if query := _q.withSeason; query != nil { + if err := _q.loadSeason(ctx, query, nodes, nil, + func(n *Episode, e *Season) { n.Edges.Season = e }); err != nil { + return nil, err + } + } + return nodes, nil +} + +func (_q *EpisodeQuery) loadSeason(ctx context.Context, query *SeasonQuery, nodes []*Episode, init func(*Episode), assign func(*Episode, *Season)) error { + ids := make([]int64, 0, len(nodes)) + nodeids := make(map[int64][]*Episode) + for i := range nodes { + fk := nodes[i].SeasonID + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(season.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "season_id" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} + +func (_q *EpisodeQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + _spec.RetryConfig = _q.retryConfig + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique + } + return sqlgraph.CountNodes(ctx, _q.driver, _spec) +} + +func (_q *EpisodeQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(episode.Table, episode.Columns, sqlgraph.NewFieldSpec(episode.FieldID, field.TypeInt64)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true + } + if fields := _q.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, episode.FieldID) + for i := range fields { + if fields[i] != episode.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + if _q.withSeason != nil { + _spec.Node.AddColumnOnce(episode.FieldSeasonID) + } + } + if ps := _q.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := _q.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := _q.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := _q.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (_q *EpisodeQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) + t1 := builder.Table(episode.Table) + columns := _q.ctx.Fields + if len(columns) == 0 { + columns = episode.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if _q.sql != nil { + selector = _q.sql + selector.Select(selector.Columns(columns...)...) + } + if _q.ctx.Unique != nil && *_q.ctx.Unique { + selector.Distinct() + } + for _, p := range _q.predicates { + p(selector) + } + for _, p := range _q.order { + p(selector) + } + if offset := _q.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := _q.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *EpisodeQuery) WithRetryOptions(opts ...any) *EpisodeQuery { + _q.retryConfig.Options = opts + return _q +} + +// EpisodeGroupBy is the group-by builder for Episode entities. +type EpisodeGroupBy struct { + selector + build *EpisodeQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (_g *EpisodeGroupBy) Aggregate(fns ...AggregateFunc) *EpisodeGroupBy { + _g.fns = append(_g.fns, fns...) + return _g +} + +// Scan applies the selector query and scans the result into the given value. +func (_g *EpisodeGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*EpisodeQuery, *EpisodeGroupBy](ctx, _g.build, _g, _g.build.inters, v) +} + +func (_g *EpisodeGroupBy) sqlScan(ctx context.Context, root *EpisodeQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*_g.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// EpisodeSelect is the builder for selecting fields of Episode entities. +type EpisodeSelect struct { + *EpisodeQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *EpisodeSelect) Aggregate(fns ...AggregateFunc) *EpisodeSelect { + _s.fns = append(_s.fns, fns...) + return _s +} + +// Scan applies the selector query and scans the result into the given value. +func (_s *EpisodeSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*EpisodeQuery, *EpisodeSelect](ctx, _s.EpisodeQuery, _s, _s.inters, v) +} + +func (_s *EpisodeSelect) sqlScan(ctx context.Context, root *EpisodeQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/examples/ydb/ent/episode_update.go b/examples/ydb/ent/episode_update.go new file mode 100644 index 0000000000..0b844a353a --- /dev/null +++ b/examples/ydb/ent/episode_update.go @@ -0,0 +1,407 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/examples/ydb/ent/episode" + "entgo.io/ent/examples/ydb/ent/predicate" + "entgo.io/ent/examples/ydb/ent/season" + "entgo.io/ent/schema/field" +) + +// EpisodeUpdate is the builder for updating Episode entities. +type EpisodeUpdate struct { + config + hooks []Hook + mutation *EpisodeMutation + retryConfig sql.RetryConfig +} + +// Where appends a list predicates to the EpisodeUpdate builder. +func (_u *EpisodeUpdate) Where(ps ...predicate.Episode) *EpisodeUpdate { + _u.mutation.Where(ps...) + return _u +} + +// SetSeasonID sets the "season_id" field. +func (_u *EpisodeUpdate) SetSeasonID(v int64) *EpisodeUpdate { + _u.mutation.SetSeasonID(v) + return _u +} + +// SetNillableSeasonID sets the "season_id" field if the given value is not nil. +func (_u *EpisodeUpdate) SetNillableSeasonID(v *int64) *EpisodeUpdate { + if v != nil { + _u.SetSeasonID(*v) + } + return _u +} + +// SetTitle sets the "title" field. +func (_u *EpisodeUpdate) SetTitle(v string) *EpisodeUpdate { + _u.mutation.SetTitle(v) + return _u +} + +// SetNillableTitle sets the "title" field if the given value is not nil. +func (_u *EpisodeUpdate) SetNillableTitle(v *string) *EpisodeUpdate { + if v != nil { + _u.SetTitle(*v) + } + return _u +} + +// SetAirDate sets the "air_date" field. +func (_u *EpisodeUpdate) SetAirDate(v time.Time) *EpisodeUpdate { + _u.mutation.SetAirDate(v) + return _u +} + +// SetNillableAirDate sets the "air_date" field if the given value is not nil. +func (_u *EpisodeUpdate) SetNillableAirDate(v *time.Time) *EpisodeUpdate { + if v != nil { + _u.SetAirDate(*v) + } + return _u +} + +// SetSeason sets the "season" edge to the Season entity. +func (_u *EpisodeUpdate) SetSeason(v *Season) *EpisodeUpdate { + return _u.SetSeasonID(v.ID) +} + +// Mutation returns the EpisodeMutation object of the builder. +func (_u *EpisodeUpdate) Mutation() *EpisodeMutation { + return _u.mutation +} + +// ClearSeason clears the "season" edge to the Season entity. +func (_u *EpisodeUpdate) ClearSeason() *EpisodeUpdate { + _u.mutation.ClearSeason() + return _u +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (_u *EpisodeUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *EpisodeUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (_u *EpisodeUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *EpisodeUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_u *EpisodeUpdate) check() error { + if v, ok := _u.mutation.Title(); ok { + if err := episode.TitleValidator(v); err != nil { + return &ValidationError{Name: "title", err: fmt.Errorf(`ent: validator failed for field "Episode.title": %w`, err)} + } + } + if _u.mutation.SeasonCleared() && len(_u.mutation.SeasonIDs()) > 0 { + return errors.New(`ent: clearing a required unique edge "Episode.season"`) + } + return nil +} + +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *EpisodeUpdate) WithRetryOptions(opts ...any) *EpisodeUpdate { + _u.retryConfig.Options = opts + return _u +} + +func (_u *EpisodeUpdate) sqlSave(ctx context.Context) (_node int, err error) { + if err := _u.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(episode.Table, episode.Columns, sqlgraph.NewFieldSpec(episode.FieldID, field.TypeInt64)) + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.Title(); ok { + _spec.SetField(episode.FieldTitle, field.TypeString, value) + } + if value, ok := _u.mutation.AirDate(); ok { + _spec.SetField(episode.FieldAirDate, field.TypeTime, value) + } + if _u.mutation.SeasonCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: episode.SeasonTable, + Columns: []string{episode.SeasonColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(season.FieldID, field.TypeInt64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.SeasonIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: episode.SeasonTable, + Columns: []string{episode.SeasonColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(season.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + _spec.RetryConfig = _u.retryConfig + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { + if sqlgraph.IsNotFound(err) { + err = &NotFoundError{episode.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + _u.mutation.done = true + return _node, nil +} + +// EpisodeUpdateOne is the builder for updating a single Episode entity. +type EpisodeUpdateOne struct { + config + fields []string + hooks []Hook + mutation *EpisodeMutation + retryConfig sql.RetryConfig +} + +// SetSeasonID sets the "season_id" field. +func (_u *EpisodeUpdateOne) SetSeasonID(v int64) *EpisodeUpdateOne { + _u.mutation.SetSeasonID(v) + return _u +} + +// SetNillableSeasonID sets the "season_id" field if the given value is not nil. +func (_u *EpisodeUpdateOne) SetNillableSeasonID(v *int64) *EpisodeUpdateOne { + if v != nil { + _u.SetSeasonID(*v) + } + return _u +} + +// SetTitle sets the "title" field. +func (_u *EpisodeUpdateOne) SetTitle(v string) *EpisodeUpdateOne { + _u.mutation.SetTitle(v) + return _u +} + +// SetNillableTitle sets the "title" field if the given value is not nil. +func (_u *EpisodeUpdateOne) SetNillableTitle(v *string) *EpisodeUpdateOne { + if v != nil { + _u.SetTitle(*v) + } + return _u +} + +// SetAirDate sets the "air_date" field. +func (_u *EpisodeUpdateOne) SetAirDate(v time.Time) *EpisodeUpdateOne { + _u.mutation.SetAirDate(v) + return _u +} + +// SetNillableAirDate sets the "air_date" field if the given value is not nil. +func (_u *EpisodeUpdateOne) SetNillableAirDate(v *time.Time) *EpisodeUpdateOne { + if v != nil { + _u.SetAirDate(*v) + } + return _u +} + +// SetSeason sets the "season" edge to the Season entity. +func (_u *EpisodeUpdateOne) SetSeason(v *Season) *EpisodeUpdateOne { + return _u.SetSeasonID(v.ID) +} + +// Mutation returns the EpisodeMutation object of the builder. +func (_u *EpisodeUpdateOne) Mutation() *EpisodeMutation { + return _u.mutation +} + +// ClearSeason clears the "season" edge to the Season entity. +func (_u *EpisodeUpdateOne) ClearSeason() *EpisodeUpdateOne { + _u.mutation.ClearSeason() + return _u +} + +// Where appends a list predicates to the EpisodeUpdate builder. +func (_u *EpisodeUpdateOne) Where(ps ...predicate.Episode) *EpisodeUpdateOne { + _u.mutation.Where(ps...) + return _u +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (_u *EpisodeUpdateOne) Select(field string, fields ...string) *EpisodeUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u +} + +// Save executes the query and returns the updated Episode entity. +func (_u *EpisodeUpdateOne) Save(ctx context.Context) (*Episode, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *EpisodeUpdateOne) SaveX(ctx context.Context) *Episode { + node, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (_u *EpisodeUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *EpisodeUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_u *EpisodeUpdateOne) check() error { + if v, ok := _u.mutation.Title(); ok { + if err := episode.TitleValidator(v); err != nil { + return &ValidationError{Name: "title", err: fmt.Errorf(`ent: validator failed for field "Episode.title": %w`, err)} + } + } + if _u.mutation.SeasonCleared() && len(_u.mutation.SeasonIDs()) > 0 { + return errors.New(`ent: clearing a required unique edge "Episode.season"`) + } + return nil +} + +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *EpisodeUpdateOne) WithRetryOptions(opts ...any) *EpisodeUpdateOne { + _u.retryConfig.Options = opts + return _u +} + +func (_u *EpisodeUpdateOne) sqlSave(ctx context.Context) (_node *Episode, err error) { + if err := _u.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(episode.Table, episode.Columns, sqlgraph.NewFieldSpec(episode.FieldID, field.TypeInt64)) + id, ok := _u.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "Episode.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := _u.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, episode.FieldID) + for _, f := range fields { + if !episode.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != episode.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.Title(); ok { + _spec.SetField(episode.FieldTitle, field.TypeString, value) + } + if value, ok := _u.mutation.AirDate(); ok { + _spec.SetField(episode.FieldAirDate, field.TypeTime, value) + } + if _u.mutation.SeasonCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: episode.SeasonTable, + Columns: []string{episode.SeasonColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(season.FieldID, field.TypeInt64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.SeasonIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: episode.SeasonTable, + Columns: []string{episode.SeasonColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(season.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + _spec.RetryConfig = _u.retryConfig + _node = &Episode{config: _u.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { + if sqlgraph.IsNotFound(err) { + err = &NotFoundError{episode.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + _u.mutation.done = true + return _node, nil +} diff --git a/examples/ydb/ent/generate.go b/examples/ydb/ent/generate.go new file mode 100644 index 0000000000..14d86db5b5 --- /dev/null +++ b/examples/ydb/ent/generate.go @@ -0,0 +1,7 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +package ent + +//go:generate go run entc.go diff --git a/examples/ydb/ent/hook/hook.go b/examples/ydb/ent/hook/hook.go new file mode 100644 index 0000000000..f833b57ead --- /dev/null +++ b/examples/ydb/ent/hook/hook.go @@ -0,0 +1,227 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package hook + +import ( + "context" + "fmt" + + "entgo.io/ent/examples/ydb/ent" +) + +// The EpisodeFunc type is an adapter to allow the use of ordinary +// function as Episode mutator. +type EpisodeFunc func(context.Context, *ent.EpisodeMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f EpisodeFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.EpisodeMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.EpisodeMutation", m) +} + +// The SeasonFunc type is an adapter to allow the use of ordinary +// function as Season mutator. +type SeasonFunc func(context.Context, *ent.SeasonMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f SeasonFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.SeasonMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.SeasonMutation", m) +} + +// The SeriesFunc type is an adapter to allow the use of ordinary +// function as Series mutator. +type SeriesFunc func(context.Context, *ent.SeriesMutation) (ent.Value, error) + +// Mutate calls f(ctx, m). +func (f SeriesFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if mv, ok := m.(*ent.SeriesMutation); ok { + return f(ctx, mv) + } + return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.SeriesMutation", m) +} + +// Condition is a hook condition function. +type Condition func(context.Context, ent.Mutation) bool + +// And groups conditions with the AND operator. +func And(first, second Condition, rest ...Condition) Condition { + return func(ctx context.Context, m ent.Mutation) bool { + if !first(ctx, m) || !second(ctx, m) { + return false + } + for _, cond := range rest { + if !cond(ctx, m) { + return false + } + } + return true + } +} + +// Or groups conditions with the OR operator. +func Or(first, second Condition, rest ...Condition) Condition { + return func(ctx context.Context, m ent.Mutation) bool { + if first(ctx, m) || second(ctx, m) { + return true + } + for _, cond := range rest { + if cond(ctx, m) { + return true + } + } + return false + } +} + +// Not negates a given condition. +func Not(cond Condition) Condition { + return func(ctx context.Context, m ent.Mutation) bool { + return !cond(ctx, m) + } +} + +// HasOp is a condition testing mutation operation. +func HasOp(op ent.Op) Condition { + return func(_ context.Context, m ent.Mutation) bool { + return m.Op().Is(op) + } +} + +// HasAddedFields is a condition validating `.AddedField` on fields. +func HasAddedFields(field string, fields ...string) Condition { + return func(_ context.Context, m ent.Mutation) bool { + if _, exists := m.AddedField(field); !exists { + return false + } + for _, field := range fields { + if _, exists := m.AddedField(field); !exists { + return false + } + } + return true + } +} + +// HasClearedFields is a condition validating `.FieldCleared` on fields. +func HasClearedFields(field string, fields ...string) Condition { + return func(_ context.Context, m ent.Mutation) bool { + if exists := m.FieldCleared(field); !exists { + return false + } + for _, field := range fields { + if exists := m.FieldCleared(field); !exists { + return false + } + } + return true + } +} + +// HasFields is a condition validating `.Field` on fields. +func HasFields(field string, fields ...string) Condition { + return func(_ context.Context, m ent.Mutation) bool { + if _, exists := m.Field(field); !exists { + return false + } + for _, field := range fields { + if _, exists := m.Field(field); !exists { + return false + } + } + return true + } +} + +// If executes the given hook under condition. +// +// hook.If(ComputeAverage, And(HasFields(...), HasAddedFields(...))) +func If(hk ent.Hook, cond Condition) ent.Hook { + return func(next ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) { + if cond(ctx, m) { + return hk(next).Mutate(ctx, m) + } + return next.Mutate(ctx, m) + }) + } +} + +// On executes the given hook only for the given operation. +// +// hook.On(Log, ent.Delete|ent.Create) +func On(hk ent.Hook, op ent.Op) ent.Hook { + return If(hk, HasOp(op)) +} + +// Unless skips the given hook only for the given operation. +// +// hook.Unless(Log, ent.Update|ent.UpdateOne) +func Unless(hk ent.Hook, op ent.Op) ent.Hook { + return If(hk, Not(HasOp(op))) +} + +// FixedError is a hook returning a fixed error. +func FixedError(err error) ent.Hook { + return func(ent.Mutator) ent.Mutator { + return ent.MutateFunc(func(context.Context, ent.Mutation) (ent.Value, error) { + return nil, err + }) + } +} + +// Reject returns a hook that rejects all operations that match op. +// +// func (T) Hooks() []ent.Hook { +// return []ent.Hook{ +// Reject(ent.Delete|ent.Update), +// } +// } +func Reject(op ent.Op) ent.Hook { + hk := FixedError(fmt.Errorf("%s operation is not allowed", op)) + return On(hk, op) +} + +// Chain acts as a list of hooks and is effectively immutable. +// Once created, it will always hold the same set of hooks in the same order. +type Chain struct { + hooks []ent.Hook +} + +// NewChain creates a new chain of hooks. +func NewChain(hooks ...ent.Hook) Chain { + return Chain{append([]ent.Hook(nil), hooks...)} +} + +// Hook chains the list of hooks and returns the final hook. +func (c Chain) Hook() ent.Hook { + return func(mutator ent.Mutator) ent.Mutator { + for i := len(c.hooks) - 1; i >= 0; i-- { + mutator = c.hooks[i](mutator) + } + return mutator + } +} + +// Append extends a chain, adding the specified hook +// as the last ones in the mutation flow. +func (c Chain) Append(hooks ...ent.Hook) Chain { + newHooks := make([]ent.Hook, 0, len(c.hooks)+len(hooks)) + newHooks = append(newHooks, c.hooks...) + newHooks = append(newHooks, hooks...) + return Chain{newHooks} +} + +// Extend extends a chain, adding the specified chain +// as the last ones in the mutation flow. +func (c Chain) Extend(chain Chain) Chain { + return c.Append(chain.hooks...) +} diff --git a/examples/ydb/ent/migrate/migrate.go b/examples/ydb/ent/migrate/migrate.go new file mode 100644 index 0000000000..0a632cc3d3 --- /dev/null +++ b/examples/ydb/ent/migrate/migrate.go @@ -0,0 +1,68 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package migrate + +import ( + "context" + "fmt" + "io" + + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/sql/schema" +) + +var ( + // WithGlobalUniqueID sets the universal ids options to the migration. + // If this option is enabled, ent migration will allocate a 1<<32 range + // for the ids of each entity (table). + // Note that this option cannot be applied on tables that already exist. + WithGlobalUniqueID = schema.WithGlobalUniqueID + // WithDropColumn sets the drop column option to the migration. + // If this option is enabled, ent migration will drop old columns + // that were used for both fields and edges. This defaults to false. + WithDropColumn = schema.WithDropColumn + // WithDropIndex sets the drop index option to the migration. + // If this option is enabled, ent migration will drop old indexes + // that were defined in the schema. This defaults to false. + // Note that unique constraints are defined using `UNIQUE INDEX`, + // and therefore, it's recommended to enable this option to get more + // flexibility in the schema changes. + WithDropIndex = schema.WithDropIndex + // WithForeignKeys enables creating foreign-key in schema DDL. This defaults to true. + WithForeignKeys = schema.WithForeignKeys +) + +// Schema is the API for creating, migrating and dropping a schema. +type Schema struct { + drv dialect.Driver +} + +// NewSchema creates a new schema client. +func NewSchema(drv dialect.Driver) *Schema { return &Schema{drv: drv} } + +// Create creates all schema resources. +func (s *Schema) Create(ctx context.Context, opts ...schema.MigrateOption) error { + return Create(ctx, s, Tables, opts...) +} + +// Create creates all table resources using the given schema driver. +func Create(ctx context.Context, s *Schema, tables []*schema.Table, opts ...schema.MigrateOption) error { + migrate, err := schema.NewMigrate(s.drv, opts...) + if err != nil { + return fmt.Errorf("ent/migrate: %w", err) + } + return migrate.Create(ctx, tables...) +} + +// WriteTo writes the schema changes to w instead of running them against the database. +// +// if err := client.Schema.WriteTo(context.Background(), os.Stdout); err != nil { +// log.Fatal(err) +// } +func (s *Schema) WriteTo(ctx context.Context, w io.Writer, opts ...schema.MigrateOption) error { + return Create(ctx, &Schema{drv: &schema.WriteDriver{Writer: w, Driver: s.drv}}, Tables, opts...) +} diff --git a/examples/ydb/ent/migrate/schema.go b/examples/ydb/ent/migrate/schema.go new file mode 100644 index 0000000000..fa2f7af054 --- /dev/null +++ b/examples/ydb/ent/migrate/schema.go @@ -0,0 +1,92 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package migrate + +import ( + "entgo.io/ent/dialect/entsql" + "entgo.io/ent/dialect/sql/schema" + "entgo.io/ent/schema/field" +) + +var ( + // EpisodesColumns holds the columns for the "episodes" table. + EpisodesColumns = []*schema.Column{ + {Name: "id", Type: field.TypeInt64, Increment: true}, + {Name: "title", Type: field.TypeString}, + {Name: "air_date", Type: field.TypeTime}, + {Name: "season_id", Type: field.TypeInt64}, + } + // EpisodesTable holds the schema information for the "episodes" table. + EpisodesTable = &schema.Table{ + Name: "episodes", + Columns: EpisodesColumns, + PrimaryKey: []*schema.Column{EpisodesColumns[0]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "episodes_seasons_episodes", + Columns: []*schema.Column{EpisodesColumns[3]}, + RefColumns: []*schema.Column{SeasonsColumns[0]}, + OnDelete: schema.NoAction, + }, + }, + } + // SeasonsColumns holds the columns for the "seasons" table. + SeasonsColumns = []*schema.Column{ + {Name: "id", Type: field.TypeInt64, Increment: true}, + {Name: "title", Type: field.TypeString}, + {Name: "first_aired", Type: field.TypeTime}, + {Name: "last_aired", Type: field.TypeTime}, + {Name: "series_id", Type: field.TypeInt64}, + } + // SeasonsTable holds the schema information for the "seasons" table. + SeasonsTable = &schema.Table{ + Name: "seasons", + Columns: SeasonsColumns, + PrimaryKey: []*schema.Column{SeasonsColumns[0]}, + ForeignKeys: []*schema.ForeignKey{ + { + Symbol: "seasons_series_seasons", + Columns: []*schema.Column{SeasonsColumns[4]}, + RefColumns: []*schema.Column{SeriesColumns[0]}, + OnDelete: schema.NoAction, + }, + }, + } + // SeriesColumns holds the columns for the "series" table. + SeriesColumns = []*schema.Column{ + {Name: "id", Type: field.TypeInt64, Increment: true}, + {Name: "title", Type: field.TypeString}, + {Name: "info", Type: field.TypeString, Nullable: true, Size: 2147483647}, + {Name: "release_date", Type: field.TypeTime}, + } + // SeriesTable holds the schema information for the "series" table. + SeriesTable = &schema.Table{ + Name: "series", + Columns: SeriesColumns, + PrimaryKey: []*schema.Column{SeriesColumns[0]}, + } + // Tables holds all the tables in the schema. + Tables = []*schema.Table{ + EpisodesTable, + SeasonsTable, + SeriesTable, + } +) + +func init() { + EpisodesTable.ForeignKeys[0].RefTable = SeasonsTable + EpisodesTable.Annotation = &entsql.Annotation{ + Table: "episodes", + } + SeasonsTable.ForeignKeys[0].RefTable = SeriesTable + SeasonsTable.Annotation = &entsql.Annotation{ + Table: "seasons", + } + SeriesTable.Annotation = &entsql.Annotation{ + Table: "series", + } +} diff --git a/examples/ydb/ent/mutation.go b/examples/ydb/ent/mutation.go new file mode 100644 index 0000000000..8ad18be334 --- /dev/null +++ b/examples/ydb/ent/mutation.go @@ -0,0 +1,1724 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "sync" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/examples/ydb/ent/episode" + "entgo.io/ent/examples/ydb/ent/predicate" + "entgo.io/ent/examples/ydb/ent/season" + "entgo.io/ent/examples/ydb/ent/series" +) + +const ( + // Operation types. + OpCreate = ent.OpCreate + OpDelete = ent.OpDelete + OpDeleteOne = ent.OpDeleteOne + OpUpdate = ent.OpUpdate + OpUpdateOne = ent.OpUpdateOne + + // Node types. + TypeEpisode = "Episode" + TypeSeason = "Season" + TypeSeries = "Series" +) + +// EpisodeMutation represents an operation that mutates the Episode nodes in the graph. +type EpisodeMutation struct { + config + op Op + typ string + id *int64 + title *string + air_date *time.Time + clearedFields map[string]struct{} + season *int64 + clearedseason bool + done bool + oldValue func(context.Context) (*Episode, error) + predicates []predicate.Episode +} + +var _ ent.Mutation = (*EpisodeMutation)(nil) + +// episodeOption allows management of the mutation configuration using functional options. +type episodeOption func(*EpisodeMutation) + +// newEpisodeMutation creates new mutation for the Episode entity. +func newEpisodeMutation(c config, op Op, opts ...episodeOption) *EpisodeMutation { + m := &EpisodeMutation{ + config: c, + op: op, + typ: TypeEpisode, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withEpisodeID sets the ID field of the mutation. +func withEpisodeID(id int64) episodeOption { + return func(m *EpisodeMutation) { + var ( + err error + once sync.Once + value *Episode + ) + m.oldValue = func(ctx context.Context) (*Episode, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().Episode.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withEpisode sets the old Episode of the mutation. +func withEpisode(node *Episode) episodeOption { + return func(m *EpisodeMutation) { + m.oldValue = func(context.Context) (*Episode, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m EpisodeMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m EpisodeMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that this +// operation is only accepted on creation of Episode entities. +func (m *EpisodeMutation) SetID(id int64) { + m.id = &id +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *EpisodeMutation) ID() (id int64, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *EpisodeMutation) IDs(ctx context.Context) ([]int64, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []int64{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().Episode.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetSeasonID sets the "season_id" field. +func (m *EpisodeMutation) SetSeasonID(i int64) { + m.season = &i +} + +// SeasonID returns the value of the "season_id" field in the mutation. +func (m *EpisodeMutation) SeasonID() (r int64, exists bool) { + v := m.season + if v == nil { + return + } + return *v, true +} + +// OldSeasonID returns the old "season_id" field's value of the Episode entity. +// If the Episode object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *EpisodeMutation) OldSeasonID(ctx context.Context) (v int64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldSeasonID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldSeasonID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldSeasonID: %w", err) + } + return oldValue.SeasonID, nil +} + +// ResetSeasonID resets all changes to the "season_id" field. +func (m *EpisodeMutation) ResetSeasonID() { + m.season = nil +} + +// SetTitle sets the "title" field. +func (m *EpisodeMutation) SetTitle(s string) { + m.title = &s +} + +// Title returns the value of the "title" field in the mutation. +func (m *EpisodeMutation) Title() (r string, exists bool) { + v := m.title + if v == nil { + return + } + return *v, true +} + +// OldTitle returns the old "title" field's value of the Episode entity. +// If the Episode object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *EpisodeMutation) OldTitle(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldTitle is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldTitle requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldTitle: %w", err) + } + return oldValue.Title, nil +} + +// ResetTitle resets all changes to the "title" field. +func (m *EpisodeMutation) ResetTitle() { + m.title = nil +} + +// SetAirDate sets the "air_date" field. +func (m *EpisodeMutation) SetAirDate(t time.Time) { + m.air_date = &t +} + +// AirDate returns the value of the "air_date" field in the mutation. +func (m *EpisodeMutation) AirDate() (r time.Time, exists bool) { + v := m.air_date + if v == nil { + return + } + return *v, true +} + +// OldAirDate returns the old "air_date" field's value of the Episode entity. +// If the Episode object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *EpisodeMutation) OldAirDate(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldAirDate is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldAirDate requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldAirDate: %w", err) + } + return oldValue.AirDate, nil +} + +// ResetAirDate resets all changes to the "air_date" field. +func (m *EpisodeMutation) ResetAirDate() { + m.air_date = nil +} + +// ClearSeason clears the "season" edge to the Season entity. +func (m *EpisodeMutation) ClearSeason() { + m.clearedseason = true + m.clearedFields[episode.FieldSeasonID] = struct{}{} +} + +// SeasonCleared reports if the "season" edge to the Season entity was cleared. +func (m *EpisodeMutation) SeasonCleared() bool { + return m.clearedseason +} + +// SeasonIDs returns the "season" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// SeasonID instead. It exists only for internal usage by the builders. +func (m *EpisodeMutation) SeasonIDs() (ids []int64) { + if id := m.season; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetSeason resets all changes to the "season" edge. +func (m *EpisodeMutation) ResetSeason() { + m.season = nil + m.clearedseason = false +} + +// Where appends a list predicates to the EpisodeMutation builder. +func (m *EpisodeMutation) Where(ps ...predicate.Episode) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the EpisodeMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *EpisodeMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.Episode, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *EpisodeMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *EpisodeMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (Episode). +func (m *EpisodeMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *EpisodeMutation) Fields() []string { + fields := make([]string, 0, 3) + if m.season != nil { + fields = append(fields, episode.FieldSeasonID) + } + if m.title != nil { + fields = append(fields, episode.FieldTitle) + } + if m.air_date != nil { + fields = append(fields, episode.FieldAirDate) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *EpisodeMutation) Field(name string) (ent.Value, bool) { + switch name { + case episode.FieldSeasonID: + return m.SeasonID() + case episode.FieldTitle: + return m.Title() + case episode.FieldAirDate: + return m.AirDate() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *EpisodeMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case episode.FieldSeasonID: + return m.OldSeasonID(ctx) + case episode.FieldTitle: + return m.OldTitle(ctx) + case episode.FieldAirDate: + return m.OldAirDate(ctx) + } + return nil, fmt.Errorf("unknown Episode field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *EpisodeMutation) SetField(name string, value ent.Value) error { + switch name { + case episode.FieldSeasonID: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetSeasonID(v) + return nil + case episode.FieldTitle: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetTitle(v) + return nil + case episode.FieldAirDate: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetAirDate(v) + return nil + } + return fmt.Errorf("unknown Episode field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *EpisodeMutation) AddedFields() []string { + var fields []string + return fields +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *EpisodeMutation) AddedField(name string) (ent.Value, bool) { + switch name { + } + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *EpisodeMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Episode numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *EpisodeMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *EpisodeMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *EpisodeMutation) ClearField(name string) error { + return fmt.Errorf("unknown Episode nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *EpisodeMutation) ResetField(name string) error { + switch name { + case episode.FieldSeasonID: + m.ResetSeasonID() + return nil + case episode.FieldTitle: + m.ResetTitle() + return nil + case episode.FieldAirDate: + m.ResetAirDate() + return nil + } + return fmt.Errorf("unknown Episode field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *EpisodeMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.season != nil { + edges = append(edges, episode.EdgeSeason) + } + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *EpisodeMutation) AddedIDs(name string) []ent.Value { + switch name { + case episode.EdgeSeason: + if id := m.season; id != nil { + return []ent.Value{*id} + } + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *EpisodeMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *EpisodeMutation) RemovedIDs(name string) []ent.Value { + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *EpisodeMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + if m.clearedseason { + edges = append(edges, episode.EdgeSeason) + } + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *EpisodeMutation) EdgeCleared(name string) bool { + switch name { + case episode.EdgeSeason: + return m.clearedseason + } + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *EpisodeMutation) ClearEdge(name string) error { + switch name { + case episode.EdgeSeason: + m.ClearSeason() + return nil + } + return fmt.Errorf("unknown Episode unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *EpisodeMutation) ResetEdge(name string) error { + switch name { + case episode.EdgeSeason: + m.ResetSeason() + return nil + } + return fmt.Errorf("unknown Episode edge %s", name) +} + +// SeasonMutation represents an operation that mutates the Season nodes in the graph. +type SeasonMutation struct { + config + op Op + typ string + id *int64 + title *string + first_aired *time.Time + last_aired *time.Time + clearedFields map[string]struct{} + series *int64 + clearedseries bool + episodes map[int64]struct{} + removedepisodes map[int64]struct{} + clearedepisodes bool + done bool + oldValue func(context.Context) (*Season, error) + predicates []predicate.Season +} + +var _ ent.Mutation = (*SeasonMutation)(nil) + +// seasonOption allows management of the mutation configuration using functional options. +type seasonOption func(*SeasonMutation) + +// newSeasonMutation creates new mutation for the Season entity. +func newSeasonMutation(c config, op Op, opts ...seasonOption) *SeasonMutation { + m := &SeasonMutation{ + config: c, + op: op, + typ: TypeSeason, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withSeasonID sets the ID field of the mutation. +func withSeasonID(id int64) seasonOption { + return func(m *SeasonMutation) { + var ( + err error + once sync.Once + value *Season + ) + m.oldValue = func(ctx context.Context) (*Season, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().Season.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withSeason sets the old Season of the mutation. +func withSeason(node *Season) seasonOption { + return func(m *SeasonMutation) { + m.oldValue = func(context.Context) (*Season, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m SeasonMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m SeasonMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that this +// operation is only accepted on creation of Season entities. +func (m *SeasonMutation) SetID(id int64) { + m.id = &id +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *SeasonMutation) ID() (id int64, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *SeasonMutation) IDs(ctx context.Context) ([]int64, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []int64{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().Season.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetSeriesID sets the "series_id" field. +func (m *SeasonMutation) SetSeriesID(i int64) { + m.series = &i +} + +// SeriesID returns the value of the "series_id" field in the mutation. +func (m *SeasonMutation) SeriesID() (r int64, exists bool) { + v := m.series + if v == nil { + return + } + return *v, true +} + +// OldSeriesID returns the old "series_id" field's value of the Season entity. +// If the Season object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SeasonMutation) OldSeriesID(ctx context.Context) (v int64, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldSeriesID is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldSeriesID requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldSeriesID: %w", err) + } + return oldValue.SeriesID, nil +} + +// ResetSeriesID resets all changes to the "series_id" field. +func (m *SeasonMutation) ResetSeriesID() { + m.series = nil +} + +// SetTitle sets the "title" field. +func (m *SeasonMutation) SetTitle(s string) { + m.title = &s +} + +// Title returns the value of the "title" field in the mutation. +func (m *SeasonMutation) Title() (r string, exists bool) { + v := m.title + if v == nil { + return + } + return *v, true +} + +// OldTitle returns the old "title" field's value of the Season entity. +// If the Season object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SeasonMutation) OldTitle(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldTitle is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldTitle requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldTitle: %w", err) + } + return oldValue.Title, nil +} + +// ResetTitle resets all changes to the "title" field. +func (m *SeasonMutation) ResetTitle() { + m.title = nil +} + +// SetFirstAired sets the "first_aired" field. +func (m *SeasonMutation) SetFirstAired(t time.Time) { + m.first_aired = &t +} + +// FirstAired returns the value of the "first_aired" field in the mutation. +func (m *SeasonMutation) FirstAired() (r time.Time, exists bool) { + v := m.first_aired + if v == nil { + return + } + return *v, true +} + +// OldFirstAired returns the old "first_aired" field's value of the Season entity. +// If the Season object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SeasonMutation) OldFirstAired(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldFirstAired is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldFirstAired requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldFirstAired: %w", err) + } + return oldValue.FirstAired, nil +} + +// ResetFirstAired resets all changes to the "first_aired" field. +func (m *SeasonMutation) ResetFirstAired() { + m.first_aired = nil +} + +// SetLastAired sets the "last_aired" field. +func (m *SeasonMutation) SetLastAired(t time.Time) { + m.last_aired = &t +} + +// LastAired returns the value of the "last_aired" field in the mutation. +func (m *SeasonMutation) LastAired() (r time.Time, exists bool) { + v := m.last_aired + if v == nil { + return + } + return *v, true +} + +// OldLastAired returns the old "last_aired" field's value of the Season entity. +// If the Season object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SeasonMutation) OldLastAired(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldLastAired is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldLastAired requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldLastAired: %w", err) + } + return oldValue.LastAired, nil +} + +// ResetLastAired resets all changes to the "last_aired" field. +func (m *SeasonMutation) ResetLastAired() { + m.last_aired = nil +} + +// ClearSeries clears the "series" edge to the Series entity. +func (m *SeasonMutation) ClearSeries() { + m.clearedseries = true + m.clearedFields[season.FieldSeriesID] = struct{}{} +} + +// SeriesCleared reports if the "series" edge to the Series entity was cleared. +func (m *SeasonMutation) SeriesCleared() bool { + return m.clearedseries +} + +// SeriesIDs returns the "series" edge IDs in the mutation. +// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use +// SeriesID instead. It exists only for internal usage by the builders. +func (m *SeasonMutation) SeriesIDs() (ids []int64) { + if id := m.series; id != nil { + ids = append(ids, *id) + } + return +} + +// ResetSeries resets all changes to the "series" edge. +func (m *SeasonMutation) ResetSeries() { + m.series = nil + m.clearedseries = false +} + +// AddEpisodeIDs adds the "episodes" edge to the Episode entity by ids. +func (m *SeasonMutation) AddEpisodeIDs(ids ...int64) { + if m.episodes == nil { + m.episodes = make(map[int64]struct{}) + } + for i := range ids { + m.episodes[ids[i]] = struct{}{} + } +} + +// ClearEpisodes clears the "episodes" edge to the Episode entity. +func (m *SeasonMutation) ClearEpisodes() { + m.clearedepisodes = true +} + +// EpisodesCleared reports if the "episodes" edge to the Episode entity was cleared. +func (m *SeasonMutation) EpisodesCleared() bool { + return m.clearedepisodes +} + +// RemoveEpisodeIDs removes the "episodes" edge to the Episode entity by IDs. +func (m *SeasonMutation) RemoveEpisodeIDs(ids ...int64) { + if m.removedepisodes == nil { + m.removedepisodes = make(map[int64]struct{}) + } + for i := range ids { + delete(m.episodes, ids[i]) + m.removedepisodes[ids[i]] = struct{}{} + } +} + +// RemovedEpisodes returns the removed IDs of the "episodes" edge to the Episode entity. +func (m *SeasonMutation) RemovedEpisodesIDs() (ids []int64) { + for id := range m.removedepisodes { + ids = append(ids, id) + } + return +} + +// EpisodesIDs returns the "episodes" edge IDs in the mutation. +func (m *SeasonMutation) EpisodesIDs() (ids []int64) { + for id := range m.episodes { + ids = append(ids, id) + } + return +} + +// ResetEpisodes resets all changes to the "episodes" edge. +func (m *SeasonMutation) ResetEpisodes() { + m.episodes = nil + m.clearedepisodes = false + m.removedepisodes = nil +} + +// Where appends a list predicates to the SeasonMutation builder. +func (m *SeasonMutation) Where(ps ...predicate.Season) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the SeasonMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *SeasonMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.Season, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *SeasonMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *SeasonMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (Season). +func (m *SeasonMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *SeasonMutation) Fields() []string { + fields := make([]string, 0, 4) + if m.series != nil { + fields = append(fields, season.FieldSeriesID) + } + if m.title != nil { + fields = append(fields, season.FieldTitle) + } + if m.first_aired != nil { + fields = append(fields, season.FieldFirstAired) + } + if m.last_aired != nil { + fields = append(fields, season.FieldLastAired) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *SeasonMutation) Field(name string) (ent.Value, bool) { + switch name { + case season.FieldSeriesID: + return m.SeriesID() + case season.FieldTitle: + return m.Title() + case season.FieldFirstAired: + return m.FirstAired() + case season.FieldLastAired: + return m.LastAired() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *SeasonMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case season.FieldSeriesID: + return m.OldSeriesID(ctx) + case season.FieldTitle: + return m.OldTitle(ctx) + case season.FieldFirstAired: + return m.OldFirstAired(ctx) + case season.FieldLastAired: + return m.OldLastAired(ctx) + } + return nil, fmt.Errorf("unknown Season field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *SeasonMutation) SetField(name string, value ent.Value) error { + switch name { + case season.FieldSeriesID: + v, ok := value.(int64) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetSeriesID(v) + return nil + case season.FieldTitle: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetTitle(v) + return nil + case season.FieldFirstAired: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetFirstAired(v) + return nil + case season.FieldLastAired: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetLastAired(v) + return nil + } + return fmt.Errorf("unknown Season field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *SeasonMutation) AddedFields() []string { + var fields []string + return fields +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *SeasonMutation) AddedField(name string) (ent.Value, bool) { + switch name { + } + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *SeasonMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Season numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *SeasonMutation) ClearedFields() []string { + return nil +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *SeasonMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *SeasonMutation) ClearField(name string) error { + return fmt.Errorf("unknown Season nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *SeasonMutation) ResetField(name string) error { + switch name { + case season.FieldSeriesID: + m.ResetSeriesID() + return nil + case season.FieldTitle: + m.ResetTitle() + return nil + case season.FieldFirstAired: + m.ResetFirstAired() + return nil + case season.FieldLastAired: + m.ResetLastAired() + return nil + } + return fmt.Errorf("unknown Season field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *SeasonMutation) AddedEdges() []string { + edges := make([]string, 0, 2) + if m.series != nil { + edges = append(edges, season.EdgeSeries) + } + if m.episodes != nil { + edges = append(edges, season.EdgeEpisodes) + } + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *SeasonMutation) AddedIDs(name string) []ent.Value { + switch name { + case season.EdgeSeries: + if id := m.series; id != nil { + return []ent.Value{*id} + } + case season.EdgeEpisodes: + ids := make([]ent.Value, 0, len(m.episodes)) + for id := range m.episodes { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *SeasonMutation) RemovedEdges() []string { + edges := make([]string, 0, 2) + if m.removedepisodes != nil { + edges = append(edges, season.EdgeEpisodes) + } + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *SeasonMutation) RemovedIDs(name string) []ent.Value { + switch name { + case season.EdgeEpisodes: + ids := make([]ent.Value, 0, len(m.removedepisodes)) + for id := range m.removedepisodes { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *SeasonMutation) ClearedEdges() []string { + edges := make([]string, 0, 2) + if m.clearedseries { + edges = append(edges, season.EdgeSeries) + } + if m.clearedepisodes { + edges = append(edges, season.EdgeEpisodes) + } + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *SeasonMutation) EdgeCleared(name string) bool { + switch name { + case season.EdgeSeries: + return m.clearedseries + case season.EdgeEpisodes: + return m.clearedepisodes + } + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *SeasonMutation) ClearEdge(name string) error { + switch name { + case season.EdgeSeries: + m.ClearSeries() + return nil + } + return fmt.Errorf("unknown Season unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *SeasonMutation) ResetEdge(name string) error { + switch name { + case season.EdgeSeries: + m.ResetSeries() + return nil + case season.EdgeEpisodes: + m.ResetEpisodes() + return nil + } + return fmt.Errorf("unknown Season edge %s", name) +} + +// SeriesMutation represents an operation that mutates the Series nodes in the graph. +type SeriesMutation struct { + config + op Op + typ string + id *int64 + title *string + info *string + release_date *time.Time + clearedFields map[string]struct{} + seasons map[int64]struct{} + removedseasons map[int64]struct{} + clearedseasons bool + done bool + oldValue func(context.Context) (*Series, error) + predicates []predicate.Series +} + +var _ ent.Mutation = (*SeriesMutation)(nil) + +// seriesOption allows management of the mutation configuration using functional options. +type seriesOption func(*SeriesMutation) + +// newSeriesMutation creates new mutation for the Series entity. +func newSeriesMutation(c config, op Op, opts ...seriesOption) *SeriesMutation { + m := &SeriesMutation{ + config: c, + op: op, + typ: TypeSeries, + clearedFields: make(map[string]struct{}), + } + for _, opt := range opts { + opt(m) + } + return m +} + +// withSeriesID sets the ID field of the mutation. +func withSeriesID(id int64) seriesOption { + return func(m *SeriesMutation) { + var ( + err error + once sync.Once + value *Series + ) + m.oldValue = func(ctx context.Context) (*Series, error) { + once.Do(func() { + if m.done { + err = errors.New("querying old values post mutation is not allowed") + } else { + value, err = m.Client().Series.Get(ctx, id) + } + }) + return value, err + } + m.id = &id + } +} + +// withSeries sets the old Series of the mutation. +func withSeries(node *Series) seriesOption { + return func(m *SeriesMutation) { + m.oldValue = func(context.Context) (*Series, error) { + return node, nil + } + m.id = &node.ID + } +} + +// Client returns a new `ent.Client` from the mutation. If the mutation was +// executed in a transaction (ent.Tx), a transactional client is returned. +func (m SeriesMutation) Client() *Client { + client := &Client{config: m.config} + client.init() + return client +} + +// Tx returns an `ent.Tx` for mutations that were executed in transactions; +// it returns an error otherwise. +func (m SeriesMutation) Tx() (*Tx, error) { + if _, ok := m.driver.(*txDriver); !ok { + return nil, errors.New("ent: mutation is not running in a transaction") + } + tx := &Tx{config: m.config} + tx.init() + return tx, nil +} + +// SetID sets the value of the id field. Note that this +// operation is only accepted on creation of Series entities. +func (m *SeriesMutation) SetID(id int64) { + m.id = &id +} + +// ID returns the ID value in the mutation. Note that the ID is only available +// if it was provided to the builder or after it was returned from the database. +func (m *SeriesMutation) ID() (id int64, exists bool) { + if m.id == nil { + return + } + return *m.id, true +} + +// IDs queries the database and returns the entity ids that match the mutation's predicate. +// That means, if the mutation is applied within a transaction with an isolation level such +// as sql.LevelSerializable, the returned ids match the ids of the rows that will be updated +// or updated by the mutation. +func (m *SeriesMutation) IDs(ctx context.Context) ([]int64, error) { + switch { + case m.op.Is(OpUpdateOne | OpDeleteOne): + id, exists := m.ID() + if exists { + return []int64{id}, nil + } + fallthrough + case m.op.Is(OpUpdate | OpDelete): + return m.Client().Series.Query().Where(m.predicates...).IDs(ctx) + default: + return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) + } +} + +// SetTitle sets the "title" field. +func (m *SeriesMutation) SetTitle(s string) { + m.title = &s +} + +// Title returns the value of the "title" field in the mutation. +func (m *SeriesMutation) Title() (r string, exists bool) { + v := m.title + if v == nil { + return + } + return *v, true +} + +// OldTitle returns the old "title" field's value of the Series entity. +// If the Series object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SeriesMutation) OldTitle(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldTitle is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldTitle requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldTitle: %w", err) + } + return oldValue.Title, nil +} + +// ResetTitle resets all changes to the "title" field. +func (m *SeriesMutation) ResetTitle() { + m.title = nil +} + +// SetInfo sets the "info" field. +func (m *SeriesMutation) SetInfo(s string) { + m.info = &s +} + +// Info returns the value of the "info" field in the mutation. +func (m *SeriesMutation) Info() (r string, exists bool) { + v := m.info + if v == nil { + return + } + return *v, true +} + +// OldInfo returns the old "info" field's value of the Series entity. +// If the Series object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SeriesMutation) OldInfo(ctx context.Context) (v string, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldInfo is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldInfo requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldInfo: %w", err) + } + return oldValue.Info, nil +} + +// ClearInfo clears the value of the "info" field. +func (m *SeriesMutation) ClearInfo() { + m.info = nil + m.clearedFields[series.FieldInfo] = struct{}{} +} + +// InfoCleared returns if the "info" field was cleared in this mutation. +func (m *SeriesMutation) InfoCleared() bool { + _, ok := m.clearedFields[series.FieldInfo] + return ok +} + +// ResetInfo resets all changes to the "info" field. +func (m *SeriesMutation) ResetInfo() { + m.info = nil + delete(m.clearedFields, series.FieldInfo) +} + +// SetReleaseDate sets the "release_date" field. +func (m *SeriesMutation) SetReleaseDate(t time.Time) { + m.release_date = &t +} + +// ReleaseDate returns the value of the "release_date" field in the mutation. +func (m *SeriesMutation) ReleaseDate() (r time.Time, exists bool) { + v := m.release_date + if v == nil { + return + } + return *v, true +} + +// OldReleaseDate returns the old "release_date" field's value of the Series entity. +// If the Series object wasn't provided to the builder, the object is fetched from the database. +// An error is returned if the mutation operation is not UpdateOne, or the database query fails. +func (m *SeriesMutation) OldReleaseDate(ctx context.Context) (v time.Time, err error) { + if !m.op.Is(OpUpdateOne) { + return v, errors.New("OldReleaseDate is only allowed on UpdateOne operations") + } + if m.id == nil || m.oldValue == nil { + return v, errors.New("OldReleaseDate requires an ID field in the mutation") + } + oldValue, err := m.oldValue(ctx) + if err != nil { + return v, fmt.Errorf("querying old value for OldReleaseDate: %w", err) + } + return oldValue.ReleaseDate, nil +} + +// ResetReleaseDate resets all changes to the "release_date" field. +func (m *SeriesMutation) ResetReleaseDate() { + m.release_date = nil +} + +// AddSeasonIDs adds the "seasons" edge to the Season entity by ids. +func (m *SeriesMutation) AddSeasonIDs(ids ...int64) { + if m.seasons == nil { + m.seasons = make(map[int64]struct{}) + } + for i := range ids { + m.seasons[ids[i]] = struct{}{} + } +} + +// ClearSeasons clears the "seasons" edge to the Season entity. +func (m *SeriesMutation) ClearSeasons() { + m.clearedseasons = true +} + +// SeasonsCleared reports if the "seasons" edge to the Season entity was cleared. +func (m *SeriesMutation) SeasonsCleared() bool { + return m.clearedseasons +} + +// RemoveSeasonIDs removes the "seasons" edge to the Season entity by IDs. +func (m *SeriesMutation) RemoveSeasonIDs(ids ...int64) { + if m.removedseasons == nil { + m.removedseasons = make(map[int64]struct{}) + } + for i := range ids { + delete(m.seasons, ids[i]) + m.removedseasons[ids[i]] = struct{}{} + } +} + +// RemovedSeasons returns the removed IDs of the "seasons" edge to the Season entity. +func (m *SeriesMutation) RemovedSeasonsIDs() (ids []int64) { + for id := range m.removedseasons { + ids = append(ids, id) + } + return +} + +// SeasonsIDs returns the "seasons" edge IDs in the mutation. +func (m *SeriesMutation) SeasonsIDs() (ids []int64) { + for id := range m.seasons { + ids = append(ids, id) + } + return +} + +// ResetSeasons resets all changes to the "seasons" edge. +func (m *SeriesMutation) ResetSeasons() { + m.seasons = nil + m.clearedseasons = false + m.removedseasons = nil +} + +// Where appends a list predicates to the SeriesMutation builder. +func (m *SeriesMutation) Where(ps ...predicate.Series) { + m.predicates = append(m.predicates, ps...) +} + +// WhereP appends storage-level predicates to the SeriesMutation builder. Using this method, +// users can use type-assertion to append predicates that do not depend on any generated package. +func (m *SeriesMutation) WhereP(ps ...func(*sql.Selector)) { + p := make([]predicate.Series, len(ps)) + for i := range ps { + p[i] = ps[i] + } + m.Where(p...) +} + +// Op returns the operation name. +func (m *SeriesMutation) Op() Op { + return m.op +} + +// SetOp allows setting the mutation operation. +func (m *SeriesMutation) SetOp(op Op) { + m.op = op +} + +// Type returns the node type of this mutation (Series). +func (m *SeriesMutation) Type() string { + return m.typ +} + +// Fields returns all fields that were changed during this mutation. Note that in +// order to get all numeric fields that were incremented/decremented, call +// AddedFields(). +func (m *SeriesMutation) Fields() []string { + fields := make([]string, 0, 3) + if m.title != nil { + fields = append(fields, series.FieldTitle) + } + if m.info != nil { + fields = append(fields, series.FieldInfo) + } + if m.release_date != nil { + fields = append(fields, series.FieldReleaseDate) + } + return fields +} + +// Field returns the value of a field with the given name. The second boolean +// return value indicates that this field was not set, or was not defined in the +// schema. +func (m *SeriesMutation) Field(name string) (ent.Value, bool) { + switch name { + case series.FieldTitle: + return m.Title() + case series.FieldInfo: + return m.Info() + case series.FieldReleaseDate: + return m.ReleaseDate() + } + return nil, false +} + +// OldField returns the old value of the field from the database. An error is +// returned if the mutation operation is not UpdateOne, or the query to the +// database failed. +func (m *SeriesMutation) OldField(ctx context.Context, name string) (ent.Value, error) { + switch name { + case series.FieldTitle: + return m.OldTitle(ctx) + case series.FieldInfo: + return m.OldInfo(ctx) + case series.FieldReleaseDate: + return m.OldReleaseDate(ctx) + } + return nil, fmt.Errorf("unknown Series field %s", name) +} + +// SetField sets the value of a field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *SeriesMutation) SetField(name string, value ent.Value) error { + switch name { + case series.FieldTitle: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetTitle(v) + return nil + case series.FieldInfo: + v, ok := value.(string) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetInfo(v) + return nil + case series.FieldReleaseDate: + v, ok := value.(time.Time) + if !ok { + return fmt.Errorf("unexpected type %T for field %s", value, name) + } + m.SetReleaseDate(v) + return nil + } + return fmt.Errorf("unknown Series field %s", name) +} + +// AddedFields returns all numeric fields that were incremented/decremented during +// this mutation. +func (m *SeriesMutation) AddedFields() []string { + return nil +} + +// AddedField returns the numeric value that was incremented/decremented on a field +// with the given name. The second boolean return value indicates that this field +// was not set, or was not defined in the schema. +func (m *SeriesMutation) AddedField(name string) (ent.Value, bool) { + return nil, false +} + +// AddField adds the value to the field with the given name. It returns an error if +// the field is not defined in the schema, or if the type mismatched the field +// type. +func (m *SeriesMutation) AddField(name string, value ent.Value) error { + switch name { + } + return fmt.Errorf("unknown Series numeric field %s", name) +} + +// ClearedFields returns all nullable fields that were cleared during this +// mutation. +func (m *SeriesMutation) ClearedFields() []string { + var fields []string + if m.FieldCleared(series.FieldInfo) { + fields = append(fields, series.FieldInfo) + } + return fields +} + +// FieldCleared returns a boolean indicating if a field with the given name was +// cleared in this mutation. +func (m *SeriesMutation) FieldCleared(name string) bool { + _, ok := m.clearedFields[name] + return ok +} + +// ClearField clears the value of the field with the given name. It returns an +// error if the field is not defined in the schema. +func (m *SeriesMutation) ClearField(name string) error { + switch name { + case series.FieldInfo: + m.ClearInfo() + return nil + } + return fmt.Errorf("unknown Series nullable field %s", name) +} + +// ResetField resets all changes in the mutation for the field with the given name. +// It returns an error if the field is not defined in the schema. +func (m *SeriesMutation) ResetField(name string) error { + switch name { + case series.FieldTitle: + m.ResetTitle() + return nil + case series.FieldInfo: + m.ResetInfo() + return nil + case series.FieldReleaseDate: + m.ResetReleaseDate() + return nil + } + return fmt.Errorf("unknown Series field %s", name) +} + +// AddedEdges returns all edge names that were set/added in this mutation. +func (m *SeriesMutation) AddedEdges() []string { + edges := make([]string, 0, 1) + if m.seasons != nil { + edges = append(edges, series.EdgeSeasons) + } + return edges +} + +// AddedIDs returns all IDs (to other nodes) that were added for the given edge +// name in this mutation. +func (m *SeriesMutation) AddedIDs(name string) []ent.Value { + switch name { + case series.EdgeSeasons: + ids := make([]ent.Value, 0, len(m.seasons)) + for id := range m.seasons { + ids = append(ids, id) + } + return ids + } + return nil +} + +// RemovedEdges returns all edge names that were removed in this mutation. +func (m *SeriesMutation) RemovedEdges() []string { + edges := make([]string, 0, 1) + if m.removedseasons != nil { + edges = append(edges, series.EdgeSeasons) + } + return edges +} + +// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with +// the given name in this mutation. +func (m *SeriesMutation) RemovedIDs(name string) []ent.Value { + switch name { + case series.EdgeSeasons: + ids := make([]ent.Value, 0, len(m.removedseasons)) + for id := range m.removedseasons { + ids = append(ids, id) + } + return ids + } + return nil +} + +// ClearedEdges returns all edge names that were cleared in this mutation. +func (m *SeriesMutation) ClearedEdges() []string { + edges := make([]string, 0, 1) + if m.clearedseasons { + edges = append(edges, series.EdgeSeasons) + } + return edges +} + +// EdgeCleared returns a boolean which indicates if the edge with the given name +// was cleared in this mutation. +func (m *SeriesMutation) EdgeCleared(name string) bool { + switch name { + case series.EdgeSeasons: + return m.clearedseasons + } + return false +} + +// ClearEdge clears the value of the edge with the given name. It returns an error +// if that edge is not defined in the schema. +func (m *SeriesMutation) ClearEdge(name string) error { + switch name { + } + return fmt.Errorf("unknown Series unique edge %s", name) +} + +// ResetEdge resets all changes to the edge with the given name in this mutation. +// It returns an error if the edge is not defined in the schema. +func (m *SeriesMutation) ResetEdge(name string) error { + switch name { + case series.EdgeSeasons: + m.ResetSeasons() + return nil + } + return fmt.Errorf("unknown Series edge %s", name) +} diff --git a/examples/ydb/ent/predicate/predicate.go b/examples/ydb/ent/predicate/predicate.go new file mode 100644 index 0000000000..dc4baef3df --- /dev/null +++ b/examples/ydb/ent/predicate/predicate.go @@ -0,0 +1,20 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package predicate + +import ( + "entgo.io/ent/dialect/sql" +) + +// Episode is the predicate function for episode builders. +type Episode func(*sql.Selector) + +// Season is the predicate function for season builders. +type Season func(*sql.Selector) + +// Series is the predicate function for series builders. +type Series func(*sql.Selector) diff --git a/examples/ydb/ent/runtime.go b/examples/ydb/ent/runtime.go new file mode 100644 index 0000000000..d986e8a6e2 --- /dev/null +++ b/examples/ydb/ent/runtime.go @@ -0,0 +1,38 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "entgo.io/ent/examples/ydb/ent/episode" + "entgo.io/ent/examples/ydb/ent/schema" + "entgo.io/ent/examples/ydb/ent/season" + "entgo.io/ent/examples/ydb/ent/series" +) + +// The init function reads all schema descriptors with runtime code +// (default values, validators, hooks and policies) and stitches it +// to their package variables. +func init() { + episodeFields := schema.Episode{}.Fields() + _ = episodeFields + // episodeDescTitle is the schema descriptor for title field. + episodeDescTitle := episodeFields[2].Descriptor() + // episode.TitleValidator is a validator for the "title" field. It is called by the builders before save. + episode.TitleValidator = episodeDescTitle.Validators[0].(func(string) error) + seasonFields := schema.Season{}.Fields() + _ = seasonFields + // seasonDescTitle is the schema descriptor for title field. + seasonDescTitle := seasonFields[2].Descriptor() + // season.TitleValidator is a validator for the "title" field. It is called by the builders before save. + season.TitleValidator = seasonDescTitle.Validators[0].(func(string) error) + seriesFields := schema.Series{}.Fields() + _ = seriesFields + // seriesDescTitle is the schema descriptor for title field. + seriesDescTitle := seriesFields[1].Descriptor() + // series.TitleValidator is a validator for the "title" field. It is called by the builders before save. + series.TitleValidator = seriesDescTitle.Validators[0].(func(string) error) +} diff --git a/examples/ydb/ent/runtime/runtime.go b/examples/ydb/ent/runtime/runtime.go new file mode 100644 index 0000000000..c51f42a630 --- /dev/null +++ b/examples/ydb/ent/runtime/runtime.go @@ -0,0 +1,13 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package runtime + +// The schema-stitching logic is generated in entgo.io/ent/examples/ydb/ent/runtime.go + +const ( + Version = "v0.0.0-00010101000000-000000000000" // Version of ent codegen. +) diff --git a/examples/ydb/ent/schema/episode.go b/examples/ydb/ent/schema/episode.go new file mode 100644 index 0000000000..e7a7ad4fac --- /dev/null +++ b/examples/ydb/ent/schema/episode.go @@ -0,0 +1,47 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +package schema + +import ( + "entgo.io/ent" + "entgo.io/ent/dialect/entsql" + "entgo.io/ent/schema" + "entgo.io/ent/schema/edge" + "entgo.io/ent/schema/field" +) + +// Episode holds the schema definition for the Episode entity. +type Episode struct { + ent.Schema +} + +// Annotations of the Episode. +func (Episode) Annotations() []schema.Annotation { + return []schema.Annotation{ + entsql.Annotation{Table: "episodes"}, + } +} + +// Fields of the Episode. +func (Episode) Fields() []ent.Field { + return []ent.Field{ + field.Int64("id"), + field.Int64("season_id"), + field.String("title"). + NotEmpty(), + field.Time("air_date"), + } +} + +// Edges of the Episode. +func (Episode) Edges() []ent.Edge { + return []ent.Edge{ + edge.From("season", Season.Type). + Ref("episodes"). + Unique(). + Required(). + Field("season_id"), + } +} diff --git a/examples/ydb/ent/schema/season.go b/examples/ydb/ent/schema/season.go new file mode 100644 index 0000000000..3093dc144b --- /dev/null +++ b/examples/ydb/ent/schema/season.go @@ -0,0 +1,49 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +package schema + +import ( + "entgo.io/ent" + "entgo.io/ent/dialect/entsql" + "entgo.io/ent/schema" + "entgo.io/ent/schema/edge" + "entgo.io/ent/schema/field" +) + +// Season holds the schema definition for the Season entity. +type Season struct { + ent.Schema +} + +// Annotations of the Season. +func (Season) Annotations() []schema.Annotation { + return []schema.Annotation{ + entsql.Annotation{Table: "seasons"}, + } +} + +// Fields of the Season. +func (Season) Fields() []ent.Field { + return []ent.Field{ + field.Int64("id"), + field.Int64("series_id"), + field.String("title"). + NotEmpty(), + field.Time("first_aired"), + field.Time("last_aired"), + } +} + +// Edges of the Season. +func (Season) Edges() []ent.Edge { + return []ent.Edge{ + edge.From("series", Series.Type). + Ref("seasons"). + Unique(). + Required(). + Field("series_id"), + edge.To("episodes", Episode.Type), + } +} diff --git a/examples/ydb/ent/schema/series.go b/examples/ydb/ent/schema/series.go new file mode 100644 index 0000000000..b50678bd43 --- /dev/null +++ b/examples/ydb/ent/schema/series.go @@ -0,0 +1,44 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +package schema + +import ( + "entgo.io/ent" + "entgo.io/ent/dialect/entsql" + "entgo.io/ent/schema" + "entgo.io/ent/schema/edge" + "entgo.io/ent/schema/field" +) + +// Series holds the schema definition for the Series entity. +type Series struct { + ent.Schema +} + +// Annotations of the Series. +func (Series) Annotations() []schema.Annotation { + return []schema.Annotation{ + entsql.Annotation{Table: "series"}, + } +} + +// Fields of the Series. +func (Series) Fields() []ent.Field { + return []ent.Field{ + field.Int64("id"), + field.String("title"). + NotEmpty(), + field.Text("info"). + Optional(), + field.Time("release_date"), + } +} + +// Edges of the Series. +func (Series) Edges() []ent.Edge { + return []ent.Edge{ + edge.To("seasons", Season.Type), + } +} diff --git a/examples/ydb/ent/season.go b/examples/ydb/ent/season.go new file mode 100644 index 0000000000..eb808605fc --- /dev/null +++ b/examples/ydb/ent/season.go @@ -0,0 +1,188 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "fmt" + "strings" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/examples/ydb/ent/season" + "entgo.io/ent/examples/ydb/ent/series" +) + +// Season is the model entity for the Season schema. +type Season struct { + config `json:"-"` + // ID of the ent. + ID int64 `json:"id,omitempty"` + // SeriesID holds the value of the "series_id" field. + SeriesID int64 `json:"series_id,omitempty"` + // Title holds the value of the "title" field. + Title string `json:"title,omitempty"` + // FirstAired holds the value of the "first_aired" field. + FirstAired time.Time `json:"first_aired,omitempty"` + // LastAired holds the value of the "last_aired" field. + LastAired time.Time `json:"last_aired,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the SeasonQuery when eager-loading is set. + Edges SeasonEdges `json:"edges"` + selectValues sql.SelectValues +} + +// SeasonEdges holds the relations/edges for other nodes in the graph. +type SeasonEdges struct { + // Series holds the value of the series edge. + Series *Series `json:"series,omitempty"` + // Episodes holds the value of the episodes edge. + Episodes []*Episode `json:"episodes,omitempty"` + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [2]bool +} + +// SeriesOrErr returns the Series value or an error if the edge +// was not loaded in eager-loading, or loaded but was not found. +func (e SeasonEdges) SeriesOrErr() (*Series, error) { + if e.Series != nil { + return e.Series, nil + } else if e.loadedTypes[0] { + return nil, &NotFoundError{label: series.Label} + } + return nil, &NotLoadedError{edge: "series"} +} + +// EpisodesOrErr returns the Episodes value or an error if the edge +// was not loaded in eager-loading. +func (e SeasonEdges) EpisodesOrErr() ([]*Episode, error) { + if e.loadedTypes[1] { + return e.Episodes, nil + } + return nil, &NotLoadedError{edge: "episodes"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*Season) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case season.FieldID, season.FieldSeriesID: + values[i] = new(sql.NullInt64) + case season.FieldTitle: + values[i] = new(sql.NullString) + case season.FieldFirstAired, season.FieldLastAired: + values[i] = new(sql.NullTime) + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the Season fields. +func (_m *Season) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case season.FieldID: + value, ok := values[i].(*sql.NullInt64) + if !ok { + return fmt.Errorf("unexpected type %T for field id", value) + } + _m.ID = int64(value.Int64) + case season.FieldSeriesID: + if value, ok := values[i].(*sql.NullInt64); !ok { + return fmt.Errorf("unexpected type %T for field series_id", values[i]) + } else if value.Valid { + _m.SeriesID = value.Int64 + } + case season.FieldTitle: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field title", values[i]) + } else if value.Valid { + _m.Title = value.String + } + case season.FieldFirstAired: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field first_aired", values[i]) + } else if value.Valid { + _m.FirstAired = value.Time + } + case season.FieldLastAired: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field last_aired", values[i]) + } else if value.Valid { + _m.LastAired = value.Time + } + default: + _m.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the Season. +// This includes values selected through modifiers, order, etc. +func (_m *Season) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + +// QuerySeries queries the "series" edge of the Season entity. +func (_m *Season) QuerySeries() *SeriesQuery { + return NewSeasonClient(_m.config).QuerySeries(_m) +} + +// QueryEpisodes queries the "episodes" edge of the Season entity. +func (_m *Season) QueryEpisodes() *EpisodeQuery { + return NewSeasonClient(_m.config).QueryEpisodes(_m) +} + +// Update returns a builder for updating this Season. +// Note that you need to call Season.Unwrap() before calling this method if this Season +// was returned from a transaction, and the transaction was committed or rolled back. +func (_m *Season) Update() *SeasonUpdateOne { + return NewSeasonClient(_m.config).UpdateOne(_m) +} + +// Unwrap unwraps the Season entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (_m *Season) Unwrap() *Season { + _tx, ok := _m.config.driver.(*txDriver) + if !ok { + panic("ent: Season is not a transactional entity") + } + _m.config.driver = _tx.drv + return _m +} + +// String implements the fmt.Stringer. +func (_m *Season) String() string { + var builder strings.Builder + builder.WriteString("Season(") + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) + builder.WriteString("series_id=") + builder.WriteString(fmt.Sprintf("%v", _m.SeriesID)) + builder.WriteString(", ") + builder.WriteString("title=") + builder.WriteString(_m.Title) + builder.WriteString(", ") + builder.WriteString("first_aired=") + builder.WriteString(_m.FirstAired.Format(time.ANSIC)) + builder.WriteString(", ") + builder.WriteString("last_aired=") + builder.WriteString(_m.LastAired.Format(time.ANSIC)) + builder.WriteByte(')') + return builder.String() +} + +// Seasons is a parsable slice of Season. +type Seasons []*Season diff --git a/examples/ydb/ent/season/season.go b/examples/ydb/ent/season/season.go new file mode 100644 index 0000000000..c1919974ba --- /dev/null +++ b/examples/ydb/ent/season/season.go @@ -0,0 +1,134 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package season + +import ( + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" +) + +const ( + // Label holds the string label denoting the season type in the database. + Label = "season" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldSeriesID holds the string denoting the series_id field in the database. + FieldSeriesID = "series_id" + // FieldTitle holds the string denoting the title field in the database. + FieldTitle = "title" + // FieldFirstAired holds the string denoting the first_aired field in the database. + FieldFirstAired = "first_aired" + // FieldLastAired holds the string denoting the last_aired field in the database. + FieldLastAired = "last_aired" + // EdgeSeries holds the string denoting the series edge name in mutations. + EdgeSeries = "series" + // EdgeEpisodes holds the string denoting the episodes edge name in mutations. + EdgeEpisodes = "episodes" + // Table holds the table name of the season in the database. + Table = "seasons" + // SeriesTable is the table that holds the series relation/edge. + SeriesTable = "seasons" + // SeriesInverseTable is the table name for the Series entity. + // It exists in this package in order to avoid circular dependency with the "series" package. + SeriesInverseTable = "series" + // SeriesColumn is the table column denoting the series relation/edge. + SeriesColumn = "series_id" + // EpisodesTable is the table that holds the episodes relation/edge. + EpisodesTable = "episodes" + // EpisodesInverseTable is the table name for the Episode entity. + // It exists in this package in order to avoid circular dependency with the "episode" package. + EpisodesInverseTable = "episodes" + // EpisodesColumn is the table column denoting the episodes relation/edge. + EpisodesColumn = "season_id" +) + +// Columns holds all SQL columns for season fields. +var Columns = []string{ + FieldID, + FieldSeriesID, + FieldTitle, + FieldFirstAired, + FieldLastAired, +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + return false +} + +var ( + // TitleValidator is a validator for the "title" field. It is called by the builders before save. + TitleValidator func(string) error +) + +// OrderOption defines the ordering options for the Season queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// BySeriesID orders the results by the series_id field. +func BySeriesID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldSeriesID, opts...).ToFunc() +} + +// ByTitle orders the results by the title field. +func ByTitle(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldTitle, opts...).ToFunc() +} + +// ByFirstAired orders the results by the first_aired field. +func ByFirstAired(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldFirstAired, opts...).ToFunc() +} + +// ByLastAired orders the results by the last_aired field. +func ByLastAired(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldLastAired, opts...).ToFunc() +} + +// BySeriesField orders the results by series field. +func BySeriesField(field string, opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newSeriesStep(), sql.OrderByField(field, opts...)) + } +} + +// ByEpisodesCount orders the results by episodes count. +func ByEpisodesCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newEpisodesStep(), opts...) + } +} + +// ByEpisodes orders the results by episodes terms. +func ByEpisodes(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newEpisodesStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} +func newSeriesStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(SeriesInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, SeriesTable, SeriesColumn), + ) +} +func newEpisodesStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(EpisodesInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, EpisodesTable, EpisodesColumn), + ) +} diff --git a/examples/ydb/ent/season/where.go b/examples/ydb/ent/season/where.go new file mode 100644 index 0000000000..801bf07703 --- /dev/null +++ b/examples/ydb/ent/season/where.go @@ -0,0 +1,306 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package season + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/examples/ydb/ent/predicate" +) + +// ID filters vertices based on their ID field. +func ID(id int64) predicate.Season { + return predicate.Season(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id int64) predicate.Season { + return predicate.Season(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id int64) predicate.Season { + return predicate.Season(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...int64) predicate.Season { + return predicate.Season(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...int64) predicate.Season { + return predicate.Season(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id int64) predicate.Season { + return predicate.Season(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id int64) predicate.Season { + return predicate.Season(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id int64) predicate.Season { + return predicate.Season(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id int64) predicate.Season { + return predicate.Season(sql.FieldLTE(FieldID, id)) +} + +// SeriesID applies equality check predicate on the "series_id" field. It's identical to SeriesIDEQ. +func SeriesID(v int64) predicate.Season { + return predicate.Season(sql.FieldEQ(FieldSeriesID, v)) +} + +// Title applies equality check predicate on the "title" field. It's identical to TitleEQ. +func Title(v string) predicate.Season { + return predicate.Season(sql.FieldEQ(FieldTitle, v)) +} + +// FirstAired applies equality check predicate on the "first_aired" field. It's identical to FirstAiredEQ. +func FirstAired(v time.Time) predicate.Season { + return predicate.Season(sql.FieldEQ(FieldFirstAired, v)) +} + +// LastAired applies equality check predicate on the "last_aired" field. It's identical to LastAiredEQ. +func LastAired(v time.Time) predicate.Season { + return predicate.Season(sql.FieldEQ(FieldLastAired, v)) +} + +// SeriesIDEQ applies the EQ predicate on the "series_id" field. +func SeriesIDEQ(v int64) predicate.Season { + return predicate.Season(sql.FieldEQ(FieldSeriesID, v)) +} + +// SeriesIDNEQ applies the NEQ predicate on the "series_id" field. +func SeriesIDNEQ(v int64) predicate.Season { + return predicate.Season(sql.FieldNEQ(FieldSeriesID, v)) +} + +// SeriesIDIn applies the In predicate on the "series_id" field. +func SeriesIDIn(vs ...int64) predicate.Season { + return predicate.Season(sql.FieldIn(FieldSeriesID, vs...)) +} + +// SeriesIDNotIn applies the NotIn predicate on the "series_id" field. +func SeriesIDNotIn(vs ...int64) predicate.Season { + return predicate.Season(sql.FieldNotIn(FieldSeriesID, vs...)) +} + +// TitleEQ applies the EQ predicate on the "title" field. +func TitleEQ(v string) predicate.Season { + return predicate.Season(sql.FieldEQ(FieldTitle, v)) +} + +// TitleNEQ applies the NEQ predicate on the "title" field. +func TitleNEQ(v string) predicate.Season { + return predicate.Season(sql.FieldNEQ(FieldTitle, v)) +} + +// TitleIn applies the In predicate on the "title" field. +func TitleIn(vs ...string) predicate.Season { + return predicate.Season(sql.FieldIn(FieldTitle, vs...)) +} + +// TitleNotIn applies the NotIn predicate on the "title" field. +func TitleNotIn(vs ...string) predicate.Season { + return predicate.Season(sql.FieldNotIn(FieldTitle, vs...)) +} + +// TitleGT applies the GT predicate on the "title" field. +func TitleGT(v string) predicate.Season { + return predicate.Season(sql.FieldGT(FieldTitle, v)) +} + +// TitleGTE applies the GTE predicate on the "title" field. +func TitleGTE(v string) predicate.Season { + return predicate.Season(sql.FieldGTE(FieldTitle, v)) +} + +// TitleLT applies the LT predicate on the "title" field. +func TitleLT(v string) predicate.Season { + return predicate.Season(sql.FieldLT(FieldTitle, v)) +} + +// TitleLTE applies the LTE predicate on the "title" field. +func TitleLTE(v string) predicate.Season { + return predicate.Season(sql.FieldLTE(FieldTitle, v)) +} + +// TitleContains applies the Contains predicate on the "title" field. +func TitleContains(v string) predicate.Season { + return predicate.Season(sql.FieldContains(FieldTitle, v)) +} + +// TitleHasPrefix applies the HasPrefix predicate on the "title" field. +func TitleHasPrefix(v string) predicate.Season { + return predicate.Season(sql.FieldHasPrefix(FieldTitle, v)) +} + +// TitleHasSuffix applies the HasSuffix predicate on the "title" field. +func TitleHasSuffix(v string) predicate.Season { + return predicate.Season(sql.FieldHasSuffix(FieldTitle, v)) +} + +// TitleEqualFold applies the EqualFold predicate on the "title" field. +func TitleEqualFold(v string) predicate.Season { + return predicate.Season(sql.FieldEqualFold(FieldTitle, v)) +} + +// TitleContainsFold applies the ContainsFold predicate on the "title" field. +func TitleContainsFold(v string) predicate.Season { + return predicate.Season(sql.FieldContainsFold(FieldTitle, v)) +} + +// FirstAiredEQ applies the EQ predicate on the "first_aired" field. +func FirstAiredEQ(v time.Time) predicate.Season { + return predicate.Season(sql.FieldEQ(FieldFirstAired, v)) +} + +// FirstAiredNEQ applies the NEQ predicate on the "first_aired" field. +func FirstAiredNEQ(v time.Time) predicate.Season { + return predicate.Season(sql.FieldNEQ(FieldFirstAired, v)) +} + +// FirstAiredIn applies the In predicate on the "first_aired" field. +func FirstAiredIn(vs ...time.Time) predicate.Season { + return predicate.Season(sql.FieldIn(FieldFirstAired, vs...)) +} + +// FirstAiredNotIn applies the NotIn predicate on the "first_aired" field. +func FirstAiredNotIn(vs ...time.Time) predicate.Season { + return predicate.Season(sql.FieldNotIn(FieldFirstAired, vs...)) +} + +// FirstAiredGT applies the GT predicate on the "first_aired" field. +func FirstAiredGT(v time.Time) predicate.Season { + return predicate.Season(sql.FieldGT(FieldFirstAired, v)) +} + +// FirstAiredGTE applies the GTE predicate on the "first_aired" field. +func FirstAiredGTE(v time.Time) predicate.Season { + return predicate.Season(sql.FieldGTE(FieldFirstAired, v)) +} + +// FirstAiredLT applies the LT predicate on the "first_aired" field. +func FirstAiredLT(v time.Time) predicate.Season { + return predicate.Season(sql.FieldLT(FieldFirstAired, v)) +} + +// FirstAiredLTE applies the LTE predicate on the "first_aired" field. +func FirstAiredLTE(v time.Time) predicate.Season { + return predicate.Season(sql.FieldLTE(FieldFirstAired, v)) +} + +// LastAiredEQ applies the EQ predicate on the "last_aired" field. +func LastAiredEQ(v time.Time) predicate.Season { + return predicate.Season(sql.FieldEQ(FieldLastAired, v)) +} + +// LastAiredNEQ applies the NEQ predicate on the "last_aired" field. +func LastAiredNEQ(v time.Time) predicate.Season { + return predicate.Season(sql.FieldNEQ(FieldLastAired, v)) +} + +// LastAiredIn applies the In predicate on the "last_aired" field. +func LastAiredIn(vs ...time.Time) predicate.Season { + return predicate.Season(sql.FieldIn(FieldLastAired, vs...)) +} + +// LastAiredNotIn applies the NotIn predicate on the "last_aired" field. +func LastAiredNotIn(vs ...time.Time) predicate.Season { + return predicate.Season(sql.FieldNotIn(FieldLastAired, vs...)) +} + +// LastAiredGT applies the GT predicate on the "last_aired" field. +func LastAiredGT(v time.Time) predicate.Season { + return predicate.Season(sql.FieldGT(FieldLastAired, v)) +} + +// LastAiredGTE applies the GTE predicate on the "last_aired" field. +func LastAiredGTE(v time.Time) predicate.Season { + return predicate.Season(sql.FieldGTE(FieldLastAired, v)) +} + +// LastAiredLT applies the LT predicate on the "last_aired" field. +func LastAiredLT(v time.Time) predicate.Season { + return predicate.Season(sql.FieldLT(FieldLastAired, v)) +} + +// LastAiredLTE applies the LTE predicate on the "last_aired" field. +func LastAiredLTE(v time.Time) predicate.Season { + return predicate.Season(sql.FieldLTE(FieldLastAired, v)) +} + +// HasSeries applies the HasEdge predicate on the "series" edge. +func HasSeries() predicate.Season { + return predicate.Season(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, SeriesTable, SeriesColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasSeriesWith applies the HasEdge predicate on the "series" edge with a given conditions (other predicates). +func HasSeriesWith(preds ...predicate.Series) predicate.Season { + return predicate.Season(func(s *sql.Selector) { + step := newSeriesStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// HasEpisodes applies the HasEdge predicate on the "episodes" edge. +func HasEpisodes() predicate.Season { + return predicate.Season(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, EpisodesTable, EpisodesColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasEpisodesWith applies the HasEdge predicate on the "episodes" edge with a given conditions (other predicates). +func HasEpisodesWith(preds ...predicate.Episode) predicate.Season { + return predicate.Season(func(s *sql.Selector) { + step := newEpisodesStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.Season) predicate.Season { + return predicate.Season(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.Season) predicate.Season { + return predicate.Season(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.Season) predicate.Season { + return predicate.Season(sql.NotPredicates(p)) +} diff --git a/examples/ydb/ent/season_create.go b/examples/ydb/ent/season_create.go new file mode 100644 index 0000000000..07270e036f --- /dev/null +++ b/examples/ydb/ent/season_create.go @@ -0,0 +1,317 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/examples/ydb/ent/episode" + "entgo.io/ent/examples/ydb/ent/season" + "entgo.io/ent/examples/ydb/ent/series" + "entgo.io/ent/schema/field" +) + +// SeasonCreate is the builder for creating a Season entity. +type SeasonCreate struct { + config + mutation *SeasonMutation + hooks []Hook + retryConfig sql.RetryConfig +} + +// SetSeriesID sets the "series_id" field. +func (_c *SeasonCreate) SetSeriesID(v int64) *SeasonCreate { + _c.mutation.SetSeriesID(v) + return _c +} + +// SetTitle sets the "title" field. +func (_c *SeasonCreate) SetTitle(v string) *SeasonCreate { + _c.mutation.SetTitle(v) + return _c +} + +// SetFirstAired sets the "first_aired" field. +func (_c *SeasonCreate) SetFirstAired(v time.Time) *SeasonCreate { + _c.mutation.SetFirstAired(v) + return _c +} + +// SetLastAired sets the "last_aired" field. +func (_c *SeasonCreate) SetLastAired(v time.Time) *SeasonCreate { + _c.mutation.SetLastAired(v) + return _c +} + +// SetID sets the "id" field. +func (_c *SeasonCreate) SetID(v int64) *SeasonCreate { + _c.mutation.SetID(v) + return _c +} + +// SetSeries sets the "series" edge to the Series entity. +func (_c *SeasonCreate) SetSeries(v *Series) *SeasonCreate { + return _c.SetSeriesID(v.ID) +} + +// AddEpisodeIDs adds the "episodes" edge to the Episode entity by IDs. +func (_c *SeasonCreate) AddEpisodeIDs(ids ...int64) *SeasonCreate { + _c.mutation.AddEpisodeIDs(ids...) + return _c +} + +// AddEpisodes adds the "episodes" edges to the Episode entity. +func (_c *SeasonCreate) AddEpisodes(v ...*Episode) *SeasonCreate { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _c.AddEpisodeIDs(ids...) +} + +// Mutation returns the SeasonMutation object of the builder. +func (_c *SeasonCreate) Mutation() *SeasonMutation { + return _c.mutation +} + +// Save creates the Season in the database. +func (_c *SeasonCreate) Save(ctx context.Context) (*Season, error) { + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (_c *SeasonCreate) SaveX(ctx context.Context) *Season { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *SeasonCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *SeasonCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_c *SeasonCreate) check() error { + if _, ok := _c.mutation.SeriesID(); !ok { + return &ValidationError{Name: "series_id", err: errors.New(`ent: missing required field "Season.series_id"`)} + } + if _, ok := _c.mutation.Title(); !ok { + return &ValidationError{Name: "title", err: errors.New(`ent: missing required field "Season.title"`)} + } + if v, ok := _c.mutation.Title(); ok { + if err := season.TitleValidator(v); err != nil { + return &ValidationError{Name: "title", err: fmt.Errorf(`ent: validator failed for field "Season.title": %w`, err)} + } + } + if _, ok := _c.mutation.FirstAired(); !ok { + return &ValidationError{Name: "first_aired", err: errors.New(`ent: missing required field "Season.first_aired"`)} + } + if _, ok := _c.mutation.LastAired(); !ok { + return &ValidationError{Name: "last_aired", err: errors.New(`ent: missing required field "Season.last_aired"`)} + } + if len(_c.mutation.SeriesIDs()) == 0 { + return &ValidationError{Name: "series", err: errors.New(`ent: missing required edge "Season.series"`)} + } + return nil +} + +func (_c *SeasonCreate) sqlSave(ctx context.Context) (*Season, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + if _spec.ID.Value != _node.ID { + id := _spec.ID.Value.(int64) + _node.ID = int64(id) + } + _c.mutation.id = &_node.ID + _c.mutation.done = true + return _node, nil +} + +func (_c *SeasonCreate) createSpec() (*Season, *sqlgraph.CreateSpec) { + var ( + _node = &Season{config: _c.config} + _spec = sqlgraph.NewCreateSpec(season.Table, sqlgraph.NewFieldSpec(season.FieldID, field.TypeInt64)) + ) + _spec.RetryConfig = _c.retryConfig + if id, ok := _c.mutation.ID(); ok { + _node.ID = id + _spec.ID.Value = id + } + if value, ok := _c.mutation.Title(); ok { + _spec.SetField(season.FieldTitle, field.TypeString, value) + _node.Title = value + } + if value, ok := _c.mutation.FirstAired(); ok { + _spec.SetField(season.FieldFirstAired, field.TypeTime, value) + _node.FirstAired = value + } + if value, ok := _c.mutation.LastAired(); ok { + _spec.SetField(season.FieldLastAired, field.TypeTime, value) + _node.LastAired = value + } + if nodes := _c.mutation.SeriesIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: season.SeriesTable, + Columns: []string{season.SeriesColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(series.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _node.SeriesID = nodes[0] + _spec.Edges = append(_spec.Edges, edge) + } + if nodes := _c.mutation.EpisodesIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: season.EpisodesTable, + Columns: []string{season.EpisodesColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(episode.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + return _node, _spec +} + +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *SeasonCreate) WithRetryOptions(opts ...any) *SeasonCreate { + _c.retryConfig.Options = opts + return _c +} + +// SeasonCreateBulk is the builder for creating many Season entities in bulk. +type SeasonCreateBulk struct { + config + err error + builders []*SeasonCreate + retryConfig sql.RetryConfig +} + +// Save creates the Season entities in the database. +func (_c *SeasonCreateBulk) Save(ctx context.Context) ([]*Season, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*Season, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { + func(i int, root context.Context) { + builder := _c.builders[i] + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*SeasonMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + if specs[i].ID.Value != nil && nodes[i].ID == 0 { + id := specs[i].ID.Value.(int64) + nodes[i].ID = int64(id) + } + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (_c *SeasonCreateBulk) SaveX(ctx context.Context) []*Season { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *SeasonCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *SeasonCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *SeasonCreateBulk) WithRetryOptions(opts ...any) *SeasonCreateBulk { + _c.retryConfig.Options = opts + return _c +} diff --git a/examples/ydb/ent/season_delete.go b/examples/ydb/ent/season_delete.go new file mode 100644 index 0000000000..8817be5b13 --- /dev/null +++ b/examples/ydb/ent/season_delete.go @@ -0,0 +1,101 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/examples/ydb/ent/predicate" + "entgo.io/ent/examples/ydb/ent/season" + "entgo.io/ent/schema/field" +) + +// SeasonDelete is the builder for deleting a Season entity. +type SeasonDelete struct { + config + hooks []Hook + mutation *SeasonMutation + retryConfig sql.RetryConfig +} + +// Where appends a list predicates to the SeasonDelete builder. +func (_d *SeasonDelete) Where(ps ...predicate.Season) *SeasonDelete { + _d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (_d *SeasonDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *SeasonDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (_d *SeasonDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(season.Table, sqlgraph.NewFieldSpec(season.FieldID, field.TypeInt64)) + _spec.RetryConfig = _d.retryConfig + if ps := _d.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + _d.mutation.done = true + return affected, err +} + +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *SeasonDelete) WithRetryOptions(opts ...any) *SeasonDelete { + _d.retryConfig.Options = opts + return _d +} + +// SeasonDeleteOne is the builder for deleting a single Season entity. +type SeasonDeleteOne struct { + _d *SeasonDelete +} + +// Where appends a list predicates to the SeasonDelete builder. +func (_d *SeasonDeleteOne) Where(ps ...predicate.Season) *SeasonDeleteOne { + _d._d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query. +func (_d *SeasonDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{season.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *SeasonDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/examples/ydb/ent/season_query.go b/examples/ydb/ent/season_query.go new file mode 100644 index 0000000000..67900aa04b --- /dev/null +++ b/examples/ydb/ent/season_query.go @@ -0,0 +1,695 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "database/sql/driver" + "fmt" + "math" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/examples/ydb/ent/episode" + "entgo.io/ent/examples/ydb/ent/predicate" + "entgo.io/ent/examples/ydb/ent/season" + "entgo.io/ent/examples/ydb/ent/series" + "entgo.io/ent/schema/field" +) + +// SeasonQuery is the builder for querying Season entities. +type SeasonQuery struct { + config + ctx *QueryContext + order []season.OrderOption + inters []Interceptor + predicates []predicate.Season + withSeries *SeriesQuery + withEpisodes *EpisodeQuery + retryConfig sql.RetryConfig + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the SeasonQuery builder. +func (_q *SeasonQuery) Where(ps ...predicate.Season) *SeasonQuery { + _q.predicates = append(_q.predicates, ps...) + return _q +} + +// Limit the number of records to be returned by this query. +func (_q *SeasonQuery) Limit(limit int) *SeasonQuery { + _q.ctx.Limit = &limit + return _q +} + +// Offset to start from. +func (_q *SeasonQuery) Offset(offset int) *SeasonQuery { + _q.ctx.Offset = &offset + return _q +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (_q *SeasonQuery) Unique(unique bool) *SeasonQuery { + _q.ctx.Unique = &unique + return _q +} + +// Order specifies how the records should be ordered. +func (_q *SeasonQuery) Order(o ...season.OrderOption) *SeasonQuery { + _q.order = append(_q.order, o...) + return _q +} + +// QuerySeries chains the current query on the "series" edge. +func (_q *SeasonQuery) QuerySeries() *SeriesQuery { + query := (&SeriesClient{config: _q.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + selector := _q.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(season.Table, season.FieldID, selector), + sqlgraph.To(series.Table, series.FieldID), + sqlgraph.Edge(sqlgraph.M2O, true, season.SeriesTable, season.SeriesColumn), + ) + fromU = sqlgraph.SetNeighbors(_q.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// QueryEpisodes chains the current query on the "episodes" edge. +func (_q *SeasonQuery) QueryEpisodes() *EpisodeQuery { + query := (&EpisodeClient{config: _q.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + selector := _q.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(season.Table, season.FieldID, selector), + sqlgraph.To(episode.Table, episode.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, season.EpisodesTable, season.EpisodesColumn), + ) + fromU = sqlgraph.SetNeighbors(_q.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// First returns the first Season entity from the query. +// Returns a *NotFoundError when no Season was found. +func (_q *SeasonQuery) First(ctx context.Context) (*Season, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{season.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (_q *SeasonQuery) FirstX(ctx context.Context) *Season { + node, err := _q.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first Season ID from the query. +// Returns a *NotFoundError when no Season ID was found. +func (_q *SeasonQuery) FirstID(ctx context.Context) (id int64, err error) { + var ids []int64 + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{season.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (_q *SeasonQuery) FirstIDX(ctx context.Context) int64 { + id, err := _q.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single Season entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one Season entity is found. +// Returns a *NotFoundError when no Season entities are found. +func (_q *SeasonQuery) Only(ctx context.Context) (*Season, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{season.Label} + default: + return nil, &NotSingularError{season.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (_q *SeasonQuery) OnlyX(ctx context.Context) *Season { + node, err := _q.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only Season ID in the query. +// Returns a *NotSingularError when more than one Season ID is found. +// Returns a *NotFoundError when no entities are found. +func (_q *SeasonQuery) OnlyID(ctx context.Context) (id int64, err error) { + var ids []int64 + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{season.Label} + default: + err = &NotSingularError{season.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (_q *SeasonQuery) OnlyIDX(ctx context.Context) int64 { + id, err := _q.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of Seasons. +func (_q *SeasonQuery) All(ctx context.Context) ([]*Season, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*Season, *SeasonQuery]() + return withInterceptors[[]*Season](ctx, _q, qr, _q.inters) +} + +// AllX is like All, but panics if an error occurs. +func (_q *SeasonQuery) AllX(ctx context.Context) []*Season { + nodes, err := _q.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of Season IDs. +func (_q *SeasonQuery) IDs(ctx context.Context) (ids []int64, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(season.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (_q *SeasonQuery) IDsX(ctx context.Context) []int64 { + ids, err := _q.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (_q *SeasonQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, _q, querierCount[*SeasonQuery](), _q.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (_q *SeasonQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (_q *SeasonQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("ent: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (_q *SeasonQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the SeasonQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (_q *SeasonQuery) Clone() *SeasonQuery { + if _q == nil { + return nil + } + return &SeasonQuery{ + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]season.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.Season{}, _q.predicates...), + withSeries: _q.withSeries.Clone(), + withEpisodes: _q.withEpisodes.Clone(), + // clone intermediate query. + sql: _q.sql.Clone(), + path: _q.path, + } +} + +// WithSeries tells the query-builder to eager-load the nodes that are connected to +// the "series" edge. The optional arguments are used to configure the query builder of the edge. +func (_q *SeasonQuery) WithSeries(opts ...func(*SeriesQuery)) *SeasonQuery { + query := (&SeriesClient{config: _q.config}).Query() + for _, opt := range opts { + opt(query) + } + _q.withSeries = query + return _q +} + +// WithEpisodes tells the query-builder to eager-load the nodes that are connected to +// the "episodes" edge. The optional arguments are used to configure the query builder of the edge. +func (_q *SeasonQuery) WithEpisodes(opts ...func(*EpisodeQuery)) *SeasonQuery { + query := (&EpisodeClient{config: _q.config}).Query() + for _, opt := range opts { + opt(query) + } + _q.withEpisodes = query + return _q +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// SeriesID int64 `json:"series_id,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.Season.Query(). +// GroupBy(season.FieldSeriesID). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +func (_q *SeasonQuery) GroupBy(field string, fields ...string) *SeasonGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &SeasonGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields + grbuild.label = season.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// SeriesID int64 `json:"series_id,omitempty"` +// } +// +// client.Season.Query(). +// Select(season.FieldSeriesID). +// Scan(ctx, &v) +func (_q *SeasonQuery) Select(fields ...string) *SeasonSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &SeasonSelect{SeasonQuery: _q} + sbuild.label = season.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a SeasonSelect configured with the given aggregations. +func (_q *SeasonQuery) Aggregate(fns ...AggregateFunc) *SeasonSelect { + return _q.Select().Aggregate(fns...) +} + +func (_q *SeasonQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { + if !season.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if _q.path != nil { + prev, err := _q.path(ctx) + if err != nil { + return err + } + _q.sql = prev + } + return nil +} + +func (_q *SeasonQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Season, error) { + var ( + nodes = []*Season{} + _spec = _q.querySpec() + loadedTypes = [2]bool{ + _q.withSeries != nil, + _q.withEpisodes != nil, + } + ) + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*Season).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &Season{config: _q.config} + nodes = append(nodes, node) + node.Edges.loadedTypes = loadedTypes + return node.assignValues(columns, values) + } + _spec.RetryConfig = _q.retryConfig + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + if query := _q.withSeries; query != nil { + if err := _q.loadSeries(ctx, query, nodes, nil, + func(n *Season, e *Series) { n.Edges.Series = e }); err != nil { + return nil, err + } + } + if query := _q.withEpisodes; query != nil { + if err := _q.loadEpisodes(ctx, query, nodes, + func(n *Season) { n.Edges.Episodes = []*Episode{} }, + func(n *Season, e *Episode) { n.Edges.Episodes = append(n.Edges.Episodes, e) }); err != nil { + return nil, err + } + } + return nodes, nil +} + +func (_q *SeasonQuery) loadSeries(ctx context.Context, query *SeriesQuery, nodes []*Season, init func(*Season), assign func(*Season, *Series)) error { + ids := make([]int64, 0, len(nodes)) + nodeids := make(map[int64][]*Season) + for i := range nodes { + fk := nodes[i].SeriesID + if _, ok := nodeids[fk]; !ok { + ids = append(ids, fk) + } + nodeids[fk] = append(nodeids[fk], nodes[i]) + } + if len(ids) == 0 { + return nil + } + query.Where(series.IDIn(ids...)) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + nodes, ok := nodeids[n.ID] + if !ok { + return fmt.Errorf(`unexpected foreign-key "series_id" returned %v`, n.ID) + } + for i := range nodes { + assign(nodes[i], n) + } + } + return nil +} +func (_q *SeasonQuery) loadEpisodes(ctx context.Context, query *EpisodeQuery, nodes []*Season, init func(*Season), assign func(*Season, *Episode)) error { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[int64]*Season) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + if init != nil { + init(nodes[i]) + } + } + if len(query.ctx.Fields) > 0 { + query.ctx.AppendFieldOnce(episode.FieldSeasonID) + } + query.Where(predicate.Episode(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(season.EpisodesColumn), fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + fk := n.SeasonID + node, ok := nodeids[fk] + if !ok { + return fmt.Errorf(`unexpected referenced foreign-key "season_id" returned %v for node %v`, fk, n.ID) + } + assign(node, n) + } + return nil +} + +func (_q *SeasonQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + _spec.RetryConfig = _q.retryConfig + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique + } + return sqlgraph.CountNodes(ctx, _q.driver, _spec) +} + +func (_q *SeasonQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(season.Table, season.Columns, sqlgraph.NewFieldSpec(season.FieldID, field.TypeInt64)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true + } + if fields := _q.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, season.FieldID) + for i := range fields { + if fields[i] != season.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + if _q.withSeries != nil { + _spec.Node.AddColumnOnce(season.FieldSeriesID) + } + } + if ps := _q.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := _q.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := _q.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := _q.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (_q *SeasonQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) + t1 := builder.Table(season.Table) + columns := _q.ctx.Fields + if len(columns) == 0 { + columns = season.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if _q.sql != nil { + selector = _q.sql + selector.Select(selector.Columns(columns...)...) + } + if _q.ctx.Unique != nil && *_q.ctx.Unique { + selector.Distinct() + } + for _, p := range _q.predicates { + p(selector) + } + for _, p := range _q.order { + p(selector) + } + if offset := _q.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := _q.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *SeasonQuery) WithRetryOptions(opts ...any) *SeasonQuery { + _q.retryConfig.Options = opts + return _q +} + +// SeasonGroupBy is the group-by builder for Season entities. +type SeasonGroupBy struct { + selector + build *SeasonQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (_g *SeasonGroupBy) Aggregate(fns ...AggregateFunc) *SeasonGroupBy { + _g.fns = append(_g.fns, fns...) + return _g +} + +// Scan applies the selector query and scans the result into the given value. +func (_g *SeasonGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*SeasonQuery, *SeasonGroupBy](ctx, _g.build, _g, _g.build.inters, v) +} + +func (_g *SeasonGroupBy) sqlScan(ctx context.Context, root *SeasonQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*_g.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// SeasonSelect is the builder for selecting fields of Season entities. +type SeasonSelect struct { + *SeasonQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *SeasonSelect) Aggregate(fns ...AggregateFunc) *SeasonSelect { + _s.fns = append(_s.fns, fns...) + return _s +} + +// Scan applies the selector query and scans the result into the given value. +func (_s *SeasonSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*SeasonQuery, *SeasonSelect](ctx, _s.SeasonQuery, _s, _s.inters, v) +} + +func (_s *SeasonSelect) sqlScan(ctx context.Context, root *SeasonQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/examples/ydb/ent/season_update.go b/examples/ydb/ent/season_update.go new file mode 100644 index 0000000000..81b6b402cd --- /dev/null +++ b/examples/ydb/ent/season_update.go @@ -0,0 +1,604 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/examples/ydb/ent/episode" + "entgo.io/ent/examples/ydb/ent/predicate" + "entgo.io/ent/examples/ydb/ent/season" + "entgo.io/ent/examples/ydb/ent/series" + "entgo.io/ent/schema/field" +) + +// SeasonUpdate is the builder for updating Season entities. +type SeasonUpdate struct { + config + hooks []Hook + mutation *SeasonMutation + retryConfig sql.RetryConfig +} + +// Where appends a list predicates to the SeasonUpdate builder. +func (_u *SeasonUpdate) Where(ps ...predicate.Season) *SeasonUpdate { + _u.mutation.Where(ps...) + return _u +} + +// SetSeriesID sets the "series_id" field. +func (_u *SeasonUpdate) SetSeriesID(v int64) *SeasonUpdate { + _u.mutation.SetSeriesID(v) + return _u +} + +// SetNillableSeriesID sets the "series_id" field if the given value is not nil. +func (_u *SeasonUpdate) SetNillableSeriesID(v *int64) *SeasonUpdate { + if v != nil { + _u.SetSeriesID(*v) + } + return _u +} + +// SetTitle sets the "title" field. +func (_u *SeasonUpdate) SetTitle(v string) *SeasonUpdate { + _u.mutation.SetTitle(v) + return _u +} + +// SetNillableTitle sets the "title" field if the given value is not nil. +func (_u *SeasonUpdate) SetNillableTitle(v *string) *SeasonUpdate { + if v != nil { + _u.SetTitle(*v) + } + return _u +} + +// SetFirstAired sets the "first_aired" field. +func (_u *SeasonUpdate) SetFirstAired(v time.Time) *SeasonUpdate { + _u.mutation.SetFirstAired(v) + return _u +} + +// SetNillableFirstAired sets the "first_aired" field if the given value is not nil. +func (_u *SeasonUpdate) SetNillableFirstAired(v *time.Time) *SeasonUpdate { + if v != nil { + _u.SetFirstAired(*v) + } + return _u +} + +// SetLastAired sets the "last_aired" field. +func (_u *SeasonUpdate) SetLastAired(v time.Time) *SeasonUpdate { + _u.mutation.SetLastAired(v) + return _u +} + +// SetNillableLastAired sets the "last_aired" field if the given value is not nil. +func (_u *SeasonUpdate) SetNillableLastAired(v *time.Time) *SeasonUpdate { + if v != nil { + _u.SetLastAired(*v) + } + return _u +} + +// SetSeries sets the "series" edge to the Series entity. +func (_u *SeasonUpdate) SetSeries(v *Series) *SeasonUpdate { + return _u.SetSeriesID(v.ID) +} + +// AddEpisodeIDs adds the "episodes" edge to the Episode entity by IDs. +func (_u *SeasonUpdate) AddEpisodeIDs(ids ...int64) *SeasonUpdate { + _u.mutation.AddEpisodeIDs(ids...) + return _u +} + +// AddEpisodes adds the "episodes" edges to the Episode entity. +func (_u *SeasonUpdate) AddEpisodes(v ...*Episode) *SeasonUpdate { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.AddEpisodeIDs(ids...) +} + +// Mutation returns the SeasonMutation object of the builder. +func (_u *SeasonUpdate) Mutation() *SeasonMutation { + return _u.mutation +} + +// ClearSeries clears the "series" edge to the Series entity. +func (_u *SeasonUpdate) ClearSeries() *SeasonUpdate { + _u.mutation.ClearSeries() + return _u +} + +// ClearEpisodes clears all "episodes" edges to the Episode entity. +func (_u *SeasonUpdate) ClearEpisodes() *SeasonUpdate { + _u.mutation.ClearEpisodes() + return _u +} + +// RemoveEpisodeIDs removes the "episodes" edge to Episode entities by IDs. +func (_u *SeasonUpdate) RemoveEpisodeIDs(ids ...int64) *SeasonUpdate { + _u.mutation.RemoveEpisodeIDs(ids...) + return _u +} + +// RemoveEpisodes removes "episodes" edges to Episode entities. +func (_u *SeasonUpdate) RemoveEpisodes(v ...*Episode) *SeasonUpdate { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.RemoveEpisodeIDs(ids...) +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (_u *SeasonUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *SeasonUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (_u *SeasonUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *SeasonUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_u *SeasonUpdate) check() error { + if v, ok := _u.mutation.Title(); ok { + if err := season.TitleValidator(v); err != nil { + return &ValidationError{Name: "title", err: fmt.Errorf(`ent: validator failed for field "Season.title": %w`, err)} + } + } + if _u.mutation.SeriesCleared() && len(_u.mutation.SeriesIDs()) > 0 { + return errors.New(`ent: clearing a required unique edge "Season.series"`) + } + return nil +} + +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *SeasonUpdate) WithRetryOptions(opts ...any) *SeasonUpdate { + _u.retryConfig.Options = opts + return _u +} + +func (_u *SeasonUpdate) sqlSave(ctx context.Context) (_node int, err error) { + if err := _u.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(season.Table, season.Columns, sqlgraph.NewFieldSpec(season.FieldID, field.TypeInt64)) + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.Title(); ok { + _spec.SetField(season.FieldTitle, field.TypeString, value) + } + if value, ok := _u.mutation.FirstAired(); ok { + _spec.SetField(season.FieldFirstAired, field.TypeTime, value) + } + if value, ok := _u.mutation.LastAired(); ok { + _spec.SetField(season.FieldLastAired, field.TypeTime, value) + } + if _u.mutation.SeriesCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: season.SeriesTable, + Columns: []string{season.SeriesColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(series.FieldID, field.TypeInt64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.SeriesIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: season.SeriesTable, + Columns: []string{season.SeriesColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(series.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if _u.mutation.EpisodesCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: season.EpisodesTable, + Columns: []string{season.EpisodesColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(episode.FieldID, field.TypeInt64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.RemovedEpisodesIDs(); len(nodes) > 0 && !_u.mutation.EpisodesCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: season.EpisodesTable, + Columns: []string{season.EpisodesColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(episode.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.EpisodesIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: season.EpisodesTable, + Columns: []string{season.EpisodesColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(episode.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + _spec.RetryConfig = _u.retryConfig + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { + if sqlgraph.IsNotFound(err) { + err = &NotFoundError{season.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + _u.mutation.done = true + return _node, nil +} + +// SeasonUpdateOne is the builder for updating a single Season entity. +type SeasonUpdateOne struct { + config + fields []string + hooks []Hook + mutation *SeasonMutation + retryConfig sql.RetryConfig +} + +// SetSeriesID sets the "series_id" field. +func (_u *SeasonUpdateOne) SetSeriesID(v int64) *SeasonUpdateOne { + _u.mutation.SetSeriesID(v) + return _u +} + +// SetNillableSeriesID sets the "series_id" field if the given value is not nil. +func (_u *SeasonUpdateOne) SetNillableSeriesID(v *int64) *SeasonUpdateOne { + if v != nil { + _u.SetSeriesID(*v) + } + return _u +} + +// SetTitle sets the "title" field. +func (_u *SeasonUpdateOne) SetTitle(v string) *SeasonUpdateOne { + _u.mutation.SetTitle(v) + return _u +} + +// SetNillableTitle sets the "title" field if the given value is not nil. +func (_u *SeasonUpdateOne) SetNillableTitle(v *string) *SeasonUpdateOne { + if v != nil { + _u.SetTitle(*v) + } + return _u +} + +// SetFirstAired sets the "first_aired" field. +func (_u *SeasonUpdateOne) SetFirstAired(v time.Time) *SeasonUpdateOne { + _u.mutation.SetFirstAired(v) + return _u +} + +// SetNillableFirstAired sets the "first_aired" field if the given value is not nil. +func (_u *SeasonUpdateOne) SetNillableFirstAired(v *time.Time) *SeasonUpdateOne { + if v != nil { + _u.SetFirstAired(*v) + } + return _u +} + +// SetLastAired sets the "last_aired" field. +func (_u *SeasonUpdateOne) SetLastAired(v time.Time) *SeasonUpdateOne { + _u.mutation.SetLastAired(v) + return _u +} + +// SetNillableLastAired sets the "last_aired" field if the given value is not nil. +func (_u *SeasonUpdateOne) SetNillableLastAired(v *time.Time) *SeasonUpdateOne { + if v != nil { + _u.SetLastAired(*v) + } + return _u +} + +// SetSeries sets the "series" edge to the Series entity. +func (_u *SeasonUpdateOne) SetSeries(v *Series) *SeasonUpdateOne { + return _u.SetSeriesID(v.ID) +} + +// AddEpisodeIDs adds the "episodes" edge to the Episode entity by IDs. +func (_u *SeasonUpdateOne) AddEpisodeIDs(ids ...int64) *SeasonUpdateOne { + _u.mutation.AddEpisodeIDs(ids...) + return _u +} + +// AddEpisodes adds the "episodes" edges to the Episode entity. +func (_u *SeasonUpdateOne) AddEpisodes(v ...*Episode) *SeasonUpdateOne { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.AddEpisodeIDs(ids...) +} + +// Mutation returns the SeasonMutation object of the builder. +func (_u *SeasonUpdateOne) Mutation() *SeasonMutation { + return _u.mutation +} + +// ClearSeries clears the "series" edge to the Series entity. +func (_u *SeasonUpdateOne) ClearSeries() *SeasonUpdateOne { + _u.mutation.ClearSeries() + return _u +} + +// ClearEpisodes clears all "episodes" edges to the Episode entity. +func (_u *SeasonUpdateOne) ClearEpisodes() *SeasonUpdateOne { + _u.mutation.ClearEpisodes() + return _u +} + +// RemoveEpisodeIDs removes the "episodes" edge to Episode entities by IDs. +func (_u *SeasonUpdateOne) RemoveEpisodeIDs(ids ...int64) *SeasonUpdateOne { + _u.mutation.RemoveEpisodeIDs(ids...) + return _u +} + +// RemoveEpisodes removes "episodes" edges to Episode entities. +func (_u *SeasonUpdateOne) RemoveEpisodes(v ...*Episode) *SeasonUpdateOne { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.RemoveEpisodeIDs(ids...) +} + +// Where appends a list predicates to the SeasonUpdate builder. +func (_u *SeasonUpdateOne) Where(ps ...predicate.Season) *SeasonUpdateOne { + _u.mutation.Where(ps...) + return _u +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (_u *SeasonUpdateOne) Select(field string, fields ...string) *SeasonUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u +} + +// Save executes the query and returns the updated Season entity. +func (_u *SeasonUpdateOne) Save(ctx context.Context) (*Season, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *SeasonUpdateOne) SaveX(ctx context.Context) *Season { + node, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (_u *SeasonUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *SeasonUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_u *SeasonUpdateOne) check() error { + if v, ok := _u.mutation.Title(); ok { + if err := season.TitleValidator(v); err != nil { + return &ValidationError{Name: "title", err: fmt.Errorf(`ent: validator failed for field "Season.title": %w`, err)} + } + } + if _u.mutation.SeriesCleared() && len(_u.mutation.SeriesIDs()) > 0 { + return errors.New(`ent: clearing a required unique edge "Season.series"`) + } + return nil +} + +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *SeasonUpdateOne) WithRetryOptions(opts ...any) *SeasonUpdateOne { + _u.retryConfig.Options = opts + return _u +} + +func (_u *SeasonUpdateOne) sqlSave(ctx context.Context) (_node *Season, err error) { + if err := _u.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(season.Table, season.Columns, sqlgraph.NewFieldSpec(season.FieldID, field.TypeInt64)) + id, ok := _u.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "Season.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := _u.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, season.FieldID) + for _, f := range fields { + if !season.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != season.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.Title(); ok { + _spec.SetField(season.FieldTitle, field.TypeString, value) + } + if value, ok := _u.mutation.FirstAired(); ok { + _spec.SetField(season.FieldFirstAired, field.TypeTime, value) + } + if value, ok := _u.mutation.LastAired(); ok { + _spec.SetField(season.FieldLastAired, field.TypeTime, value) + } + if _u.mutation.SeriesCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: season.SeriesTable, + Columns: []string{season.SeriesColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(series.FieldID, field.TypeInt64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.SeriesIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.M2O, + Inverse: true, + Table: season.SeriesTable, + Columns: []string{season.SeriesColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(series.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + if _u.mutation.EpisodesCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: season.EpisodesTable, + Columns: []string{season.EpisodesColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(episode.FieldID, field.TypeInt64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.RemovedEpisodesIDs(); len(nodes) > 0 && !_u.mutation.EpisodesCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: season.EpisodesTable, + Columns: []string{season.EpisodesColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(episode.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.EpisodesIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: season.EpisodesTable, + Columns: []string{season.EpisodesColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(episode.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + _spec.RetryConfig = _u.retryConfig + _node = &Season{config: _u.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { + if sqlgraph.IsNotFound(err) { + err = &NotFoundError{season.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + _u.mutation.done = true + return _node, nil +} diff --git a/examples/ydb/ent/series.go b/examples/ydb/ent/series.go new file mode 100644 index 0000000000..2b137d6066 --- /dev/null +++ b/examples/ydb/ent/series.go @@ -0,0 +1,158 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "fmt" + "strings" + "time" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/examples/ydb/ent/series" +) + +// Series is the model entity for the Series schema. +type Series struct { + config `json:"-"` + // ID of the ent. + ID int64 `json:"id,omitempty"` + // Title holds the value of the "title" field. + Title string `json:"title,omitempty"` + // Info holds the value of the "info" field. + Info string `json:"info,omitempty"` + // ReleaseDate holds the value of the "release_date" field. + ReleaseDate time.Time `json:"release_date,omitempty"` + // Edges holds the relations/edges for other nodes in the graph. + // The values are being populated by the SeriesQuery when eager-loading is set. + Edges SeriesEdges `json:"edges"` + selectValues sql.SelectValues +} + +// SeriesEdges holds the relations/edges for other nodes in the graph. +type SeriesEdges struct { + // Seasons holds the value of the seasons edge. + Seasons []*Season `json:"seasons,omitempty"` + // loadedTypes holds the information for reporting if a + // type was loaded (or requested) in eager-loading or not. + loadedTypes [1]bool +} + +// SeasonsOrErr returns the Seasons value or an error if the edge +// was not loaded in eager-loading. +func (e SeriesEdges) SeasonsOrErr() ([]*Season, error) { + if e.loadedTypes[0] { + return e.Seasons, nil + } + return nil, &NotLoadedError{edge: "seasons"} +} + +// scanValues returns the types for scanning values from sql.Rows. +func (*Series) scanValues(columns []string) ([]any, error) { + values := make([]any, len(columns)) + for i := range columns { + switch columns[i] { + case series.FieldID: + values[i] = new(sql.NullInt64) + case series.FieldTitle, series.FieldInfo: + values[i] = new(sql.NullString) + case series.FieldReleaseDate: + values[i] = new(sql.NullTime) + default: + values[i] = new(sql.UnknownType) + } + } + return values, nil +} + +// assignValues assigns the values that were returned from sql.Rows (after scanning) +// to the Series fields. +func (_m *Series) assignValues(columns []string, values []any) error { + if m, n := len(values), len(columns); m < n { + return fmt.Errorf("mismatch number of scan values: %d != %d", m, n) + } + for i := range columns { + switch columns[i] { + case series.FieldID: + value, ok := values[i].(*sql.NullInt64) + if !ok { + return fmt.Errorf("unexpected type %T for field id", value) + } + _m.ID = int64(value.Int64) + case series.FieldTitle: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field title", values[i]) + } else if value.Valid { + _m.Title = value.String + } + case series.FieldInfo: + if value, ok := values[i].(*sql.NullString); !ok { + return fmt.Errorf("unexpected type %T for field info", values[i]) + } else if value.Valid { + _m.Info = value.String + } + case series.FieldReleaseDate: + if value, ok := values[i].(*sql.NullTime); !ok { + return fmt.Errorf("unexpected type %T for field release_date", values[i]) + } else if value.Valid { + _m.ReleaseDate = value.Time + } + default: + _m.selectValues.Set(columns[i], values[i]) + } + } + return nil +} + +// Value returns the ent.Value that was dynamically selected and assigned to the Series. +// This includes values selected through modifiers, order, etc. +func (_m *Series) Value(name string) (ent.Value, error) { + return _m.selectValues.Get(name) +} + +// QuerySeasons queries the "seasons" edge of the Series entity. +func (_m *Series) QuerySeasons() *SeasonQuery { + return NewSeriesClient(_m.config).QuerySeasons(_m) +} + +// Update returns a builder for updating this Series. +// Note that you need to call Series.Unwrap() before calling this method if this Series +// was returned from a transaction, and the transaction was committed or rolled back. +func (_m *Series) Update() *SeriesUpdateOne { + return NewSeriesClient(_m.config).UpdateOne(_m) +} + +// Unwrap unwraps the Series entity that was returned from a transaction after it was closed, +// so that all future queries will be executed through the driver which created the transaction. +func (_m *Series) Unwrap() *Series { + _tx, ok := _m.config.driver.(*txDriver) + if !ok { + panic("ent: Series is not a transactional entity") + } + _m.config.driver = _tx.drv + return _m +} + +// String implements the fmt.Stringer. +func (_m *Series) String() string { + var builder strings.Builder + builder.WriteString("Series(") + builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID)) + builder.WriteString("title=") + builder.WriteString(_m.Title) + builder.WriteString(", ") + builder.WriteString("info=") + builder.WriteString(_m.Info) + builder.WriteString(", ") + builder.WriteString("release_date=") + builder.WriteString(_m.ReleaseDate.Format(time.ANSIC)) + builder.WriteByte(')') + return builder.String() +} + +// SeriesSlice is a parsable slice of Series. +type SeriesSlice []*Series diff --git a/examples/ydb/ent/series/series.go b/examples/ydb/ent/series/series.go new file mode 100644 index 0000000000..1e21b94896 --- /dev/null +++ b/examples/ydb/ent/series/series.go @@ -0,0 +1,103 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package series + +import ( + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" +) + +const ( + // Label holds the string label denoting the series type in the database. + Label = "series" + // FieldID holds the string denoting the id field in the database. + FieldID = "id" + // FieldTitle holds the string denoting the title field in the database. + FieldTitle = "title" + // FieldInfo holds the string denoting the info field in the database. + FieldInfo = "info" + // FieldReleaseDate holds the string denoting the release_date field in the database. + FieldReleaseDate = "release_date" + // EdgeSeasons holds the string denoting the seasons edge name in mutations. + EdgeSeasons = "seasons" + // Table holds the table name of the series in the database. + Table = "series" + // SeasonsTable is the table that holds the seasons relation/edge. + SeasonsTable = "seasons" + // SeasonsInverseTable is the table name for the Season entity. + // It exists in this package in order to avoid circular dependency with the "season" package. + SeasonsInverseTable = "seasons" + // SeasonsColumn is the table column denoting the seasons relation/edge. + SeasonsColumn = "series_id" +) + +// Columns holds all SQL columns for series fields. +var Columns = []string{ + FieldID, + FieldTitle, + FieldInfo, + FieldReleaseDate, +} + +// ValidColumn reports if the column name is valid (part of the table columns). +func ValidColumn(column string) bool { + for i := range Columns { + if column == Columns[i] { + return true + } + } + return false +} + +var ( + // TitleValidator is a validator for the "title" field. It is called by the builders before save. + TitleValidator func(string) error +) + +// OrderOption defines the ordering options for the Series queries. +type OrderOption func(*sql.Selector) + +// ByID orders the results by the id field. +func ByID(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldID, opts...).ToFunc() +} + +// ByTitle orders the results by the title field. +func ByTitle(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldTitle, opts...).ToFunc() +} + +// ByInfo orders the results by the info field. +func ByInfo(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldInfo, opts...).ToFunc() +} + +// ByReleaseDate orders the results by the release_date field. +func ByReleaseDate(opts ...sql.OrderTermOption) OrderOption { + return sql.OrderByField(FieldReleaseDate, opts...).ToFunc() +} + +// BySeasonsCount orders the results by seasons count. +func BySeasonsCount(opts ...sql.OrderTermOption) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborsCount(s, newSeasonsStep(), opts...) + } +} + +// BySeasons orders the results by seasons terms. +func BySeasons(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { + return func(s *sql.Selector) { + sqlgraph.OrderByNeighborTerms(s, newSeasonsStep(), append([]sql.OrderTerm{term}, terms...)...) + } +} +func newSeasonsStep() *sqlgraph.Step { + return sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.To(SeasonsInverseTable, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, SeasonsTable, SeasonsColumn), + ) +} diff --git a/examples/ydb/ent/series/where.go b/examples/ydb/ent/series/where.go new file mode 100644 index 0000000000..d308a6c8a3 --- /dev/null +++ b/examples/ydb/ent/series/where.go @@ -0,0 +1,293 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package series + +import ( + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/examples/ydb/ent/predicate" +) + +// ID filters vertices based on their ID field. +func ID(id int64) predicate.Series { + return predicate.Series(sql.FieldEQ(FieldID, id)) +} + +// IDEQ applies the EQ predicate on the ID field. +func IDEQ(id int64) predicate.Series { + return predicate.Series(sql.FieldEQ(FieldID, id)) +} + +// IDNEQ applies the NEQ predicate on the ID field. +func IDNEQ(id int64) predicate.Series { + return predicate.Series(sql.FieldNEQ(FieldID, id)) +} + +// IDIn applies the In predicate on the ID field. +func IDIn(ids ...int64) predicate.Series { + return predicate.Series(sql.FieldIn(FieldID, ids...)) +} + +// IDNotIn applies the NotIn predicate on the ID field. +func IDNotIn(ids ...int64) predicate.Series { + return predicate.Series(sql.FieldNotIn(FieldID, ids...)) +} + +// IDGT applies the GT predicate on the ID field. +func IDGT(id int64) predicate.Series { + return predicate.Series(sql.FieldGT(FieldID, id)) +} + +// IDGTE applies the GTE predicate on the ID field. +func IDGTE(id int64) predicate.Series { + return predicate.Series(sql.FieldGTE(FieldID, id)) +} + +// IDLT applies the LT predicate on the ID field. +func IDLT(id int64) predicate.Series { + return predicate.Series(sql.FieldLT(FieldID, id)) +} + +// IDLTE applies the LTE predicate on the ID field. +func IDLTE(id int64) predicate.Series { + return predicate.Series(sql.FieldLTE(FieldID, id)) +} + +// Title applies equality check predicate on the "title" field. It's identical to TitleEQ. +func Title(v string) predicate.Series { + return predicate.Series(sql.FieldEQ(FieldTitle, v)) +} + +// Info applies equality check predicate on the "info" field. It's identical to InfoEQ. +func Info(v string) predicate.Series { + return predicate.Series(sql.FieldEQ(FieldInfo, v)) +} + +// ReleaseDate applies equality check predicate on the "release_date" field. It's identical to ReleaseDateEQ. +func ReleaseDate(v time.Time) predicate.Series { + return predicate.Series(sql.FieldEQ(FieldReleaseDate, v)) +} + +// TitleEQ applies the EQ predicate on the "title" field. +func TitleEQ(v string) predicate.Series { + return predicate.Series(sql.FieldEQ(FieldTitle, v)) +} + +// TitleNEQ applies the NEQ predicate on the "title" field. +func TitleNEQ(v string) predicate.Series { + return predicate.Series(sql.FieldNEQ(FieldTitle, v)) +} + +// TitleIn applies the In predicate on the "title" field. +func TitleIn(vs ...string) predicate.Series { + return predicate.Series(sql.FieldIn(FieldTitle, vs...)) +} + +// TitleNotIn applies the NotIn predicate on the "title" field. +func TitleNotIn(vs ...string) predicate.Series { + return predicate.Series(sql.FieldNotIn(FieldTitle, vs...)) +} + +// TitleGT applies the GT predicate on the "title" field. +func TitleGT(v string) predicate.Series { + return predicate.Series(sql.FieldGT(FieldTitle, v)) +} + +// TitleGTE applies the GTE predicate on the "title" field. +func TitleGTE(v string) predicate.Series { + return predicate.Series(sql.FieldGTE(FieldTitle, v)) +} + +// TitleLT applies the LT predicate on the "title" field. +func TitleLT(v string) predicate.Series { + return predicate.Series(sql.FieldLT(FieldTitle, v)) +} + +// TitleLTE applies the LTE predicate on the "title" field. +func TitleLTE(v string) predicate.Series { + return predicate.Series(sql.FieldLTE(FieldTitle, v)) +} + +// TitleContains applies the Contains predicate on the "title" field. +func TitleContains(v string) predicate.Series { + return predicate.Series(sql.FieldContains(FieldTitle, v)) +} + +// TitleHasPrefix applies the HasPrefix predicate on the "title" field. +func TitleHasPrefix(v string) predicate.Series { + return predicate.Series(sql.FieldHasPrefix(FieldTitle, v)) +} + +// TitleHasSuffix applies the HasSuffix predicate on the "title" field. +func TitleHasSuffix(v string) predicate.Series { + return predicate.Series(sql.FieldHasSuffix(FieldTitle, v)) +} + +// TitleEqualFold applies the EqualFold predicate on the "title" field. +func TitleEqualFold(v string) predicate.Series { + return predicate.Series(sql.FieldEqualFold(FieldTitle, v)) +} + +// TitleContainsFold applies the ContainsFold predicate on the "title" field. +func TitleContainsFold(v string) predicate.Series { + return predicate.Series(sql.FieldContainsFold(FieldTitle, v)) +} + +// InfoEQ applies the EQ predicate on the "info" field. +func InfoEQ(v string) predicate.Series { + return predicate.Series(sql.FieldEQ(FieldInfo, v)) +} + +// InfoNEQ applies the NEQ predicate on the "info" field. +func InfoNEQ(v string) predicate.Series { + return predicate.Series(sql.FieldNEQ(FieldInfo, v)) +} + +// InfoIn applies the In predicate on the "info" field. +func InfoIn(vs ...string) predicate.Series { + return predicate.Series(sql.FieldIn(FieldInfo, vs...)) +} + +// InfoNotIn applies the NotIn predicate on the "info" field. +func InfoNotIn(vs ...string) predicate.Series { + return predicate.Series(sql.FieldNotIn(FieldInfo, vs...)) +} + +// InfoGT applies the GT predicate on the "info" field. +func InfoGT(v string) predicate.Series { + return predicate.Series(sql.FieldGT(FieldInfo, v)) +} + +// InfoGTE applies the GTE predicate on the "info" field. +func InfoGTE(v string) predicate.Series { + return predicate.Series(sql.FieldGTE(FieldInfo, v)) +} + +// InfoLT applies the LT predicate on the "info" field. +func InfoLT(v string) predicate.Series { + return predicate.Series(sql.FieldLT(FieldInfo, v)) +} + +// InfoLTE applies the LTE predicate on the "info" field. +func InfoLTE(v string) predicate.Series { + return predicate.Series(sql.FieldLTE(FieldInfo, v)) +} + +// InfoContains applies the Contains predicate on the "info" field. +func InfoContains(v string) predicate.Series { + return predicate.Series(sql.FieldContains(FieldInfo, v)) +} + +// InfoHasPrefix applies the HasPrefix predicate on the "info" field. +func InfoHasPrefix(v string) predicate.Series { + return predicate.Series(sql.FieldHasPrefix(FieldInfo, v)) +} + +// InfoHasSuffix applies the HasSuffix predicate on the "info" field. +func InfoHasSuffix(v string) predicate.Series { + return predicate.Series(sql.FieldHasSuffix(FieldInfo, v)) +} + +// InfoIsNil applies the IsNil predicate on the "info" field. +func InfoIsNil() predicate.Series { + return predicate.Series(sql.FieldIsNull(FieldInfo)) +} + +// InfoNotNil applies the NotNil predicate on the "info" field. +func InfoNotNil() predicate.Series { + return predicate.Series(sql.FieldNotNull(FieldInfo)) +} + +// InfoEqualFold applies the EqualFold predicate on the "info" field. +func InfoEqualFold(v string) predicate.Series { + return predicate.Series(sql.FieldEqualFold(FieldInfo, v)) +} + +// InfoContainsFold applies the ContainsFold predicate on the "info" field. +func InfoContainsFold(v string) predicate.Series { + return predicate.Series(sql.FieldContainsFold(FieldInfo, v)) +} + +// ReleaseDateEQ applies the EQ predicate on the "release_date" field. +func ReleaseDateEQ(v time.Time) predicate.Series { + return predicate.Series(sql.FieldEQ(FieldReleaseDate, v)) +} + +// ReleaseDateNEQ applies the NEQ predicate on the "release_date" field. +func ReleaseDateNEQ(v time.Time) predicate.Series { + return predicate.Series(sql.FieldNEQ(FieldReleaseDate, v)) +} + +// ReleaseDateIn applies the In predicate on the "release_date" field. +func ReleaseDateIn(vs ...time.Time) predicate.Series { + return predicate.Series(sql.FieldIn(FieldReleaseDate, vs...)) +} + +// ReleaseDateNotIn applies the NotIn predicate on the "release_date" field. +func ReleaseDateNotIn(vs ...time.Time) predicate.Series { + return predicate.Series(sql.FieldNotIn(FieldReleaseDate, vs...)) +} + +// ReleaseDateGT applies the GT predicate on the "release_date" field. +func ReleaseDateGT(v time.Time) predicate.Series { + return predicate.Series(sql.FieldGT(FieldReleaseDate, v)) +} + +// ReleaseDateGTE applies the GTE predicate on the "release_date" field. +func ReleaseDateGTE(v time.Time) predicate.Series { + return predicate.Series(sql.FieldGTE(FieldReleaseDate, v)) +} + +// ReleaseDateLT applies the LT predicate on the "release_date" field. +func ReleaseDateLT(v time.Time) predicate.Series { + return predicate.Series(sql.FieldLT(FieldReleaseDate, v)) +} + +// ReleaseDateLTE applies the LTE predicate on the "release_date" field. +func ReleaseDateLTE(v time.Time) predicate.Series { + return predicate.Series(sql.FieldLTE(FieldReleaseDate, v)) +} + +// HasSeasons applies the HasEdge predicate on the "seasons" edge. +func HasSeasons() predicate.Series { + return predicate.Series(func(s *sql.Selector) { + step := sqlgraph.NewStep( + sqlgraph.From(Table, FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, SeasonsTable, SeasonsColumn), + ) + sqlgraph.HasNeighbors(s, step) + }) +} + +// HasSeasonsWith applies the HasEdge predicate on the "seasons" edge with a given conditions (other predicates). +func HasSeasonsWith(preds ...predicate.Season) predicate.Series { + return predicate.Series(func(s *sql.Selector) { + step := newSeasonsStep() + sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) { + for _, p := range preds { + p(s) + } + }) + }) +} + +// And groups predicates with the AND operator between them. +func And(predicates ...predicate.Series) predicate.Series { + return predicate.Series(sql.AndPredicates(predicates...)) +} + +// Or groups predicates with the OR operator between them. +func Or(predicates ...predicate.Series) predicate.Series { + return predicate.Series(sql.OrPredicates(predicates...)) +} + +// Not applies the not operator on the given predicate. +func Not(p predicate.Series) predicate.Series { + return predicate.Series(sql.NotPredicates(p)) +} diff --git a/examples/ydb/ent/series_create.go b/examples/ydb/ent/series_create.go new file mode 100644 index 0000000000..5d56ef3b6d --- /dev/null +++ b/examples/ydb/ent/series_create.go @@ -0,0 +1,287 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/examples/ydb/ent/season" + "entgo.io/ent/examples/ydb/ent/series" + "entgo.io/ent/schema/field" +) + +// SeriesCreate is the builder for creating a Series entity. +type SeriesCreate struct { + config + mutation *SeriesMutation + hooks []Hook + retryConfig sql.RetryConfig +} + +// SetTitle sets the "title" field. +func (_c *SeriesCreate) SetTitle(v string) *SeriesCreate { + _c.mutation.SetTitle(v) + return _c +} + +// SetInfo sets the "info" field. +func (_c *SeriesCreate) SetInfo(v string) *SeriesCreate { + _c.mutation.SetInfo(v) + return _c +} + +// SetNillableInfo sets the "info" field if the given value is not nil. +func (_c *SeriesCreate) SetNillableInfo(v *string) *SeriesCreate { + if v != nil { + _c.SetInfo(*v) + } + return _c +} + +// SetReleaseDate sets the "release_date" field. +func (_c *SeriesCreate) SetReleaseDate(v time.Time) *SeriesCreate { + _c.mutation.SetReleaseDate(v) + return _c +} + +// SetID sets the "id" field. +func (_c *SeriesCreate) SetID(v int64) *SeriesCreate { + _c.mutation.SetID(v) + return _c +} + +// AddSeasonIDs adds the "seasons" edge to the Season entity by IDs. +func (_c *SeriesCreate) AddSeasonIDs(ids ...int64) *SeriesCreate { + _c.mutation.AddSeasonIDs(ids...) + return _c +} + +// AddSeasons adds the "seasons" edges to the Season entity. +func (_c *SeriesCreate) AddSeasons(v ...*Season) *SeriesCreate { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _c.AddSeasonIDs(ids...) +} + +// Mutation returns the SeriesMutation object of the builder. +func (_c *SeriesCreate) Mutation() *SeriesMutation { + return _c.mutation +} + +// Save creates the Series in the database. +func (_c *SeriesCreate) Save(ctx context.Context) (*Series, error) { + return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks) +} + +// SaveX calls Save and panics if Save returns an error. +func (_c *SeriesCreate) SaveX(ctx context.Context) *Series { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *SeriesCreate) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *SeriesCreate) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_c *SeriesCreate) check() error { + if _, ok := _c.mutation.Title(); !ok { + return &ValidationError{Name: "title", err: errors.New(`ent: missing required field "Series.title"`)} + } + if v, ok := _c.mutation.Title(); ok { + if err := series.TitleValidator(v); err != nil { + return &ValidationError{Name: "title", err: fmt.Errorf(`ent: validator failed for field "Series.title": %w`, err)} + } + } + if _, ok := _c.mutation.ReleaseDate(); !ok { + return &ValidationError{Name: "release_date", err: errors.New(`ent: missing required field "Series.release_date"`)} + } + return nil +} + +func (_c *SeriesCreate) sqlSave(ctx context.Context) (*Series, error) { + if err := _c.check(); err != nil { + return nil, err + } + _node, _spec := _c.createSpec() + if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + if _spec.ID.Value != _node.ID { + id := _spec.ID.Value.(int64) + _node.ID = int64(id) + } + _c.mutation.id = &_node.ID + _c.mutation.done = true + return _node, nil +} + +func (_c *SeriesCreate) createSpec() (*Series, *sqlgraph.CreateSpec) { + var ( + _node = &Series{config: _c.config} + _spec = sqlgraph.NewCreateSpec(series.Table, sqlgraph.NewFieldSpec(series.FieldID, field.TypeInt64)) + ) + _spec.RetryConfig = _c.retryConfig + if id, ok := _c.mutation.ID(); ok { + _node.ID = id + _spec.ID.Value = id + } + if value, ok := _c.mutation.Title(); ok { + _spec.SetField(series.FieldTitle, field.TypeString, value) + _node.Title = value + } + if value, ok := _c.mutation.Info(); ok { + _spec.SetField(series.FieldInfo, field.TypeString, value) + _node.Info = value + } + if value, ok := _c.mutation.ReleaseDate(); ok { + _spec.SetField(series.FieldReleaseDate, field.TypeTime, value) + _node.ReleaseDate = value + } + if nodes := _c.mutation.SeasonsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: series.SeasonsTable, + Columns: []string{series.SeasonsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(season.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges = append(_spec.Edges, edge) + } + return _node, _spec +} + +// WithRetryOptions sets the retry options for the create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *SeriesCreate) WithRetryOptions(opts ...any) *SeriesCreate { + _c.retryConfig.Options = opts + return _c +} + +// SeriesCreateBulk is the builder for creating many Series entities in bulk. +type SeriesCreateBulk struct { + config + err error + builders []*SeriesCreate + retryConfig sql.RetryConfig +} + +// Save creates the Series entities in the database. +func (_c *SeriesCreateBulk) Save(ctx context.Context) ([]*Series, error) { + if _c.err != nil { + return nil, _c.err + } + specs := make([]*sqlgraph.CreateSpec, len(_c.builders)) + nodes := make([]*Series, len(_c.builders)) + mutators := make([]Mutator, len(_c.builders)) + for i := range _c.builders { + func(i int, root context.Context) { + builder := _c.builders[i] + var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { + mutation, ok := m.(*SeriesMutation) + if !ok { + return nil, fmt.Errorf("unexpected mutation type %T", m) + } + if err := builder.check(); err != nil { + return nil, err + } + builder.mutation = mutation + var err error + nodes[i], specs[i] = builder.createSpec() + if i < len(mutators)-1 { + _, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation) + } else { + spec := &sqlgraph.BatchCreateSpec{Nodes: specs} + spec.RetryConfig = _c.retryConfig + // Invoke the actual operation on the latest mutation in the chain. + if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil { + if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + } + } + if err != nil { + return nil, err + } + mutation.id = &nodes[i].ID + if specs[i].ID.Value != nil && nodes[i].ID == 0 { + id := specs[i].ID.Value.(int64) + nodes[i].ID = int64(id) + } + mutation.done = true + return nodes[i], nil + }) + for i := len(builder.hooks) - 1; i >= 0; i-- { + mut = builder.hooks[i](mut) + } + mutators[i] = mut + }(i, ctx) + } + if len(mutators) > 0 { + if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil { + return nil, err + } + } + return nodes, nil +} + +// SaveX is like Save, but panics if an error occurs. +func (_c *SeriesCreateBulk) SaveX(ctx context.Context) []*Series { + v, err := _c.Save(ctx) + if err != nil { + panic(err) + } + return v +} + +// Exec executes the query. +func (_c *SeriesCreateBulk) Exec(ctx context.Context) error { + _, err := _c.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_c *SeriesCreateBulk) ExecX(ctx context.Context) { + if err := _c.Exec(ctx); err != nil { + panic(err) + } +} + +// WithRetryOptions sets the retry options for the bulk create operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_c *SeriesCreateBulk) WithRetryOptions(opts ...any) *SeriesCreateBulk { + _c.retryConfig.Options = opts + return _c +} diff --git a/examples/ydb/ent/series_delete.go b/examples/ydb/ent/series_delete.go new file mode 100644 index 0000000000..45b6bd9ffb --- /dev/null +++ b/examples/ydb/ent/series_delete.go @@ -0,0 +1,101 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/examples/ydb/ent/predicate" + "entgo.io/ent/examples/ydb/ent/series" + "entgo.io/ent/schema/field" +) + +// SeriesDelete is the builder for deleting a Series entity. +type SeriesDelete struct { + config + hooks []Hook + mutation *SeriesMutation + retryConfig sql.RetryConfig +} + +// Where appends a list predicates to the SeriesDelete builder. +func (_d *SeriesDelete) Where(ps ...predicate.Series) *SeriesDelete { + _d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query and returns how many vertices were deleted. +func (_d *SeriesDelete) Exec(ctx context.Context) (int, error) { + return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks) +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *SeriesDelete) ExecX(ctx context.Context) int { + n, err := _d.Exec(ctx) + if err != nil { + panic(err) + } + return n +} + +func (_d *SeriesDelete) sqlExec(ctx context.Context) (int, error) { + _spec := sqlgraph.NewDeleteSpec(series.Table, sqlgraph.NewFieldSpec(series.FieldID, field.TypeInt64)) + _spec.RetryConfig = _d.retryConfig + if ps := _d.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec) + if err != nil && sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + _d.mutation.done = true + return affected, err +} + +// WithRetryOptions sets the retry options for the delete operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_d *SeriesDelete) WithRetryOptions(opts ...any) *SeriesDelete { + _d.retryConfig.Options = opts + return _d +} + +// SeriesDeleteOne is the builder for deleting a single Series entity. +type SeriesDeleteOne struct { + _d *SeriesDelete +} + +// Where appends a list predicates to the SeriesDelete builder. +func (_d *SeriesDeleteOne) Where(ps ...predicate.Series) *SeriesDeleteOne { + _d._d.mutation.Where(ps...) + return _d +} + +// Exec executes the deletion query. +func (_d *SeriesDeleteOne) Exec(ctx context.Context) error { + n, err := _d._d.Exec(ctx) + switch { + case err != nil: + return err + case n == 0: + return &NotFoundError{series.Label} + default: + return nil + } +} + +// ExecX is like Exec, but panics if an error occurs. +func (_d *SeriesDeleteOne) ExecX(ctx context.Context) { + if err := _d.Exec(ctx); err != nil { + panic(err) + } +} diff --git a/examples/ydb/ent/series_query.go b/examples/ydb/ent/series_query.go new file mode 100644 index 0000000000..76a915fada --- /dev/null +++ b/examples/ydb/ent/series_query.go @@ -0,0 +1,620 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "database/sql/driver" + "fmt" + "math" + + "entgo.io/ent" + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/examples/ydb/ent/predicate" + "entgo.io/ent/examples/ydb/ent/season" + "entgo.io/ent/examples/ydb/ent/series" + "entgo.io/ent/schema/field" +) + +// SeriesQuery is the builder for querying Series entities. +type SeriesQuery struct { + config + ctx *QueryContext + order []series.OrderOption + inters []Interceptor + predicates []predicate.Series + withSeasons *SeasonQuery + retryConfig sql.RetryConfig + // intermediate query (i.e. traversal path). + sql *sql.Selector + path func(context.Context) (*sql.Selector, error) +} + +// Where adds a new predicate for the SeriesQuery builder. +func (_q *SeriesQuery) Where(ps ...predicate.Series) *SeriesQuery { + _q.predicates = append(_q.predicates, ps...) + return _q +} + +// Limit the number of records to be returned by this query. +func (_q *SeriesQuery) Limit(limit int) *SeriesQuery { + _q.ctx.Limit = &limit + return _q +} + +// Offset to start from. +func (_q *SeriesQuery) Offset(offset int) *SeriesQuery { + _q.ctx.Offset = &offset + return _q +} + +// Unique configures the query builder to filter duplicate records on query. +// By default, unique is set to true, and can be disabled using this method. +func (_q *SeriesQuery) Unique(unique bool) *SeriesQuery { + _q.ctx.Unique = &unique + return _q +} + +// Order specifies how the records should be ordered. +func (_q *SeriesQuery) Order(o ...series.OrderOption) *SeriesQuery { + _q.order = append(_q.order, o...) + return _q +} + +// QuerySeasons chains the current query on the "seasons" edge. +func (_q *SeriesQuery) QuerySeasons() *SeasonQuery { + query := (&SeasonClient{config: _q.config}).Query() + query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + selector := _q.sqlQuery(ctx) + if err := selector.Err(); err != nil { + return nil, err + } + step := sqlgraph.NewStep( + sqlgraph.From(series.Table, series.FieldID, selector), + sqlgraph.To(season.Table, season.FieldID), + sqlgraph.Edge(sqlgraph.O2M, false, series.SeasonsTable, series.SeasonsColumn), + ) + fromU = sqlgraph.SetNeighbors(_q.driver.Dialect(), step) + return fromU, nil + } + return query +} + +// First returns the first Series entity from the query. +// Returns a *NotFoundError when no Series was found. +func (_q *SeriesQuery) First(ctx context.Context) (*Series, error) { + nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst)) + if err != nil { + return nil, err + } + if len(nodes) == 0 { + return nil, &NotFoundError{series.Label} + } + return nodes[0], nil +} + +// FirstX is like First, but panics if an error occurs. +func (_q *SeriesQuery) FirstX(ctx context.Context) *Series { + node, err := _q.First(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return node +} + +// FirstID returns the first Series ID from the query. +// Returns a *NotFoundError when no Series ID was found. +func (_q *SeriesQuery) FirstID(ctx context.Context) (id int64, err error) { + var ids []int64 + if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil { + return + } + if len(ids) == 0 { + err = &NotFoundError{series.Label} + return + } + return ids[0], nil +} + +// FirstIDX is like FirstID, but panics if an error occurs. +func (_q *SeriesQuery) FirstIDX(ctx context.Context) int64 { + id, err := _q.FirstID(ctx) + if err != nil && !IsNotFound(err) { + panic(err) + } + return id +} + +// Only returns a single Series entity found by the query, ensuring it only returns one. +// Returns a *NotSingularError when more than one Series entity is found. +// Returns a *NotFoundError when no Series entities are found. +func (_q *SeriesQuery) Only(ctx context.Context) (*Series, error) { + nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly)) + if err != nil { + return nil, err + } + switch len(nodes) { + case 1: + return nodes[0], nil + case 0: + return nil, &NotFoundError{series.Label} + default: + return nil, &NotSingularError{series.Label} + } +} + +// OnlyX is like Only, but panics if an error occurs. +func (_q *SeriesQuery) OnlyX(ctx context.Context) *Series { + node, err := _q.Only(ctx) + if err != nil { + panic(err) + } + return node +} + +// OnlyID is like Only, but returns the only Series ID in the query. +// Returns a *NotSingularError when more than one Series ID is found. +// Returns a *NotFoundError when no entities are found. +func (_q *SeriesQuery) OnlyID(ctx context.Context) (id int64, err error) { + var ids []int64 + if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil { + return + } + switch len(ids) { + case 1: + id = ids[0] + case 0: + err = &NotFoundError{series.Label} + default: + err = &NotSingularError{series.Label} + } + return +} + +// OnlyIDX is like OnlyID, but panics if an error occurs. +func (_q *SeriesQuery) OnlyIDX(ctx context.Context) int64 { + id, err := _q.OnlyID(ctx) + if err != nil { + panic(err) + } + return id +} + +// All executes the query and returns a list of SeriesSlice. +func (_q *SeriesQuery) All(ctx context.Context) ([]*Series, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll) + if err := _q.prepareQuery(ctx); err != nil { + return nil, err + } + qr := querierAll[[]*Series, *SeriesQuery]() + return withInterceptors[[]*Series](ctx, _q, qr, _q.inters) +} + +// AllX is like All, but panics if an error occurs. +func (_q *SeriesQuery) AllX(ctx context.Context) []*Series { + nodes, err := _q.All(ctx) + if err != nil { + panic(err) + } + return nodes +} + +// IDs executes the query and returns a list of Series IDs. +func (_q *SeriesQuery) IDs(ctx context.Context) (ids []int64, err error) { + if _q.ctx.Unique == nil && _q.path != nil { + _q.Unique(true) + } + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs) + if err = _q.Select(series.FieldID).Scan(ctx, &ids); err != nil { + return nil, err + } + return ids, nil +} + +// IDsX is like IDs, but panics if an error occurs. +func (_q *SeriesQuery) IDsX(ctx context.Context) []int64 { + ids, err := _q.IDs(ctx) + if err != nil { + panic(err) + } + return ids +} + +// Count returns the count of the given query. +func (_q *SeriesQuery) Count(ctx context.Context) (int, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount) + if err := _q.prepareQuery(ctx); err != nil { + return 0, err + } + return withInterceptors[int](ctx, _q, querierCount[*SeriesQuery](), _q.inters) +} + +// CountX is like Count, but panics if an error occurs. +func (_q *SeriesQuery) CountX(ctx context.Context) int { + count, err := _q.Count(ctx) + if err != nil { + panic(err) + } + return count +} + +// Exist returns true if the query has elements in the graph. +func (_q *SeriesQuery) Exist(ctx context.Context) (bool, error) { + ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist) + switch _, err := _q.FirstID(ctx); { + case IsNotFound(err): + return false, nil + case err != nil: + return false, fmt.Errorf("ent: check existence: %w", err) + default: + return true, nil + } +} + +// ExistX is like Exist, but panics if an error occurs. +func (_q *SeriesQuery) ExistX(ctx context.Context) bool { + exist, err := _q.Exist(ctx) + if err != nil { + panic(err) + } + return exist +} + +// Clone returns a duplicate of the SeriesQuery builder, including all associated steps. It can be +// used to prepare common query builders and use them differently after the clone is made. +func (_q *SeriesQuery) Clone() *SeriesQuery { + if _q == nil { + return nil + } + return &SeriesQuery{ + config: _q.config, + ctx: _q.ctx.Clone(), + order: append([]series.OrderOption{}, _q.order...), + inters: append([]Interceptor{}, _q.inters...), + predicates: append([]predicate.Series{}, _q.predicates...), + withSeasons: _q.withSeasons.Clone(), + // clone intermediate query. + sql: _q.sql.Clone(), + path: _q.path, + } +} + +// WithSeasons tells the query-builder to eager-load the nodes that are connected to +// the "seasons" edge. The optional arguments are used to configure the query builder of the edge. +func (_q *SeriesQuery) WithSeasons(opts ...func(*SeasonQuery)) *SeriesQuery { + query := (&SeasonClient{config: _q.config}).Query() + for _, opt := range opts { + opt(query) + } + _q.withSeasons = query + return _q +} + +// GroupBy is used to group vertices by one or more fields/columns. +// It is often used with aggregate functions, like: count, max, mean, min, sum. +// +// Example: +// +// var v []struct { +// Title string `json:"title,omitempty"` +// Count int `json:"count,omitempty"` +// } +// +// client.Series.Query(). +// GroupBy(series.FieldTitle). +// Aggregate(ent.Count()). +// Scan(ctx, &v) +func (_q *SeriesQuery) GroupBy(field string, fields ...string) *SeriesGroupBy { + _q.ctx.Fields = append([]string{field}, fields...) + grbuild := &SeriesGroupBy{build: _q} + grbuild.flds = &_q.ctx.Fields + grbuild.label = series.Label + grbuild.scan = grbuild.Scan + return grbuild +} + +// Select allows the selection one or more fields/columns for the given query, +// instead of selecting all fields in the entity. +// +// Example: +// +// var v []struct { +// Title string `json:"title,omitempty"` +// } +// +// client.Series.Query(). +// Select(series.FieldTitle). +// Scan(ctx, &v) +func (_q *SeriesQuery) Select(fields ...string) *SeriesSelect { + _q.ctx.Fields = append(_q.ctx.Fields, fields...) + sbuild := &SeriesSelect{SeriesQuery: _q} + sbuild.label = series.Label + sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan + return sbuild +} + +// Aggregate returns a SeriesSelect configured with the given aggregations. +func (_q *SeriesQuery) Aggregate(fns ...AggregateFunc) *SeriesSelect { + return _q.Select().Aggregate(fns...) +} + +func (_q *SeriesQuery) prepareQuery(ctx context.Context) error { + for _, inter := range _q.inters { + if inter == nil { + return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)") + } + if trv, ok := inter.(Traverser); ok { + if err := trv.Traverse(ctx, _q); err != nil { + return err + } + } + } + for _, f := range _q.ctx.Fields { + if !series.ValidColumn(f) { + return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + } + if _q.path != nil { + prev, err := _q.path(ctx) + if err != nil { + return err + } + _q.sql = prev + } + return nil +} + +func (_q *SeriesQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Series, error) { + var ( + nodes = []*Series{} + _spec = _q.querySpec() + loadedTypes = [1]bool{ + _q.withSeasons != nil, + } + ) + _spec.ScanValues = func(columns []string) ([]any, error) { + return (*Series).scanValues(nil, columns) + } + _spec.Assign = func(columns []string, values []any) error { + node := &Series{config: _q.config} + nodes = append(nodes, node) + node.Edges.loadedTypes = loadedTypes + return node.assignValues(columns, values) + } + _spec.RetryConfig = _q.retryConfig + for i := range hooks { + hooks[i](ctx, _spec) + } + if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil { + return nil, err + } + if len(nodes) == 0 { + return nodes, nil + } + if query := _q.withSeasons; query != nil { + if err := _q.loadSeasons(ctx, query, nodes, + func(n *Series) { n.Edges.Seasons = []*Season{} }, + func(n *Series, e *Season) { n.Edges.Seasons = append(n.Edges.Seasons, e) }); err != nil { + return nil, err + } + } + return nodes, nil +} + +func (_q *SeriesQuery) loadSeasons(ctx context.Context, query *SeasonQuery, nodes []*Series, init func(*Series), assign func(*Series, *Season)) error { + fks := make([]driver.Value, 0, len(nodes)) + nodeids := make(map[int64]*Series) + for i := range nodes { + fks = append(fks, nodes[i].ID) + nodeids[nodes[i].ID] = nodes[i] + if init != nil { + init(nodes[i]) + } + } + if len(query.ctx.Fields) > 0 { + query.ctx.AppendFieldOnce(season.FieldSeriesID) + } + query.Where(predicate.Season(func(s *sql.Selector) { + s.Where(sql.InValues(s.C(series.SeasonsColumn), fks...)) + })) + neighbors, err := query.All(ctx) + if err != nil { + return err + } + for _, n := range neighbors { + fk := n.SeriesID + node, ok := nodeids[fk] + if !ok { + return fmt.Errorf(`unexpected referenced foreign-key "series_id" returned %v for node %v`, fk, n.ID) + } + assign(node, n) + } + return nil +} + +func (_q *SeriesQuery) sqlCount(ctx context.Context) (int, error) { + _spec := _q.querySpec() + _spec.RetryConfig = _q.retryConfig + _spec.Node.Columns = _q.ctx.Fields + if len(_q.ctx.Fields) > 0 { + _spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique + } + return sqlgraph.CountNodes(ctx, _q.driver, _spec) +} + +func (_q *SeriesQuery) querySpec() *sqlgraph.QuerySpec { + _spec := sqlgraph.NewQuerySpec(series.Table, series.Columns, sqlgraph.NewFieldSpec(series.FieldID, field.TypeInt64)) + _spec.From = _q.sql + if unique := _q.ctx.Unique; unique != nil { + _spec.Unique = *unique + } else if _q.path != nil { + _spec.Unique = true + } + if fields := _q.ctx.Fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, series.FieldID) + for i := range fields { + if fields[i] != series.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) + } + } + } + if ps := _q.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if limit := _q.ctx.Limit; limit != nil { + _spec.Limit = *limit + } + if offset := _q.ctx.Offset; offset != nil { + _spec.Offset = *offset + } + if ps := _q.order; len(ps) > 0 { + _spec.Order = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + return _spec +} + +func (_q *SeriesQuery) sqlQuery(ctx context.Context) *sql.Selector { + builder := sql.Dialect(_q.driver.Dialect()) + t1 := builder.Table(series.Table) + columns := _q.ctx.Fields + if len(columns) == 0 { + columns = series.Columns + } + selector := builder.Select(t1.Columns(columns...)...).From(t1) + if _q.sql != nil { + selector = _q.sql + selector.Select(selector.Columns(columns...)...) + } + if _q.ctx.Unique != nil && *_q.ctx.Unique { + selector.Distinct() + } + for _, p := range _q.predicates { + p(selector) + } + for _, p := range _q.order { + p(selector) + } + if offset := _q.ctx.Offset; offset != nil { + // limit is mandatory for offset clause. We start + // with default value, and override it below if needed. + selector.Offset(*offset).Limit(math.MaxInt32) + } + if limit := _q.ctx.Limit; limit != nil { + selector.Limit(*limit) + } + return selector +} + +// WithRetryOptions sets the retry options for the query operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_q *SeriesQuery) WithRetryOptions(opts ...any) *SeriesQuery { + _q.retryConfig.Options = opts + return _q +} + +// SeriesGroupBy is the group-by builder for Series entities. +type SeriesGroupBy struct { + selector + build *SeriesQuery +} + +// Aggregate adds the given aggregation functions to the group-by query. +func (_g *SeriesGroupBy) Aggregate(fns ...AggregateFunc) *SeriesGroupBy { + _g.fns = append(_g.fns, fns...) + return _g +} + +// Scan applies the selector query and scans the result into the given value. +func (_g *SeriesGroupBy) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy) + if err := _g.build.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*SeriesQuery, *SeriesGroupBy](ctx, _g.build, _g, _g.build.inters, v) +} + +func (_g *SeriesGroupBy) sqlScan(ctx context.Context, root *SeriesQuery, v any) error { + selector := root.sqlQuery(ctx).Select() + aggregation := make([]string, 0, len(_g.fns)) + for _, fn := range _g.fns { + aggregation = append(aggregation, fn(selector)) + } + if len(selector.SelectedColumns()) == 0 { + columns := make([]string, 0, len(*_g.flds)+len(_g.fns)) + for _, f := range *_g.flds { + columns = append(columns, selector.C(f)) + } + columns = append(columns, aggregation...) + selector.Select(columns...) + } + selector.GroupBy(selector.Columns(*_g.flds...)...) + if err := selector.Err(); err != nil { + return err + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _g.build.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} + +// SeriesSelect is the builder for selecting fields of Series entities. +type SeriesSelect struct { + *SeriesQuery + selector +} + +// Aggregate adds the given aggregation functions to the selector query. +func (_s *SeriesSelect) Aggregate(fns ...AggregateFunc) *SeriesSelect { + _s.fns = append(_s.fns, fns...) + return _s +} + +// Scan applies the selector query and scans the result into the given value. +func (_s *SeriesSelect) Scan(ctx context.Context, v any) error { + ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect) + if err := _s.prepareQuery(ctx); err != nil { + return err + } + return scanWithInterceptors[*SeriesQuery, *SeriesSelect](ctx, _s.SeriesQuery, _s, _s.inters, v) +} + +func (_s *SeriesSelect) sqlScan(ctx context.Context, root *SeriesQuery, v any) error { + selector := root.sqlQuery(ctx) + aggregation := make([]string, 0, len(_s.fns)) + for _, fn := range _s.fns { + aggregation = append(aggregation, fn(selector)) + } + switch n := len(*_s.selector.flds); { + case n == 0 && len(aggregation) > 0: + selector.Select(aggregation...) + case n != 0 && len(aggregation) > 0: + selector.AppendSelect(aggregation...) + } + rows := &sql.Rows{} + query, args := selector.Query() + if err := _s.driver.Query(ctx, query, args, rows); err != nil { + return err + } + defer rows.Close() + return sql.ScanSlice(rows, v) +} diff --git a/examples/ydb/ent/series_update.go b/examples/ydb/ent/series_update.go new file mode 100644 index 0000000000..e7cae45802 --- /dev/null +++ b/examples/ydb/ent/series_update.go @@ -0,0 +1,507 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "errors" + "fmt" + "time" + + "entgo.io/ent/dialect/sql" + "entgo.io/ent/dialect/sql/sqlgraph" + "entgo.io/ent/examples/ydb/ent/predicate" + "entgo.io/ent/examples/ydb/ent/season" + "entgo.io/ent/examples/ydb/ent/series" + "entgo.io/ent/schema/field" +) + +// SeriesUpdate is the builder for updating Series entities. +type SeriesUpdate struct { + config + hooks []Hook + mutation *SeriesMutation + retryConfig sql.RetryConfig +} + +// Where appends a list predicates to the SeriesUpdate builder. +func (_u *SeriesUpdate) Where(ps ...predicate.Series) *SeriesUpdate { + _u.mutation.Where(ps...) + return _u +} + +// SetTitle sets the "title" field. +func (_u *SeriesUpdate) SetTitle(v string) *SeriesUpdate { + _u.mutation.SetTitle(v) + return _u +} + +// SetNillableTitle sets the "title" field if the given value is not nil. +func (_u *SeriesUpdate) SetNillableTitle(v *string) *SeriesUpdate { + if v != nil { + _u.SetTitle(*v) + } + return _u +} + +// SetInfo sets the "info" field. +func (_u *SeriesUpdate) SetInfo(v string) *SeriesUpdate { + _u.mutation.SetInfo(v) + return _u +} + +// SetNillableInfo sets the "info" field if the given value is not nil. +func (_u *SeriesUpdate) SetNillableInfo(v *string) *SeriesUpdate { + if v != nil { + _u.SetInfo(*v) + } + return _u +} + +// ClearInfo clears the value of the "info" field. +func (_u *SeriesUpdate) ClearInfo() *SeriesUpdate { + _u.mutation.ClearInfo() + return _u +} + +// SetReleaseDate sets the "release_date" field. +func (_u *SeriesUpdate) SetReleaseDate(v time.Time) *SeriesUpdate { + _u.mutation.SetReleaseDate(v) + return _u +} + +// SetNillableReleaseDate sets the "release_date" field if the given value is not nil. +func (_u *SeriesUpdate) SetNillableReleaseDate(v *time.Time) *SeriesUpdate { + if v != nil { + _u.SetReleaseDate(*v) + } + return _u +} + +// AddSeasonIDs adds the "seasons" edge to the Season entity by IDs. +func (_u *SeriesUpdate) AddSeasonIDs(ids ...int64) *SeriesUpdate { + _u.mutation.AddSeasonIDs(ids...) + return _u +} + +// AddSeasons adds the "seasons" edges to the Season entity. +func (_u *SeriesUpdate) AddSeasons(v ...*Season) *SeriesUpdate { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.AddSeasonIDs(ids...) +} + +// Mutation returns the SeriesMutation object of the builder. +func (_u *SeriesUpdate) Mutation() *SeriesMutation { + return _u.mutation +} + +// ClearSeasons clears all "seasons" edges to the Season entity. +func (_u *SeriesUpdate) ClearSeasons() *SeriesUpdate { + _u.mutation.ClearSeasons() + return _u +} + +// RemoveSeasonIDs removes the "seasons" edge to Season entities by IDs. +func (_u *SeriesUpdate) RemoveSeasonIDs(ids ...int64) *SeriesUpdate { + _u.mutation.RemoveSeasonIDs(ids...) + return _u +} + +// RemoveSeasons removes "seasons" edges to Season entities. +func (_u *SeriesUpdate) RemoveSeasons(v ...*Season) *SeriesUpdate { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.RemoveSeasonIDs(ids...) +} + +// Save executes the query and returns the number of nodes affected by the update operation. +func (_u *SeriesUpdate) Save(ctx context.Context) (int, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *SeriesUpdate) SaveX(ctx context.Context) int { + affected, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return affected +} + +// Exec executes the query. +func (_u *SeriesUpdate) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *SeriesUpdate) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_u *SeriesUpdate) check() error { + if v, ok := _u.mutation.Title(); ok { + if err := series.TitleValidator(v); err != nil { + return &ValidationError{Name: "title", err: fmt.Errorf(`ent: validator failed for field "Series.title": %w`, err)} + } + } + return nil +} + +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *SeriesUpdate) WithRetryOptions(opts ...any) *SeriesUpdate { + _u.retryConfig.Options = opts + return _u +} + +func (_u *SeriesUpdate) sqlSave(ctx context.Context) (_node int, err error) { + if err := _u.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(series.Table, series.Columns, sqlgraph.NewFieldSpec(series.FieldID, field.TypeInt64)) + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.Title(); ok { + _spec.SetField(series.FieldTitle, field.TypeString, value) + } + if value, ok := _u.mutation.Info(); ok { + _spec.SetField(series.FieldInfo, field.TypeString, value) + } + if _u.mutation.InfoCleared() { + _spec.ClearField(series.FieldInfo, field.TypeString) + } + if value, ok := _u.mutation.ReleaseDate(); ok { + _spec.SetField(series.FieldReleaseDate, field.TypeTime, value) + } + if _u.mutation.SeasonsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: series.SeasonsTable, + Columns: []string{series.SeasonsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(season.FieldID, field.TypeInt64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.RemovedSeasonsIDs(); len(nodes) > 0 && !_u.mutation.SeasonsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: series.SeasonsTable, + Columns: []string{series.SeasonsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(season.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.SeasonsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: series.SeasonsTable, + Columns: []string{series.SeasonsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(season.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + _spec.RetryConfig = _u.retryConfig + if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil { + if sqlgraph.IsNotFound(err) { + err = &NotFoundError{series.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return 0, err + } + _u.mutation.done = true + return _node, nil +} + +// SeriesUpdateOne is the builder for updating a single Series entity. +type SeriesUpdateOne struct { + config + fields []string + hooks []Hook + mutation *SeriesMutation + retryConfig sql.RetryConfig +} + +// SetTitle sets the "title" field. +func (_u *SeriesUpdateOne) SetTitle(v string) *SeriesUpdateOne { + _u.mutation.SetTitle(v) + return _u +} + +// SetNillableTitle sets the "title" field if the given value is not nil. +func (_u *SeriesUpdateOne) SetNillableTitle(v *string) *SeriesUpdateOne { + if v != nil { + _u.SetTitle(*v) + } + return _u +} + +// SetInfo sets the "info" field. +func (_u *SeriesUpdateOne) SetInfo(v string) *SeriesUpdateOne { + _u.mutation.SetInfo(v) + return _u +} + +// SetNillableInfo sets the "info" field if the given value is not nil. +func (_u *SeriesUpdateOne) SetNillableInfo(v *string) *SeriesUpdateOne { + if v != nil { + _u.SetInfo(*v) + } + return _u +} + +// ClearInfo clears the value of the "info" field. +func (_u *SeriesUpdateOne) ClearInfo() *SeriesUpdateOne { + _u.mutation.ClearInfo() + return _u +} + +// SetReleaseDate sets the "release_date" field. +func (_u *SeriesUpdateOne) SetReleaseDate(v time.Time) *SeriesUpdateOne { + _u.mutation.SetReleaseDate(v) + return _u +} + +// SetNillableReleaseDate sets the "release_date" field if the given value is not nil. +func (_u *SeriesUpdateOne) SetNillableReleaseDate(v *time.Time) *SeriesUpdateOne { + if v != nil { + _u.SetReleaseDate(*v) + } + return _u +} + +// AddSeasonIDs adds the "seasons" edge to the Season entity by IDs. +func (_u *SeriesUpdateOne) AddSeasonIDs(ids ...int64) *SeriesUpdateOne { + _u.mutation.AddSeasonIDs(ids...) + return _u +} + +// AddSeasons adds the "seasons" edges to the Season entity. +func (_u *SeriesUpdateOne) AddSeasons(v ...*Season) *SeriesUpdateOne { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.AddSeasonIDs(ids...) +} + +// Mutation returns the SeriesMutation object of the builder. +func (_u *SeriesUpdateOne) Mutation() *SeriesMutation { + return _u.mutation +} + +// ClearSeasons clears all "seasons" edges to the Season entity. +func (_u *SeriesUpdateOne) ClearSeasons() *SeriesUpdateOne { + _u.mutation.ClearSeasons() + return _u +} + +// RemoveSeasonIDs removes the "seasons" edge to Season entities by IDs. +func (_u *SeriesUpdateOne) RemoveSeasonIDs(ids ...int64) *SeriesUpdateOne { + _u.mutation.RemoveSeasonIDs(ids...) + return _u +} + +// RemoveSeasons removes "seasons" edges to Season entities. +func (_u *SeriesUpdateOne) RemoveSeasons(v ...*Season) *SeriesUpdateOne { + ids := make([]int64, len(v)) + for i := range v { + ids[i] = v[i].ID + } + return _u.RemoveSeasonIDs(ids...) +} + +// Where appends a list predicates to the SeriesUpdate builder. +func (_u *SeriesUpdateOne) Where(ps ...predicate.Series) *SeriesUpdateOne { + _u.mutation.Where(ps...) + return _u +} + +// Select allows selecting one or more fields (columns) of the returned entity. +// The default is selecting all fields defined in the entity schema. +func (_u *SeriesUpdateOne) Select(field string, fields ...string) *SeriesUpdateOne { + _u.fields = append([]string{field}, fields...) + return _u +} + +// Save executes the query and returns the updated Series entity. +func (_u *SeriesUpdateOne) Save(ctx context.Context) (*Series, error) { + return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks) +} + +// SaveX is like Save, but panics if an error occurs. +func (_u *SeriesUpdateOne) SaveX(ctx context.Context) *Series { + node, err := _u.Save(ctx) + if err != nil { + panic(err) + } + return node +} + +// Exec executes the query on the entity. +func (_u *SeriesUpdateOne) Exec(ctx context.Context) error { + _, err := _u.Save(ctx) + return err +} + +// ExecX is like Exec, but panics if an error occurs. +func (_u *SeriesUpdateOne) ExecX(ctx context.Context) { + if err := _u.Exec(ctx); err != nil { + panic(err) + } +} + +// check runs all checks and user-defined validators on the builder. +func (_u *SeriesUpdateOne) check() error { + if v, ok := _u.mutation.Title(); ok { + if err := series.TitleValidator(v); err != nil { + return &ValidationError{Name: "title", err: fmt.Errorf(`ent: validator failed for field "Series.title": %w`, err)} + } + } + return nil +} + +// WithRetryOptions sets the retry options for the update operation. +// For YDB, these should be retry.Option values from ydb-go-sdk. +func (_u *SeriesUpdateOne) WithRetryOptions(opts ...any) *SeriesUpdateOne { + _u.retryConfig.Options = opts + return _u +} + +func (_u *SeriesUpdateOne) sqlSave(ctx context.Context) (_node *Series, err error) { + if err := _u.check(); err != nil { + return _node, err + } + _spec := sqlgraph.NewUpdateSpec(series.Table, series.Columns, sqlgraph.NewFieldSpec(series.FieldID, field.TypeInt64)) + id, ok := _u.mutation.ID() + if !ok { + return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "Series.id" for update`)} + } + _spec.Node.ID.Value = id + if fields := _u.fields; len(fields) > 0 { + _spec.Node.Columns = make([]string, 0, len(fields)) + _spec.Node.Columns = append(_spec.Node.Columns, series.FieldID) + for _, f := range fields { + if !series.ValidColumn(f) { + return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} + } + if f != series.FieldID { + _spec.Node.Columns = append(_spec.Node.Columns, f) + } + } + } + if ps := _u.mutation.predicates; len(ps) > 0 { + _spec.Predicate = func(selector *sql.Selector) { + for i := range ps { + ps[i](selector) + } + } + } + if value, ok := _u.mutation.Title(); ok { + _spec.SetField(series.FieldTitle, field.TypeString, value) + } + if value, ok := _u.mutation.Info(); ok { + _spec.SetField(series.FieldInfo, field.TypeString, value) + } + if _u.mutation.InfoCleared() { + _spec.ClearField(series.FieldInfo, field.TypeString) + } + if value, ok := _u.mutation.ReleaseDate(); ok { + _spec.SetField(series.FieldReleaseDate, field.TypeTime, value) + } + if _u.mutation.SeasonsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: series.SeasonsTable, + Columns: []string{series.SeasonsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(season.FieldID, field.TypeInt64), + }, + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.RemovedSeasonsIDs(); len(nodes) > 0 && !_u.mutation.SeasonsCleared() { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: series.SeasonsTable, + Columns: []string{series.SeasonsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(season.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Clear = append(_spec.Edges.Clear, edge) + } + if nodes := _u.mutation.SeasonsIDs(); len(nodes) > 0 { + edge := &sqlgraph.EdgeSpec{ + Rel: sqlgraph.O2M, + Inverse: false, + Table: series.SeasonsTable, + Columns: []string{series.SeasonsColumn}, + Bidi: false, + Target: &sqlgraph.EdgeTarget{ + IDSpec: sqlgraph.NewFieldSpec(season.FieldID, field.TypeInt64), + }, + } + for _, k := range nodes { + edge.Target.Nodes = append(edge.Target.Nodes, k) + } + _spec.Edges.Add = append(_spec.Edges.Add, edge) + } + _spec.RetryConfig = _u.retryConfig + _node = &Series{config: _u.config} + _spec.Assign = _node.assignValues + _spec.ScanValues = _node.scanValues + if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil { + if sqlgraph.IsNotFound(err) { + err = &NotFoundError{series.Label} + } else if sqlgraph.IsConstraintError(err) { + err = &ConstraintError{msg: err.Error(), wrap: err} + } + return nil, err + } + _u.mutation.done = true + return _node, nil +} diff --git a/examples/ydb/ent/tx.go b/examples/ydb/ent/tx.go new file mode 100644 index 0000000000..12c3ea1cbb --- /dev/null +++ b/examples/ydb/ent/tx.go @@ -0,0 +1,220 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +// Code generated by ent, DO NOT EDIT. + +package ent + +import ( + "context" + "sync" + + "entgo.io/ent/dialect" +) + +// Tx is a transactional client that is created by calling Client.Tx(). +type Tx struct { + config + // Episode is the client for interacting with the Episode builders. + Episode *EpisodeClient + // Season is the client for interacting with the Season builders. + Season *SeasonClient + // Series is the client for interacting with the Series builders. + Series *SeriesClient + + // lazily loaded. + client *Client + clientOnce sync.Once + // ctx lives for the life of the transaction. It is + // the same context used by the underlying connection. + ctx context.Context +} + +type ( + // Committer is the interface that wraps the Commit method. + Committer interface { + Commit(context.Context, *Tx) error + } + + // The CommitFunc type is an adapter to allow the use of ordinary + // function as a Committer. If f is a function with the appropriate + // signature, CommitFunc(f) is a Committer that calls f. + CommitFunc func(context.Context, *Tx) error + + // CommitHook defines the "commit middleware". A function that gets a Committer + // and returns a Committer. For example: + // + // hook := func(next ent.Committer) ent.Committer { + // return ent.CommitFunc(func(ctx context.Context, tx *ent.Tx) error { + // // Do some stuff before. + // if err := next.Commit(ctx, tx); err != nil { + // return err + // } + // // Do some stuff after. + // return nil + // }) + // } + // + CommitHook func(Committer) Committer +) + +// Commit calls f(ctx, m). +func (f CommitFunc) Commit(ctx context.Context, tx *Tx) error { + return f(ctx, tx) +} + +// Commit commits the transaction. +func (tx *Tx) Commit() error { + txDriver := tx.config.driver.(*txDriver) + var fn Committer = CommitFunc(func(context.Context, *Tx) error { + return txDriver.tx.Commit() + }) + txDriver.mu.Lock() + hooks := append([]CommitHook(nil), txDriver.onCommit...) + txDriver.mu.Unlock() + for i := len(hooks) - 1; i >= 0; i-- { + fn = hooks[i](fn) + } + return fn.Commit(tx.ctx, tx) +} + +// OnCommit adds a hook to call on commit. +func (tx *Tx) OnCommit(f CommitHook) { + txDriver := tx.config.driver.(*txDriver) + txDriver.mu.Lock() + txDriver.onCommit = append(txDriver.onCommit, f) + txDriver.mu.Unlock() +} + +type ( + // Rollbacker is the interface that wraps the Rollback method. + Rollbacker interface { + Rollback(context.Context, *Tx) error + } + + // The RollbackFunc type is an adapter to allow the use of ordinary + // function as a Rollbacker. If f is a function with the appropriate + // signature, RollbackFunc(f) is a Rollbacker that calls f. + RollbackFunc func(context.Context, *Tx) error + + // RollbackHook defines the "rollback middleware". A function that gets a Rollbacker + // and returns a Rollbacker. For example: + // + // hook := func(next ent.Rollbacker) ent.Rollbacker { + // return ent.RollbackFunc(func(ctx context.Context, tx *ent.Tx) error { + // // Do some stuff before. + // if err := next.Rollback(ctx, tx); err != nil { + // return err + // } + // // Do some stuff after. + // return nil + // }) + // } + // + RollbackHook func(Rollbacker) Rollbacker +) + +// Rollback calls f(ctx, m). +func (f RollbackFunc) Rollback(ctx context.Context, tx *Tx) error { + return f(ctx, tx) +} + +// Rollback rollbacks the transaction. +func (tx *Tx) Rollback() error { + txDriver := tx.config.driver.(*txDriver) + var fn Rollbacker = RollbackFunc(func(context.Context, *Tx) error { + return txDriver.tx.Rollback() + }) + txDriver.mu.Lock() + hooks := append([]RollbackHook(nil), txDriver.onRollback...) + txDriver.mu.Unlock() + for i := len(hooks) - 1; i >= 0; i-- { + fn = hooks[i](fn) + } + return fn.Rollback(tx.ctx, tx) +} + +// OnRollback adds a hook to call on rollback. +func (tx *Tx) OnRollback(f RollbackHook) { + txDriver := tx.config.driver.(*txDriver) + txDriver.mu.Lock() + txDriver.onRollback = append(txDriver.onRollback, f) + txDriver.mu.Unlock() +} + +// Client returns a Client that binds to current transaction. +func (tx *Tx) Client() *Client { + tx.clientOnce.Do(func() { + tx.client = &Client{config: tx.config} + tx.client.init() + }) + return tx.client +} + +func (tx *Tx) init() { + tx.Episode = NewEpisodeClient(tx.config) + tx.Season = NewSeasonClient(tx.config) + tx.Series = NewSeriesClient(tx.config) +} + +// txDriver wraps the given dialect.Tx with a nop dialect.Driver implementation. +// The idea is to support transactions without adding any extra code to the builders. +// When a builder calls to driver.Tx(), it gets the same dialect.Tx instance. +// Commit and Rollback are nop for the internal builders and the user must call one +// of them in order to commit or rollback the transaction. +// +// If a closed transaction is embedded in one of the generated entities, and the entity +// applies a query, for example: Episode.QueryXXX(), the query will be executed +// through the driver which created this transaction. +// +// Note that txDriver is not goroutine safe. +type txDriver struct { + // the driver we started the transaction from. + drv dialect.Driver + // tx is the underlying transaction. + tx dialect.Tx + // completion hooks. + mu sync.Mutex + onCommit []CommitHook + onRollback []RollbackHook +} + +// newTx creates a new transactional driver. +func newTx(ctx context.Context, drv dialect.Driver) (*txDriver, error) { + tx, err := drv.Tx(ctx) + if err != nil { + return nil, err + } + return &txDriver{tx: tx, drv: drv}, nil +} + +// Tx returns the transaction wrapper (txDriver) to avoid Commit or Rollback calls +// from the internal builders. Should be called only by the internal builders. +func (tx *txDriver) Tx(context.Context) (dialect.Tx, error) { return tx, nil } + +// Dialect returns the dialect of the driver we started the transaction from. +func (tx *txDriver) Dialect() string { return tx.drv.Dialect() } + +// Close is a nop close. +func (*txDriver) Close() error { return nil } + +// Commit is a nop commit for the internal builders. +// User must call `Tx.Commit` in order to commit the transaction. +func (*txDriver) Commit() error { return nil } + +// Rollback is a nop rollback for the internal builders. +// User must call `Tx.Rollback` in order to rollback the transaction. +func (*txDriver) Rollback() error { return nil } + +// Exec calls tx.Exec. +func (tx *txDriver) Exec(ctx context.Context, query string, args, v any) error { + return tx.tx.Exec(ctx, query, args, v) +} + +// Query calls tx.Query. +func (tx *txDriver) Query(ctx context.Context, query string, args, v any) error { + return tx.tx.Query(ctx, query, args, v) +} + +var _ dialect.Driver = (*txDriver)(nil) diff --git a/examples/ydb/example.go b/examples/ydb/example.go new file mode 100644 index 0000000000..797b9cf311 --- /dev/null +++ b/examples/ydb/example.go @@ -0,0 +1,194 @@ +// Copyright 2019-present Facebook Inc. All rights reserved. +// This source code is licensed under the Apache 2.0 license found +// in the LICENSE file in the root directory of this source tree. + +package main + +import ( + "context" + "fmt" + "log" + "time" + + "ariga.io/atlas/sql/migrate" + "entgo.io/ent/dialect" + "entgo.io/ent/dialect/sql/schema" + "entgo.io/ent/examples/ydb/ent" + "entgo.io/ent/examples/ydb/ent/episode" + "entgo.io/ent/examples/ydb/ent/season" + "entgo.io/ent/examples/ydb/ent/series" + + "github.com/ydb-platform/ydb-go-sdk/v3/retry" +) + +func main() { + // Open connection to YDB + client, err := ent.Open("ydb", "grpc://localhost:2136/local") + if err != nil { + log.Fatalf("failed opening connection to ydb: %v", err) + } + defer client.Close() + + ctx := context.Background() + + // Run the auto migration tool to create tables with debug logging + err = client.Schema.Create( + ctx, + schema.WithDropColumn(true), + schema.WithDropIndex(true), + schema.WithApplyHook(func(next schema.Applier) schema.Applier { + return schema.ApplyFunc(func(ctx context.Context, conn dialect.ExecQuerier, plan *migrate.Plan) error { + log.Println("=== DDL Commands ===") + for i, c := range plan.Changes { + log.Printf("DDL[%d] Comment: %s", i, c.Comment) + log.Printf("DDL[%d] Cmd: %s", i, c.Cmd) + log.Printf("DDL[%d] Args: %v", i, c.Args) + } + return next.Apply(ctx, conn, plan) + }) + }), + ) + if err != nil { + log.Fatalf("failed creating schema resources: %v", err) + } + + // Clear existing data before running example + log.Println("Clearing existing data...") + if _, err := client.Episode.Delete().Exec(ctx); err != nil { + log.Printf("Warning: failed to clear episodes: %v", err) + } + if _, err := client.Season.Delete().Exec(ctx); err != nil { + log.Printf("Warning: failed to clear seasons: %v", err) + } + if _, err := client.Series.Delete().Exec(ctx); err != nil { + log.Printf("Warning: failed to clear series: %v", err) + } + log.Println("Data cleared") + + // Run the example + if err := Example(ctx, client); err != nil { + log.Fatal(err) + } +} + +// Example demonstrates CRUD operations with YDB and ent. +func Example(ctx context.Context, client *ent.Client) error { + // Create a new series with retry options + theExpanse, err := client.Series.Create(). + SetTitle("The Expanse"). + SetInfo("Humanity has colonized the solar system - Mars, the Moon, the Asteroid Belt and beyond"). + SetReleaseDate(time.Date(2015, 12, 14, 0, 0, 0, 0, time.UTC)). + WithRetryOptions(retry.WithIdempotent(true)). + Save(ctx) + if err != nil { + return fmt.Errorf("failed creating series: %w", err) + } + log.Printf("Created series: %v", theExpanse) + + // Create seasons for the series + season1, err := client.Season.Create(). + SetTitle("Season 1"). + SetFirstAired(time.Date(2015, 12, 14, 0, 0, 0, 0, time.UTC)). + SetLastAired(time.Date(2016, 2, 2, 0, 0, 0, 0, time.UTC)). + SetSeries(theExpanse). + WithRetryOptions(retry.WithIdempotent(true)). + Save(ctx) + if err != nil { + return fmt.Errorf("failed creating season: %w", err) + } + log.Printf("Created season: %v", season1) + + // Create episodes + ep1, err := client.Episode.Create(). + SetTitle("Dulcinea"). + SetAirDate(time.Date(2015, 12, 14, 0, 0, 0, 0, time.UTC)). + SetSeason(season1). + WithRetryOptions(retry.WithIdempotent(true)). + Save(ctx) + if err != nil { + return fmt.Errorf("failed creating episode: %w", err) + } + log.Printf("Created episode: %v", ep1) + + ep2, err := client.Episode.Create(). + SetTitle("The Big Empty"). + SetAirDate(time.Date(2015, 12, 15, 0, 0, 0, 0, time.UTC)). + SetSeason(season1). + WithRetryOptions(retry.WithIdempotent(true)). + Save(ctx) + if err != nil { + return fmt.Errorf("failed creating episode: %w", err) + } + log.Printf("Created episode: %v", ep2) + + // Query series with retry options + allSeries, err := client.Series.Query(). + WithRetryOptions(retry.WithIdempotent(true)). + All(ctx) + if err != nil { + return fmt.Errorf("failed querying series: %w", err) + } + log.Printf("All series: %v", allSeries) + + // Query with filtering + expSeries, err := client.Series.Query(). + Where(series.TitleContains("Expanse")). + WithRetryOptions(retry.WithIdempotent(true)). + Only(ctx) + if err != nil { + return fmt.Errorf("failed querying series by title: %w", err) + } + log.Printf("Found series: %v", expSeries) + + // Query seasons for a series using edge traversal + seasons, err := expSeries.QuerySeasons(). + WithRetryOptions(retry.WithIdempotent(true)). + All(ctx) + if err != nil { + return fmt.Errorf("failed querying seasons: %w", err) + } + log.Printf("Seasons of %s: %v", expSeries.Title, seasons) + + // Query episodes for a season + episodes, err := client.Episode.Query(). + Where(episode.HasSeasonWith(season.TitleEQ("Season 1"))). + WithRetryOptions(retry.WithIdempotent(true)). + All(ctx) + if err != nil { + return fmt.Errorf("failed querying episodes: %w", err) + } + log.Printf("Episodes in Season 1: %v", episodes) + + // Update series info + _, err = client.Series.Update(). + Where(series.IDEQ(theExpanse.ID)). + SetInfo("Humanity has colonized the solar system - a sci-fi masterpiece based on the novels by James S.A. Corey"). + WithRetryOptions(retry.WithIdempotent(true)). + Save(ctx) + if err != nil { + return fmt.Errorf("failed updating series: %w", err) + } + log.Printf("Updated series info") + + // Delete episode + _, err = client.Episode.Delete(). + Where(episode.TitleEQ("The Big Empty")). + WithRetryOptions(retry.WithIdempotent(true)). + Exec(ctx) + if err != nil { + return fmt.Errorf("failed deleting episode: %w", err) + } + log.Printf("Deleted episode") + + // Verify deletion + remaining, err := client.Episode.Query(). + Where(episode.HasSeasonWith(season.TitleEQ("Season 1"))). + WithRetryOptions(retry.WithIdempotent(true)). + All(ctx) + if err != nil { + return fmt.Errorf("failed querying remaining episodes: %w", err) + } + log.Printf("Remaining episodes: %v", remaining) + + return nil +} diff --git a/go.mod b/go.mod index b66ada2ec7..bedb5df1ba 100644 --- a/go.mod +++ b/go.mod @@ -1,14 +1,12 @@ module entgo.io/ent -go 1.24 - -toolchain go1.24.0 +go 1.24.13 require ( ariga.io/atlas v0.36.2-0.20250730182955-2c6300d0a3e1 github.com/DATA-DOG/go-sqlmock v1.5.0 github.com/go-openapi/inflect v0.19.0 - github.com/google/uuid v1.3.0 + github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.0 github.com/jessevdk/go-flags v1.5.0 github.com/json-iterator/go v1.1.12 @@ -17,10 +15,12 @@ require ( github.com/modern-go/reflect2 v1.0.2 github.com/olekukonko/tablewriter v1.0.8 github.com/spf13/cobra v1.7.0 - github.com/stretchr/testify v1.8.4 + github.com/stretchr/testify v1.11.1 + github.com/ydb-platform/ydb-go-sdk/v3 v3.125.4 go.opencensus.io v0.24.0 - golang.org/x/sync v0.11.0 - golang.org/x/tools v0.30.0 + golang.org/x/sync v0.19.0 + golang.org/x/tools v0.39.0 + golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated ) require ( @@ -29,29 +29,37 @@ require ( github.com/bmatcuk/doublestar v1.3.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/fatih/color v1.15.0 // indirect + github.com/golang-jwt/jwt/v4 v4.5.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/hashicorp/hcl/v2 v2.18.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jonboulle/clockwork v0.5.0 // indirect github.com/kr/pretty v0.3.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-runewidth v0.0.16 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect github.com/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6 // indirect github.com/olekukonko/ll v0.0.8 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/sergi/go-diff v1.3.1 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/stretchr/objx v0.5.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect + github.com/ydb-platform/ydb-go-genproto v0.0.0-20251222105147-0bf751469a4a // indirect github.com/zclconf/go-cty v1.14.4 // indirect github.com/zclconf/go-cty-yaml v1.1.0 // indirect - golang.org/x/mod v0.24.0 // indirect - golang.org/x/sys v0.30.0 // indirect - golang.org/x/text v0.21.0 // indirect - gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect + golang.org/x/mod v0.30.0 // indirect + golang.org/x/net v0.48.0 // indirect + golang.org/x/sys v0.39.0 // indirect + golang.org/x/text v0.32.0 // indirect + golang.org/x/tools/go/expect v0.1.0-deprecated // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect + google.golang.org/grpc v1.78.0 // indirect + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) + +replace ariga.io/atlas => github.com/ydb-platform/ariga-atlas v0.0.1 diff --git a/go.sum b/go.sum index ac2427a565..da8b2d1d85 100644 --- a/go.sum +++ b/go.sum @@ -1,18 +1,24 @@ -ariga.io/atlas v0.36.2-0.20250730182955-2c6300d0a3e1 h1:NPPfBaVZgz4LKBCIc0FbMogCjvXN+yGf7CZwotOwJo8= -ariga.io/atlas v0.36.2-0.20250730182955-2c6300d0a3e1/go.mod h1:Ex5l1xHsnWQUc3wYnrJ9gD7RUEzG76P7ZRQp8wNr0wc= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0= github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -21,13 +27,22 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= +github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -35,33 +50,44 @@ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4er github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/hcl/v2 v2.18.1 h1:6nxnOJFku1EuSawSD81fuviYUV8DxFr3fp2dUi3ZYSo= github.com/hashicorp/hcl/v2 v2.18.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= +github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I= +github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -91,8 +117,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6 h1:r3FaAI0NZK3hSmtTDrBVREhKULp8oUeqLT5Eyl2mSPo= github.com/olekukonko/errors v0.0.0-20250405072817-4e6d85265da6/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y= github.com/olekukonko/ll v0.0.8 h1:sbGZ1Fx4QxJXEqL/6IG8GEFnYojUSQ45dJVwN2FH2fc= @@ -102,8 +126,11 @@ github.com/olekukonko/tablewriter v1.0.8/go.mod h1:H428M+HzoUXC6JU2Abj9IT9ooRmdq github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rekby/fixenv v0.6.1 h1:jUFiSPpajT4WY2cYuc++7Y1zWrnCxnovGCIX72PZniM= +github.com/rekby/fixenv v0.6.1/go.mod h1:/b5LRc06BYJtslRtHKxsPWFT/ySpHV+rWvzTg+XWk4c= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -115,72 +142,120 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/ydb-platform/ariga-atlas v0.0.1 h1:atWj2dpOKWIZ6sR0NVQrZDIJ40k85gkZ/7D7opqlCW0= +github.com/ydb-platform/ariga-atlas v0.0.1/go.mod h1:t5BRX5MhK+I0vLdUMeUBOz1x2uNP/FYejPLUBcsCWcw= +github.com/ydb-platform/ydb-go-genproto v0.0.0-20251222105147-0bf751469a4a h1:nRqONRrMFulP2bTWM2RRnPM1VDhWuBZg4ULXkG4xXdk= +github.com/ydb-platform/ydb-go-genproto v0.0.0-20251222105147-0bf751469a4a/go.mod h1:Er+FePu1dNUieD+XTMDduGpQuCPssK5Q4BjF+IIXJ3I= +github.com/ydb-platform/ydb-go-sdk/v3 v3.125.4 h1:GAC7qeNgsibEJkUVzV4z06aBnHR4jqfXsFiQtrY40gI= +github.com/ydb-platform/ydb-go-sdk/v3 v3.125.4/go.mod h1:stS1mQYjbJvwwYaYzKyFY9eMiuVXWWXQA6T+SpOLg9c= github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= github.com/zclconf/go-cty-yaml v1.1.0 h1:nP+jp0qPHv2IhUVqmQSzjvqAWcObN0KBkUl2rWBdig0= github.com/zclconf/go-cty-yaml v1.1.0/go.mod h1:9YLUH4g7lOhVWqUbctnVlZ5KLpg7JAprQNgxSZ1Gyxs= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= +go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= -golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/mod v0.30.0 h1:fDEXFVZ/fmCKProc/yAXXUijritrDzahmwwefnjoPFk= +golang.org/x/mod v0.30.0/go.mod h1:lAsf5O2EvJeSFMiBxXDki7sCgAxEUcZHXoXMKT4GJKc= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= +golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= +golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= +golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY= -golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= +golang.org/x/tools v0.39.0 h1:ik4ho21kwuQln40uelmciQPp9SipgNDdrafrYA4TmQQ= +golang.org/x/tools v0.39.0/go.mod h1:JnefbkDPyD8UU2kI5fuf8ZX4/yUeh9W877ZeBONxUqQ= +golang.org/x/tools/go/expect v0.1.0-deprecated h1:jY2C5HGYR5lqex3gEniOQL0r7Dq5+VGVgY1nudX5lXY= +golang.org/x/tools/go/expect v0.1.0-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY= +golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated h1:1h2MnaIAIXISqTFKdENegdpAgUXz6NrPEsbIeWaBRvM= +golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= +google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -190,13 +265,20 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=