From c7de6ed0af343a797516042530ede25c3747f68d Mon Sep 17 00:00:00 2001
From: Egor Danilov <63148392+LostImagin4tion@users.noreply.github.com>
Date: Tue, 11 Nov 2025 18:32:43 +0300
Subject: [PATCH 01/14] Implemented basic ent driver for YDB (#2)
---
dialect/dialect.go | 1 +
dialect/ydb/driver.go | 48 ++++++
dialect/ydb/driver_test.go | 297 +++++++++++++++++++++++++++++++++++++
entc/integration/go.mod | 18 +--
entc/integration/go.sum | 36 ++---
examples/go.mod | 25 ++--
examples/go.sum | 64 +++++---
go.mod | 34 +++--
go.sum | 124 +++++++++++++---
9 files changed, 549 insertions(+), 98 deletions(-)
create mode 100644 dialect/ydb/driver.go
create mode 100644 dialect/ydb/driver_test.go
diff --git a/dialect/dialect.go b/dialect/dialect.go
index 3378463480..79bceeb405 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.
diff --git a/dialect/ydb/driver.go b/dialect/ydb/driver.go
new file mode 100644
index 0000000000..f0845647c1
--- /dev/null
+++ b/dialect/ydb/driver.go
@@ -0,0 +1,48 @@
+// 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 ydb
+
+import (
+ "context"
+ "database/sql"
+
+ "entgo.io/ent/dialect"
+ entSql "entgo.io/ent/dialect/sql"
+ ydb "github.com/ydb-platform/ydb-go-sdk/v3"
+)
+
+// YDBDriver is a [dialect.Driver] implementation for YDB.
+type YDBDriver struct {
+ *entSql.Driver
+
+ nativeDriver *ydb.Driver
+}
+
+func Open(ctx context.Context, dsn string) (*YDBDriver, error) {
+ nativeDriver, err := ydb.Open(ctx, dsn)
+ if err != nil {
+ return nil, err
+ }
+
+ conn, err := ydb.Connector(
+ nativeDriver,
+ ydb.WithAutoDeclare(),
+ ydb.WithTablePathPrefix(nativeDriver.Name()),
+ )
+ if err != nil {
+ panic(err)
+ }
+
+ dbSQLDriver := sql.OpenDB(conn)
+
+ return &YDBDriver{
+ Driver: entSql.OpenDB(dialect.YDB, dbSQLDriver),
+ nativeDriver: nativeDriver,
+ }, nil
+}
+
+func (y *YDBDriver) NativeDriver() *ydb.Driver {
+ return y.nativeDriver
+}
diff --git a/dialect/ydb/driver_test.go b/dialect/ydb/driver_test.go
new file mode 100644
index 0000000000..a012925593
--- /dev/null
+++ b/dialect/ydb/driver_test.go
@@ -0,0 +1,297 @@
+// 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 ydb
+
+import (
+ "context"
+ "fmt"
+ "testing"
+
+ "entgo.io/ent/dialect"
+ entSql "entgo.io/ent/dialect/sql"
+
+ "github.com/DATA-DOG/go-sqlmock"
+ "github.com/stretchr/testify/require"
+)
+
+func TestOpenAndClose(t *testing.T) {
+ // Given
+ db, mock, err := sqlmock.New()
+ require.NoError(t, err)
+ defer db.Close()
+
+ driver := &YDBDriver{
+ Driver: entSql.OpenDB(dialect.YDB, db),
+ }
+
+ // When
+ mock.ExpectClose()
+ err = driver.Close()
+
+ // Then - verify closed
+ require.NoError(t, err, "should close connection")
+ require.NoError(t, mock.ExpectationsWereMet())
+}
+
+func TestExecCreateTable(t *testing.T) {
+ // Given
+ db, mock, err := sqlmock.New()
+ require.NoError(t, err)
+ defer db.Close()
+
+ ctx := context.Background()
+ driver := &YDBDriver{Driver: entSql.OpenDB(dialect.YDB, db)}
+
+ // When
+ mock.ExpectExec("DROP TABLE IF EXISTS test_users").
+ WillReturnResult(sqlmock.NewResult(0, 0))
+
+ mock.ExpectExec("CREATE TABLE test_users").
+ WillReturnResult(sqlmock.NewResult(0, 0))
+
+ _ = driver.Exec(ctx, "DROP TABLE IF EXISTS test_users", []any{}, nil)
+ err = driver.Exec(ctx, `CREATE TABLE test_users (
+ id Int64 NOT NULL,
+ name Utf8,
+ age Int32,
+ PRIMARY KEY (id)
+ )`, []any{}, nil)
+ require.NoError(t, err, "CREATE TABLE should execute without err")
+
+ // Then - verify table created
+ mock.ExpectQuery("SELECT 1 FROM test_users").
+ WillReturnRows(sqlmock.NewRows([]string{"1"}))
+
+ var rows entSql.Rows
+ err = driver.Query(ctx, "SELECT 1 FROM test_users", []any{}, &rows)
+ require.NoError(t, err, "created table should exist")
+ rows.Close()
+
+ require.NoError(t, mock.ExpectationsWereMet())
+}
+
+func TestExecInsert(t *testing.T) {
+ // Given
+ db, mock, err := sqlmock.New()
+ require.NoError(t, err)
+ defer db.Close()
+
+ ctx := context.Background()
+ driver := &YDBDriver{Driver: entSql.OpenDB(dialect.YDB, db)}
+
+ // When
+ mock.ExpectExec("INSERT INTO test_users").
+ WillReturnResult(sqlmock.NewResult(1, 1))
+
+ insertQuery := `INSERT INTO test_users (id, name, age) VALUES (1, 'Alice', 30)`
+ err = driver.Exec(ctx, insertQuery, []any{}, nil)
+ require.NoError(t, err, "INSERT data execute without err")
+
+ // Then - verify row count
+ mock.ExpectQuery("SELECT COUNT\\(\\*\\) AS").
+ WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(1))
+
+ var rows entSql.Rows
+ err = driver.Query(ctx, "SELECT COUNT(*) AS `count` FROM test_users", []any{}, &rows)
+ require.NoError(t, err, "SELECT COUNT(*) should execute without err")
+
+ require.True(t, rows.Next(), "Result should have at least 1 row")
+ var count uint64
+ err = rows.Scan(&count)
+ require.NoError(t, err)
+ require.Equal(t, uint64(1), count, "Table should contain exactly 1 row")
+ rows.Close()
+
+ require.NoError(t, mock.ExpectationsWereMet())
+}
+
+func TestExecUpdate(t *testing.T) {
+ // Given
+ db, mock, err := sqlmock.New()
+ require.NoError(t, err)
+ defer db.Close()
+
+ ctx := context.Background()
+ drv := &YDBDriver{Driver: entSql.OpenDB(dialect.YDB, db)}
+
+ mock.ExpectExec("INSERT INTO test_users").
+ WillReturnResult(sqlmock.NewResult(1, 1))
+
+ insertDataQuery := "INSERT INTO test_users (id, name, age) VALUES (1, 'Alice', 30)"
+ require.NoError(t, drv.Exec(ctx, insertDataQuery, []any{}, nil))
+
+ // When
+ mock.ExpectExec("UPDATE test_users SET age = 31 WHERE id = 1").
+ WillReturnResult(sqlmock.NewResult(0, 1))
+
+ updateQuery := `UPDATE test_users SET age = 31 WHERE id = 1`
+ err = drv.Exec(ctx, updateQuery, []any{}, nil)
+ require.NoError(t, err, "should update data")
+
+ // Then
+ mock.ExpectQuery("SELECT \\* FROM test_users").
+ WillReturnRows(sqlmock.NewRows([]string{"id", "name", "age"}).
+ AddRow(1, "Alice", 31))
+
+ var rows entSql.Rows
+ err = drv.Query(ctx, "SELECT * FROM test_users", []any{}, &rows)
+ require.NoError(t, err)
+
+ require.True(t, rows.Next())
+ var id, age int64
+ var name string
+ err = rows.Scan(&id, &name, &age)
+ require.NoError(t, err)
+ require.Equal(t, int64(31), age, "Age should've been changed")
+ rows.Close()
+
+ require.NoError(t, mock.ExpectationsWereMet())
+}
+
+func TestExecDelete(t *testing.T) {
+ // Given
+ db, mock, err := sqlmock.New()
+ require.NoError(t, err)
+ defer db.Close()
+
+ ctx := context.Background()
+ drv := &YDBDriver{Driver: entSql.OpenDB(dialect.YDB, db)}
+
+ mock.ExpectExec("INSERT INTO test_users").
+ WillReturnResult(sqlmock.NewResult(1, 1))
+
+ insertDataQuery := "INSERT INTO test_users (id, name, age) VALUES (1, 'Alice', 30)"
+ require.NoError(t, drv.Exec(ctx, insertDataQuery, []any{}, nil))
+
+ // When
+ mock.ExpectExec("DELETE FROM test_users WHERE id = 1").
+ WillReturnResult(sqlmock.NewResult(0, 1))
+
+ deleteQuery := `DELETE FROM test_users WHERE id = 1`
+ err = drv.Exec(ctx, deleteQuery, []any{}, nil)
+ require.NoError(t, err, "DELETE request should execute without err")
+
+ // Then
+ mock.ExpectQuery("SELECT COUNT\\(\\*\\)").
+ WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(0))
+
+ var rows entSql.Rows
+ err = drv.Query(ctx, "SELECT COUNT(*) AS `count` FROM test_users", []any{}, &rows)
+ require.NoError(t, err)
+ require.True(t, rows.Next())
+ var count uint64
+ err = rows.Scan(&count)
+ require.NoError(t, err)
+ require.Equal(t, uint64(0), count, "Table should be empty after DELETE")
+ rows.Close()
+
+ require.NoError(t, mock.ExpectationsWereMet())
+}
+
+func TestQueryEmptyTable(t *testing.T) {
+ // Given
+ db, mock, err := sqlmock.New()
+ require.NoError(t, err)
+ defer db.Close()
+
+ ctx := context.Background()
+ drv := &YDBDriver{Driver: entSql.OpenDB(dialect.YDB, db)}
+
+ // When
+ mock.ExpectQuery("SELECT \\* FROM test_users").
+ WillReturnRows(sqlmock.NewRows([]string{"id", "name", "age"}))
+
+ var rows entSql.Rows
+ err = drv.Query(ctx, "SELECT * FROM test_users", []any{}, &rows)
+
+ // Then
+ require.NoError(t, err, "SELECT data should execute without err")
+
+ counter := 0
+ for rows.Next() {
+ counter++
+ }
+ require.Equal(t, 0, counter, "Table should be empty")
+ rows.Close()
+
+ require.NoError(t, mock.ExpectationsWereMet())
+}
+
+func TestExecMultipleInserts(t *testing.T) {
+ // Given
+ db, mock, err := sqlmock.New()
+ require.NoError(t, err)
+ defer db.Close()
+
+ ctx := context.Background()
+ drv := &YDBDriver{Driver: entSql.OpenDB(dialect.YDB, db)}
+
+ // When
+ for i := 0; i < 10; i++ {
+ insertQuery := fmt.Sprintf("INSERT INTO test_users (id, name, age) VALUES (%d, 'User%d', 20)", i, i)
+ mock.ExpectExec("INSERT INTO test_users").
+ WillReturnResult(sqlmock.NewResult(int64(i), 1))
+
+ err := drv.Exec(ctx, insertQuery, []any{}, nil)
+ require.NoError(t, err)
+ }
+
+ // Then
+ mock.ExpectQuery("SELECT COUNT\\(\\*\\)").
+ WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(10))
+
+ var rows entSql.Rows
+ err = drv.Query(ctx, "SELECT COUNT(*) AS `count` FROM test_users", []any{}, &rows)
+ require.NoError(t, err)
+ require.True(t, rows.Next())
+ var count uint64
+ err = rows.Scan(&count)
+ require.NoError(t, err)
+ require.Equal(t, uint64(10), count, "Table should contain exactly 10 rows")
+ rows.Close()
+
+ require.NoError(t, mock.ExpectationsWereMet())
+}
+
+func TestQueryInvalidQuery(t *testing.T) {
+ // Given
+ db, mock, err := sqlmock.New()
+ require.NoError(t, err)
+ defer db.Close()
+
+ ctx := context.Background()
+ drv := &YDBDriver{Driver: entSql.OpenDB(dialect.YDB, db)}
+
+ // When
+ invalidQuery := "SELECT * FROM non_existent_table"
+ mock.ExpectQuery("SELECT \\* FROM non_existent_table").
+ WillReturnError(fmt.Errorf("table not found"))
+
+ var rows entSql.Rows
+ err = drv.Query(ctx, invalidQuery, []any{}, &rows)
+
+ // Then
+ require.Error(t, err, "should return error for invalid query")
+ require.NoError(t, mock.ExpectationsWereMet())
+}
+
+func TestContextCancellation(t *testing.T) {
+ // Given
+ db, _, err := sqlmock.New()
+ require.NoError(t, err)
+ defer db.Close()
+
+ ctx := context.Background()
+ drv := &YDBDriver{Driver: entSql.OpenDB(dialect.YDB, db)}
+
+ // When
+ cancelCtx, cancel := context.WithCancel(ctx)
+ cancel()
+
+ // Then
+ err = drv.Exec(cancelCtx, "SELECT 1", []any{}, nil)
+ require.Error(t, err, "should return error when context is cancelled")
+ require.Contains(t, err.Error(), "context canceled")
+}
diff --git a/entc/integration/go.mod b/entc/integration/go.mod
index e631fae3f5..9167aee375 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.0
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.10.0
+ golang.org/x/sync v0.17.0
)
require (
@@ -24,7 +22,7 @@ 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/google/go-cmp v0.7.0 // indirect
github.com/hashicorp/hcl/v2 v2.18.1 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
@@ -33,10 +31,10 @@ 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/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.28.0 // indirect
+ golang.org/x/text v0.30.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/entc/integration/go.sum b/entc/integration/go.sum
index f9069a0a13..878cf011ac 100644
--- a/entc/integration/go.sum
+++ b/entc/integration/go.sum
@@ -19,11 +19,11 @@ github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ
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/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.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
+github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
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=
@@ -58,29 +58,25 @@ github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUz
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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
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=
+golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
+golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
+golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
+golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
+golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
+golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
+golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
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/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=
diff --git a/examples/go.mod b/examples/go.mod
index 345c216eaa..15f275af12 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.0
replace entgo.io/ent => ../
@@ -10,10 +8,10 @@ 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.10.0
gocloud.dev v0.28.0
)
@@ -24,8 +22,7 @@ require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-openapi/inflect v0.19.0 // 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/mitchellh/go-wordwrap v1.0.1 // indirect
@@ -33,15 +30,15 @@ require (
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.43.0 // indirect
+ golang.org/x/mod v0.28.0 // indirect
+ golang.org/x/net v0.46.0 // indirect
+ golang.org/x/sys v0.37.0 // indirect
+ golang.org/x/text v0.30.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.76.0 // indirect
+ google.golang.org/protobuf v1.36.10 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/examples/go.sum b/examples/go.sum
index 87bdf12f86..c164037661 100644
--- a/examples/go.sum
+++ b/examples/go.sum
@@ -124,8 +124,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.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU=
+cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=
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 +852,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=
@@ -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=
@@ -1642,8 +1648,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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
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=
@@ -1732,6 +1738,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.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
+go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
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 +1751,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.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
+go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
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 +1769,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.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
+go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
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.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
+go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
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.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
+go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
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.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
+go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
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=
@@ -1838,8 +1856,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.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
+golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
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 +1900,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.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
+golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
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 +1985,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.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
+golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
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 +2015,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.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
+golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
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 +2034,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.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
+golang.org/x/sync v0.17.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 +2186,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.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
+golang.org/x/sys v0.37.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 +2208,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.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
+golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
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 +2318,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 +2554,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.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A=
+google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c=
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 +2572,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.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
+google.golang.org/protobuf v1.36.10/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/go.mod b/go.mod
index b66ada2ec7..5b224366a8 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.0
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.10.0
+ github.com/ydb-platform/ydb-go-sdk/v3 v3.118.0
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.17.0
+ golang.org/x/tools v0.37.0
+ golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated
)
require (
@@ -29,29 +29,35 @@ 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-20250911135631-b3beddd517d9 // 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.28.0 // indirect
+ golang.org/x/net v0.46.0 // indirect
+ golang.org/x/sys v0.37.0 // indirect
+ golang.org/x/text v0.30.0 // indirect
+ golang.org/x/tools/go/expect v0.1.0-deprecated // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda // indirect
+ google.golang.org/grpc v1.76.0 // indirect
+ google.golang.org/protobuf v1.36.10 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/go.sum b/go.sum
index ac2427a565..bfaf07d6dc 100644
--- a/go.sum
+++ b/go.sum
@@ -1,18 +1,26 @@
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 +29,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 +52,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 +119,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 +128,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 +144,118 @@ 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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/ydb-platform/ydb-go-genproto v0.0.0-20250911135631-b3beddd517d9 h1:SKqSRP6/ocY2Z4twOqKEKxpmawVTHTvQiom7hrU6jt0=
+github.com/ydb-platform/ydb-go-genproto v0.0.0-20250911135631-b3beddd517d9/go.mod h1:Er+FePu1dNUieD+XTMDduGpQuCPssK5Q4BjF+IIXJ3I=
+github.com/ydb-platform/ydb-go-sdk/v3 v3.118.0 h1:wLnWJ29yzYdVds3WFRgkzij/2li9dknyRBO7B+reJfY=
+github.com/ydb-platform/ydb-go-sdk/v3 v3.118.0/go.mod h1:UEMMk+JMunUveo2j+zlJEJ5I7ntf2+MbimciVNJYnNs=
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.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
+go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
+go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
+go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
+go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
+go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
+go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
+go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
+go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
+go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
+go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
+go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
+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.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
+golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
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.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
+golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
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.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
+golang.org/x/sync v0.17.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.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
+golang.org/x/sys v0.37.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.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
+golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
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.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
+golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
+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-20251029180050-ab9386a59fda h1:i/Q+bfisr7gq6feoJnS/DlpdwEL4ihp41fvRiM3Ork0=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
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.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A=
+google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c=
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.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
+google.golang.org/protobuf v1.36.10/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=
From db0e2b0339a5980ff7e575ef3cd84ccf2ebcbd05 Mon Sep 17 00:00:00 2001
From: Egor Danilov <63148392+LostImagin4tion@users.noreply.github.com>
Date: Mon, 24 Nov 2025 13:07:16 +0300
Subject: [PATCH 02/14] dialect/sql: added support for basic YQL CRUD queries
(#4)
* dialect/sql: implemented delete queries for yql
* dialect/sql: implemented insert queries for yql
* dialect/sql: implemented update queries for yql
* dialect/sql: added support for yql joins
* dialect/sql: added support for some yql select clauses
* dialect/sql: improved tests
* dialect/sql: added support for replace clause
* dialect/sql: fixed linter error
---
dialect/sql/builder.go | 350 ++++++++++++++++---
dialect/sql/builder_test.go | 676 ++++++++++++++++++++++++++++++++++++
2 files changed, 980 insertions(+), 46 deletions(-)
diff --git a/dialect/sql/builder.go b/dialect/sql/builder.go
index 576ba19470..a59b415719 100644
--- a/dialect/sql/builder.go
+++ b/dialect/sql/builder.go
@@ -146,6 +146,10 @@ type InsertBuilder struct {
returning []string
values [][]any
conflict *conflict
+
+ // YDB-specific:
+ isUpsert bool // use UPSERT instead of INSERT
+ isReplace bool // use REPLACE instead of INSERT
}
// Insert creates a builder for the `INSERT INTO` statement.
@@ -158,6 +162,36 @@ 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}
+}
+
+// Replace creates a builder for the `REPLACE INTO` statement.
+// REPLACE overwrites entire rows based on primary key comparison.
+// For existing rows, the entire row is replaced (unspecified columns get default values).
+// For missing rows, new rows are inserted.
+//
+// Replace("users").
+// Columns("id", "name", "age").
+// Values(1, "a8m", 10).
+// Values(2, "foo", 20)
+//
+// Note: REPLACE is only supported in YDB dialect.
+func Replace(table string) *InsertBuilder {
+ return &InsertBuilder{table: table, isReplace: true}
+}
+
// Schema sets the database name for the insert table.
func (i *InsertBuilder) Schema(name string) *InsertBuilder {
i.schema = name
@@ -438,11 +472,28 @@ 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 ")
+
+ switch {
+ case i.isUpsert:
+ if !b.ydb() {
+ b.AddError(fmt.Errorf("UPSERT INTO: unsupported dialect: %q", b.dialect))
+ return "", nil, b.Err()
+ }
+ b.WriteString("UPSERT INTO ")
+ case i.isReplace:
+ if !b.ydb() {
+ b.AddError(fmt.Errorf("REPLACE INTO: unsupported dialect: %q", b.dialect))
+ return "", nil, b.Err()
+ }
+ b.WriteString("REPLACE INTO ")
+ default:
+ b.WriteString("INSERT INTO ")
+ }
+
b.writeSchema(i.schema)
b.Ident(i.table).Pad()
if i.defaults && len(i.columns) == 0 {
@@ -529,6 +580,7 @@ type UpdateBuilder struct {
order []any
limit *int
prefix Queries
+ onSelect *Selector // YDB-specific: UPDATE ON subquery
}
// Update creates a builder for the `UPDATE` statement.
@@ -638,6 +690,25 @@ func (u *UpdateBuilder) Returning(columns ...string) *UpdateBuilder {
return u
}
+// On sets a subquery for the UPDATE ON statement (YDB-specific).
+// The subquery must return columns that include all primary key columns.
+// For each row in the subquery result, the corresponding row in the table is updated.
+//
+// Update("users").
+// On(
+// Select("key", "name")
+// .From(Table("temp_updates"))
+// .Where(EQ("status", "pending"))
+// )
+func (u *UpdateBuilder) On(s *Selector) *UpdateBuilder {
+ if u.ydb() {
+ u.onSelect = s
+ } else {
+ u.AddError(fmt.Errorf("UPDATE ON: unsupported dialect: %q", u.dialect))
+ }
+ return u
+}
+
// Query returns query representation of an `UPDATE` statement.
func (u *UpdateBuilder) Query() (string, []any) {
b := u.Builder.clone()
@@ -647,7 +718,18 @@ func (u *UpdateBuilder) Query() (string, []any) {
}
b.WriteString("UPDATE ")
b.writeSchema(u.schema)
- b.Ident(u.table).WriteString(" SET ")
+ b.Ident(u.table)
+
+ // UPDATE ON pattern (YDB-specific)
+ if u.onSelect != nil {
+ b.WriteString(" ON ")
+ b.Join(u.onSelect)
+ joinReturning(u.returning, &b)
+ return b.String(), b.args
+ }
+
+ // Standard UPDATE SET pattern
+ b.WriteString(" SET ")
u.writeSetter(&b)
if u.where != nil {
b.WriteString(" WHERE ")
@@ -693,6 +775,10 @@ type DeleteBuilder struct {
table string
schema string
where *Predicate
+
+ // For YDB's DELETE FROM ... ON SELECT pattern
+ onSelect *Selector
+ returning []string
}
// Delete creates a builder for the `DELETE` statement.
@@ -735,16 +821,50 @@ func (d *DeleteBuilder) FromSelect(s *Selector) *DeleteBuilder {
return d
}
+// On sets the subquery for DELETE FROM ... ON SELECT pattern (YDB-specific).
+// This allows deleting rows based on a subquery that returns primary key columns.
+//
+// Delete("users").
+// On(Select("id").From(Table("users")).Where(EQ("status", "inactive")))
+func (d *DeleteBuilder) On(s *Selector) *DeleteBuilder {
+ if d.ydb() {
+ d.onSelect = s
+ } else {
+ d.AddError(fmt.Errorf("DELETE ON: unsupported dialect: %q", d.dialect))
+ }
+ 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: unsupported dialect: %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)
- if d.where != nil {
- d.WriteString(" WHERE ")
- d.Join(d.where)
+ b := d.Builder.clone()
+ b.WriteString("DELETE FROM ")
+ b.writeSchema(d.schema)
+ b.Ident(d.table)
+
+ // YDB-specific DELETE ON SELECT pattern
+ if d.onSelect != nil {
+ d.onSelect.SetDialect(b.dialect)
+ b.WriteString(" ON ")
+ b.Join(d.onSelect)
+ } else if d.where != nil {
+ b.WriteString(" WHERE ")
+ b.Join(d.where)
}
- return d.String(), d.args
+
+ joinReturning(d.returning, &b)
+ return b.String(), b.args
}
// Predicate is a where predicate.
@@ -1583,6 +1703,7 @@ type SelectTable struct {
name string
schema string
quote bool
+ index string // YDB-specific: secondary index name for VIEW clause
}
// Table returns a new table selector.
@@ -1605,6 +1726,20 @@ func (s *SelectTable) As(alias string) *SelectTable {
return s
}
+// View sets the secondary index name for the VIEW clause (YDB-specific).
+// This allows explicit use of secondary indexes in SELECT and JOIN operations.
+//
+// t := Table("users").View("idx_email").As("u")
+// Select().From(Table("orders")).Join(t).On(...)
+func (s *SelectTable) View(index string) *SelectTable {
+ if s.ydb() {
+ s.index = index
+ } else {
+ s.AddError(fmt.Errorf("VIEW: unsupported dialect: %q", s.dialect))
+ }
+ return s
+}
+
// C returns a formatted string for the table column.
func (s *SelectTable) C(column string) string {
name := s.name
@@ -1644,6 +1779,13 @@ func (s *SelectTable) ref() string {
b := &Builder{dialect: s.dialect}
b.writeSchema(s.schema)
b.Ident(s.name)
+
+ // YDB-specific: VIEW clause for secondary indexes
+ if s.index != "" {
+ b.WriteString(" VIEW ")
+ b.Ident(s.index)
+ }
+
if s.as != "" {
b.WriteString(" AS ")
b.Ident(s.as)
@@ -1675,24 +1817,25 @@ type Selector struct {
Builder
// ctx stores contextual data typically from
// generated code such as alternate table schemas.
- ctx context.Context
- as string
- selection []selection
- from []TableView
- joins []join
- collected [][]*Predicate
- where *Predicate
- or bool
- not bool
- order []any
- group []string
- having *Predicate
- limit *int
- offset *int
- distinct bool
- setOps []setOp
- prefix Queries
- lock *LockOptions
+ ctx context.Context
+ as string
+ selection []selection
+ from []TableView
+ joins []join
+ collected [][]*Predicate
+ where *Predicate
+ or bool
+ not bool
+ order []any
+ assumeOrder []string // YDB-specific: ASSUME ORDER BY columns
+ group []string
+ having *Predicate
+ limit *int
+ offset *int
+ distinct bool
+ setOps []setOp
+ prefix Queries
+ lock *LockOptions
}
// New returns a new Selector with the same dialect and context.
@@ -2107,6 +2250,36 @@ func (s *Selector) FullJoin(t TableView) *Selector {
return s.join("FULL JOIN", t)
}
+// LeftSemiJoin appends a `LEFT SEMI JOIN` clause to the statement (YDB-specific).
+func (s *Selector) LeftSemiJoin(t TableView) *Selector {
+ return s.join("LEFT SEMI JOIN", t)
+}
+
+// RightSemiJoin appends a `RIGHT SEMI JOIN` clause to the statement (YDB-specific).
+func (s *Selector) RightSemiJoin(t TableView) *Selector {
+ return s.join("RIGHT SEMI JOIN", t)
+}
+
+// LeftOnlyJoin appends a `LEFT ONLY JOIN` clause to the statement (YDB-specific).
+func (s *Selector) LeftOnlyJoin(t TableView) *Selector {
+ return s.join("LEFT ONLY JOIN", t)
+}
+
+// RightOnlyJoin appends a `RIGHT ONLY JOIN` clause to the statement (YDB-specific).
+func (s *Selector) RightOnlyJoin(t TableView) *Selector {
+ return s.join("RIGHT ONLY JOIN", t)
+}
+
+// CrossJoin appends a `CROSS JOIN` clause to the statement.
+func (s *Selector) CrossJoin(t TableView) *Selector {
+ return s.join("CROSS JOIN", t)
+}
+
+// ExclusionJoin appends an `EXCLUSION JOIN` clause to the statement (YDB-specific).
+func (s *Selector) ExclusionJoin(t TableView) *Selector {
+ return s.join("EXCLUSION 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{
@@ -2396,21 +2569,22 @@ func (s *Selector) Clone() *Selector {
joins[i] = s.joins[i].clone()
}
return &Selector{
- Builder: s.Builder.clone(),
- ctx: s.ctx,
- as: s.as,
- or: s.or,
- not: s.not,
- from: s.from,
- limit: s.limit,
- offset: s.offset,
- distinct: s.distinct,
- where: s.where.clone(),
- having: s.having.clone(),
- joins: append([]join{}, joins...),
- group: append([]string{}, s.group...),
- order: append([]any{}, s.order...),
- selection: append([]selection{}, s.selection...),
+ Builder: s.Builder.clone(),
+ ctx: s.ctx,
+ as: s.as,
+ or: s.or,
+ not: s.not,
+ from: s.from,
+ limit: s.limit,
+ offset: s.offset,
+ distinct: s.distinct,
+ where: s.where.clone(),
+ having: s.having.clone(),
+ joins: append([]join{}, joins...),
+ group: append([]string{}, s.group...),
+ order: append([]any{}, s.order...),
+ assumeOrder: append([]string{}, s.assumeOrder...),
+ selection: append([]selection{}, s.selection...),
}
}
@@ -2438,6 +2612,11 @@ func DescExpr(x Querier) Querier {
// OrderBy appends the `ORDER BY` clause to the `SELECT` statement.
func (s *Selector) OrderBy(columns ...string) *Selector {
+ if s.ydb() && len(s.assumeOrder) != 0 {
+ s.AddError(fmt.Errorf("ORDER BY: can't be used with ASSUME ORDER BY simultaneously"))
+ return s
+ }
+
for i := range columns {
s.order = append(s.order, columns[i])
}
@@ -2479,6 +2658,27 @@ func (s *Selector) ClearOrder() *Selector {
return s
}
+// AssumeOrderBy appends the `ASSUME ORDER BY` clause to the `SELECT` statement (YDB-specific).
+// This tells YDB to assume the data is already sorted without actually sorting it.
+// This is an optimization hint and only works with column names (not expressions).
+//
+// Select("*").
+// From(Table("users")).
+// AssumeOrderBy("first-key", Desc("second-key"))
+func (s *Selector) AssumeOrderBy(columns ...string) *Selector {
+ if s.ydb() {
+ if len(s.order) != 0 {
+ s.AddError(fmt.Errorf("ASSUME ORDER BY: can't be used with ORDER BY simultaneously"))
+ return s
+ }
+
+ s.assumeOrder = append(s.assumeOrder, columns...)
+ } else {
+ s.AddError(fmt.Errorf("ASSUME ORDER BY: unsupported dialect: %q", s.dialect))
+ }
+ return s
+}
+
// GroupBy appends the `GROUP BY` clause to the `SELECT` statement.
func (s *Selector) GroupBy(columns ...string) *Selector {
s.group = append(s.group, columns...)
@@ -2569,6 +2769,7 @@ func (s *Selector) Query() (string, []any) {
s.joinSetOps(&b)
}
joinOrder(s.order, &b)
+ s.joinAssumeOrder(&b)
if s.limit != nil {
b.WriteString(" LIMIT ")
b.WriteString(strconv.Itoa(*s.limit))
@@ -2647,8 +2848,22 @@ func joinOrder(order []any, b *Builder) {
}
}
+func (s *Selector) joinAssumeOrder(b *Builder) {
+ if !b.ydb() || len(s.assumeOrder) == 0 {
+ return
+ }
+ b.WriteString(" ASSUME ORDER BY ")
+ for i := range s.assumeOrder {
+ if i > 0 {
+ b.Comma()
+ }
+ b.Ident(s.assumeOrder[i])
+ }
+}
+
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 ")
@@ -3177,6 +3392,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{
@@ -3215,7 +3433,16 @@ func (b *Builder) Argf(format string, a any) *Builder {
return b
}
b.total++
- b.args = append(b.args, a)
+
+ // YDB requires named parameters
+ if b.ydb() {
+ // Extract parameter name from format (e.g., "$p0" -> "p0")
+ paramName := strings.TrimPrefix(format, "$")
+ b.args = append(b.args, driver.NamedValue{Name: paramName, Value: a})
+ } else {
+ b.args = append(b.args, a)
+ }
+
b.WriteString(format)
return b
}
@@ -3331,6 +3558,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, `"`) {
@@ -3437,6 +3669,32 @@ 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
+}
+
+// Replace creates an InsertBuilder for the REPLACE statement with the configured dialect.
+// REPLACE is only supported in YDB dialect.
+//
+// Dialect(dialect.YDB).
+// Replace("users").
+// Columns("id", "name", "age").
+// Values(1, "a8m", 10)
+func (d *DialectBuilder) Replace(table string) *InsertBuilder {
+ b := Replace(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..91f42e5677 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`, `g`.`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(*) 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(*) 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,465 @@ 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: func() Querier {
+ d := Dialect(dialect.YDB)
+ subquery := d.Select("id", "email").
+ From(Table("users")).
+ Where(EQ("status", "ToDelete"))
+ return d.Delete("users").On(subquery)
+ }(),
+ wantQuery: "DELETE FROM `users` ON SELECT `id`, `email` FROM `users` WHERE `status` = $p0",
+ wantArgs: []any{driver.NamedValue{Name: "p0", Value: "ToDelete"}},
+ },
+ {
+ input: func() Querier {
+ d := Dialect(dialect.YDB)
+ subquery := d.Select("*").
+ From(Table("temp_delete_list"))
+ return d.Delete("users").On(subquery)
+ }(),
+ wantQuery: "DELETE FROM `users` ON SELECT * FROM `temp_delete_list`",
+ },
+ {
+ 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: func() Querier {
+ d := Dialect(dialect.YDB)
+ subquery := d.Select("id").
+ From(Table("temp_ids"))
+ return d.Delete("users").
+ On(subquery).
+ Returning("id", "name")
+ }(),
+ wantQuery: "DELETE FROM `users` ON SELECT `id` FROM `temp_ids` RETURNING `id`, `name`",
+ },
+ {
+ 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).
+ Replace("users").
+ Columns("id", "name", "age").
+ Values(1, "a8m", 10),
+ wantQuery: "REPLACE 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).
+ Replace("users").
+ Columns("id", "name", "age").
+ Values(1, "a8m", 10).
+ Values(2, "foo", 20),
+ wantQuery: "REPLACE 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).
+ Replace("orders").
+ Columns("order_id", "status", "amount").
+ Values(1001, "shipped", 500).
+ Returning("*"),
+ wantQuery: "REPLACE 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).
+ 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 {
+ d := Dialect(dialect.YDB)
+ subquery := d.Select("key", "value").
+ From(Table("temp_updates")).
+ Where(EQ("status", "pending"))
+ return d.Update("users").On(subquery)
+ }(),
+ wantQuery: "UPDATE `users` ON SELECT `key`, `value` FROM `temp_updates` WHERE `status` = $p0",
+ wantArgs: []any{driver.NamedValue{Name: "p0", Value: "pending"}},
+ },
+ {
+ input: func() Querier {
+ d := Dialect(dialect.YDB)
+ subquery := d.Select("*").
+ From(Table("staged_data"))
+ return d.Update("users").
+ On(subquery).
+ Returning("id", "name")
+ }(),
+ wantQuery: "UPDATE `users` ON SELECT * FROM `staged_data` RETURNING `id`, `name`",
+ },
+ {
+ input: func() Querier {
+ d := Dialect(dialect.YDB)
+ t1 := d.Table("orders")
+ t2 := d.Table("users").View("idx_email").As("u")
+ return d.Select(t1.C("id"), t2.C("name")).
+ From(t1).
+ Join(t2).
+ On(t1.C("user_id"), t2.C("id"))
+ }(),
+ wantQuery: "SELECT `orders`.`id`, `u`.`name` FROM `orders` JOIN `users` VIEW `idx_email` AS `u` ON `orders`.`user_id` = `u`.`id`",
+ },
+ {
+ input: func() Querier {
+ d := Dialect(dialect.YDB)
+ t1 := d.Table("a_table").As("a")
+ t2 := d.Table("b_table").View("b_index_ref").As("b")
+ return d.Select(t1.C("value"), t2.C("value")).
+ From(t1).
+ Join(t2).
+ On(t1.C("ref"), t2.C("ref"))
+ }(),
+ wantQuery: "SELECT `a`.`value`, `b`.`value` FROM `a_table` AS `a` JOIN `b_table` VIEW `b_index_ref` AS `b` ON `a`.`ref` = `b`.`ref`",
+ },
+ {
+ input: func() Querier {
+ d := Dialect(dialect.YDB)
+ t1 := d.Table("orders")
+ t2 := d.Table("products").View("idx_category")
+ return d.Select("*").
+ From(t1).
+ LeftJoin(t2).
+ On(t1.C("product_id"), t2.C("id")).
+ Where(EQ(t2.C("category"), "Electronics"))
+ }(),
+ wantQuery: "SELECT * FROM `orders` LEFT JOIN `products` VIEW `idx_category` AS `t1` ON `orders`.`product_id` = `t1`.`id` WHERE `t1`.`category` = $p0",
+ wantArgs: []any{driver.NamedValue{Name: "p0", Value: "Electronics"}},
+ },
+ {
+ input: func() Querier {
+ d := Dialect(dialect.YDB)
+ t1 := d.Table("users")
+ t2 := d.Table("blacklist")
+ return d.Select(t1.C("id"), t1.C("name")).
+ From(t1).
+ LeftSemiJoin(t2).
+ On(t1.C("id"), t2.C("user_id"))
+ }(),
+ wantQuery: "SELECT `users`.`id`, `users`.`name` FROM `users` LEFT SEMI JOIN `blacklist` AS `t1` ON `users`.`id` = `t1`.`user_id`",
+ },
+ {
+ input: func() Querier {
+ d := Dialect(dialect.YDB)
+ t1 := d.Table("orders")
+ t2 := d.Table("active_users").As("t1")
+ return d.Select(t2.C("id"), t2.C("email")).
+ From(t1).
+ RightSemiJoin(t2).
+ On(t1.C("user_id"), t2.C("id"))
+ }(),
+ wantQuery: "SELECT `t1`.`id`, `t1`.`email` FROM `orders` RIGHT SEMI JOIN `active_users` AS `t1` ON `orders`.`user_id` = `t1`.`id`",
+ },
+ {
+ input: func() Querier {
+ d := Dialect(dialect.YDB)
+ t1 := d.Table("users")
+ t2 := d.Table("deleted_users")
+ return d.Select(t1.C("id"), t1.C("name")).
+ From(t1).
+ LeftOnlyJoin(t2).
+ On(t1.C("id"), t2.C("id"))
+ }(),
+ wantQuery: "SELECT `users`.`id`, `users`.`name` FROM `users` LEFT ONLY JOIN `deleted_users` AS `t1` ON `users`.`id` = `t1`.`id`",
+ },
+ {
+ input: func() Querier {
+ d := Dialect(dialect.YDB)
+ t1 := d.Table("archived")
+ t2 := d.Table("users").As("t1")
+ return d.Select(t2.C("id"), t2.C("status")).
+ From(t1).
+ RightOnlyJoin(t2).
+ On(t1.C("user_id"), t2.C("id"))
+ }(),
+ wantQuery: "SELECT `t1`.`id`, `t1`.`status` FROM `archived` RIGHT ONLY JOIN `users` AS `t1` ON `archived`.`user_id` = `t1`.`id`",
+ },
+ {
+ input: func() Querier {
+ d := Dialect(dialect.YDB)
+ t1 := d.Table("table_a").As("a")
+ t2 := d.Table("table_b").As("b")
+ return d.Select(t1.C("key"), t2.C("key")).
+ From(t1).
+ ExclusionJoin(t2).
+ On(t1.C("key"), t2.C("key"))
+ }(),
+ wantQuery: "SELECT `a`.`key`, `b`.`key` FROM `table_a` AS `a` EXCLUSION JOIN `table_b` AS `b` ON `a`.`key` = `b`.`key`",
+ },
+ {
+ 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`, `b`.`value`, `c`.`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 +2113,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 +2231,111 @@ func TestSelector_Intersect(t *testing.T) {
require.Equal(t, []any{20, "true", 18}, args)
}
+func TestSelector_AssumeOrderBy_YDB(t *testing.T) {
+ query, args := Dialect(dialect.YDB).
+ Select("*").
+ From(Table("my_table")).
+ AssumeOrderBy("key").
+ Query()
+ require.Equal(t, "SELECT * FROM `my_table` ASSUME ORDER BY `key`", query)
+ require.Empty(t, args)
+
+ query, args = Dialect(dialect.YDB).
+ Select("key", "subkey").
+ From(Table("my_table")).
+ AssumeOrderBy("key", Desc("subkey")).
+ Query()
+ require.Equal(t, "SELECT `key`, `subkey` FROM `my_table` ASSUME ORDER BY `key`, `subkey` DESC", query)
+ require.Empty(t, args)
+
+ query, args = Dialect(dialect.YDB).
+ Select("*").
+ From(Table("orders")).
+ Where(EQ("status", "active")).
+ AssumeOrderBy("created_at").
+ Query()
+ require.Equal(t, "SELECT * FROM `orders` WHERE `status` = $p0 ASSUME ORDER BY `created_at`", query)
+ require.Equal(t, []any{driver.NamedValue{Name: "p0", Value: "active"}}, args)
+
+ query, args = Dialect(dialect.YDB).
+ Select("id", "name").
+ From(Table("users")).
+ AssumeOrderBy("id").
+ Limit(10).
+ Query()
+ require.Equal(t, "SELECT `id`, `name` FROM `users` ASSUME ORDER BY `id` LIMIT 10", query)
+ require.Empty(t, args)
+
+ t.Run("OrderBy then AssumeOrderBy should error", func(t *testing.T) {
+ selector := Dialect(dialect.YDB).
+ Select("*").
+ From(Table("users")).
+ OrderBy("id").
+ AssumeOrderBy("id")
+
+ err := selector.Err()
+ require.Error(t, err)
+ })
+
+ t.Run("AssumeOrderBy then OrderBy should error", func(t *testing.T) {
+ selector := Dialect(dialect.YDB).
+ Select("*").
+ From(Table("users")).
+ AssumeOrderBy("id").
+ OrderBy("id")
+
+ err := selector.Err()
+ require.Error(t, err)
+ })
+
+ t.Run("Non-YDB dialect with AssumeOrderBy should error", func(t *testing.T) {
+ selector := Dialect(dialect.Postgres).
+ Select("*").
+ From(Table("users")).
+ AssumeOrderBy("name")
+
+ err := selector.Err()
+ require.Error(t, err)
+ })
+}
+
+func TestSelector_VIEW_SecondaryIndex_YDB(t *testing.T) {
+ t.Run("Simple SELECT with VIEW in FROM clause", func(t *testing.T) {
+ d := Dialect(dialect.YDB)
+ query, args := d.Select("series_id", "title", "info", "release_date", "views", "uploaded_user_id").
+ From(d.Table("series").View("views_index")).
+ Where(GTE("views", 1000)).
+ Query()
+
+ require.Equal(t, "SELECT `series_id`, `title`, `info`, `release_date`, `views`, `uploaded_user_id` FROM `series` VIEW `views_index` WHERE `views` >= $p0", query)
+ require.Equal(t, []any{driver.NamedValue{Name: "p0", Value: 1000}}, args)
+ })
+
+ t.Run("JOIN with VIEW on both tables", func(t *testing.T) {
+ d := Dialect(dialect.YDB)
+ series := d.Table("series").View("users_index").As("t1")
+ users := d.Table("users").View("name_index").As("t2")
+
+ query, args := d.Select(series.C("series_id"), series.C("title")).
+ From(series).
+ Join(users).
+ On(series.C("uploaded_user_id"), users.C("user_id")).
+ Where(EQ(users.C("name"), "John Doe")).
+ Query()
+
+ require.Equal(t, "SELECT `t1`.`series_id`, `t1`.`title` FROM `series` VIEW `users_index` AS `t1` JOIN `users` VIEW `name_index` AS `t2` ON `t1`.`uploaded_user_id` = `t2`.`user_id` WHERE `t2`.`name` = $p0", query)
+ require.Equal(t, []any{driver.NamedValue{Name: "p0", Value: "John Doe"}}, args)
+ })
+
+ t.Run("VIEW on non-YDB dialect should error", func(t *testing.T) {
+ d := Dialect(dialect.Postgres)
+ table := d.Table("users").View("idx_name")
+
+ err := table.Err()
+ require.Error(t, err)
+ })
+}
+
func TestSelector_SetOperatorWithRecursive(t *testing.T) {
t1, t2, t3 := Table("files"), Table("files"), Table("path")
n := Queries{
From e67bef20488a2032755f32ba1075950e52eecbe8 Mon Sep 17 00:00:00 2001
From: Egor Danilov <63148392+LostImagin4tion@users.noreply.github.com>
Date: Tue, 25 Nov 2025 14:02:06 +0300
Subject: [PATCH 03/14] dialect/sql: added support for ydb create view queries
(#5)
---
dialect/sql/builder.go | 6 ++++++
dialect/sql/builder_test.go | 28 ++++++++++++++++++++++++++++
2 files changed, 34 insertions(+)
diff --git a/dialect/sql/builder.go b/dialect/sql/builder.go
index a59b415719..02df35dc68 100644
--- a/dialect/sql/builder.go
+++ b/dialect/sql/builder.go
@@ -131,6 +131,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
diff --git a/dialect/sql/builder_test.go b/dialect/sql/builder_test.go
index 91f42e5677..fbeb9fded5 100644
--- a/dialect/sql/builder_test.go
+++ b/dialect/sql/builder_test.go
@@ -2336,6 +2336,34 @@ func TestSelector_VIEW_SecondaryIndex_YDB(t *testing.T) {
})
}
+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{
From a51ada81cff0985b4ee4ccc6a51d32f902f07921 Mon Sep 17 00:00:00 2001
From: Egor Danilov <63148392+LostImagin4tion@users.noreply.github.com>
Date: Tue, 25 Nov 2025 14:59:19 +0300
Subject: [PATCH 04/14] dialect/sql: added support for YQL batch update and
delete queries (#6)
* dialect/sql: added support for batch update query
* dialect/sql: added support for batch delete query
* dialect/sql: fixed comment
---
dialect/sql/builder.go | 120 +++++++++++++++++++++++++++++++++---
dialect/sql/builder_test.go | 115 ++++++++++++++++++++++++++++++++++
2 files changed, 225 insertions(+), 10 deletions(-)
diff --git a/dialect/sql/builder.go b/dialect/sql/builder.go
index 02df35dc68..bb661d1d8d 100644
--- a/dialect/sql/builder.go
+++ b/dialect/sql/builder.go
@@ -586,7 +586,10 @@ type UpdateBuilder struct {
order []any
limit *int
prefix Queries
- onSelect *Selector // YDB-specific: UPDATE ON subquery
+
+ // YDB-specific:
+ onSelect *Selector // UPDATE ON subquery
+ isBatch bool // use BATCH UPDATE instead of UPDATE
}
// Update creates a builder for the `UPDATE` statement.
@@ -594,6 +597,17 @@ type UpdateBuilder struct {
// Update("users").Set("name", "foo").Set("age", 10)
func Update(table string) *UpdateBuilder { return &UpdateBuilder{table: table} }
+// BatchUpdate creates a builder for the `BATCH UPDATE` statement (YDB-specific).
+// BATCH UPDATE processes large tables in batches, minimizing lock invalidation risk.
+//
+// Note: BATCH UPDATE is only supported in YDB dialect.
+// Note: YDB uses path notation for tables, e.g. "/database/path/to/table"
+//
+// BatchUpdate("/local/my_table").Set("status", "active").Where(GT("id", 100))
+func BatchUpdate(table string) *UpdateBuilder {
+ return &UpdateBuilder{table: table, isBatch: true}
+}
+
// Schema sets the database name for the updated table.
func (u *UpdateBuilder) Schema(name string) *UpdateBuilder {
u.schema = name
@@ -717,12 +731,36 @@ func (u *UpdateBuilder) On(s *Selector) *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 ")
+
+ // BATCH UPDATE (YDB-specific)
+ if u.isBatch {
+ if !b.ydb() {
+ b.AddError(fmt.Errorf("BATCH UPDATE: unsupported dialect: %q", b.dialect))
+ return "", nil, b.Err()
+ }
+ if len(u.returning) > 0 {
+ b.AddError(fmt.Errorf("BATCH UPDATE: RETURNING clause is not supported"))
+ return "", nil, b.Err()
+ }
+ if u.onSelect != nil {
+ b.AddError(fmt.Errorf("BATCH UPDATE: UPDATE ON pattern is not supported"))
+ return "", nil, b.Err()
+ }
+ b.WriteString("BATCH UPDATE ")
+ } else {
+ b.WriteString("UPDATE ")
+ }
+
b.writeSchema(u.schema)
b.Ident(u.table)
@@ -731,7 +769,7 @@ func (u *UpdateBuilder) Query() (string, []any) {
b.WriteString(" ON ")
b.Join(u.onSelect)
joinReturning(u.returning, &b)
- return b.String(), b.args
+ return b.String(), b.args, nil
}
// Standard UPDATE SET pattern
@@ -747,7 +785,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.
@@ -782,9 +820,10 @@ type DeleteBuilder struct {
schema string
where *Predicate
- // For YDB's DELETE FROM ... ON SELECT pattern
- onSelect *Selector
+ // YDB-specific:
+ onSelect *Selector // DELETE FROM ... ON SELECT pattern
returning []string
+ isBatch bool // use BATCH DELETE instead of DELETE
}
// Delete creates a builder for the `DELETE` statement.
@@ -802,6 +841,17 @@ type DeleteBuilder struct {
// )
func Delete(table string) *DeleteBuilder { return &DeleteBuilder{table: table} }
+// BatchDelete creates a builder for the `BATCH DELETE FROM` statement (YDB-specific).
+// BATCH DELETE processes large tables in batches, minimizing lock invalidation risk.
+//
+// Note: BATCH DELETE is only supported in YDB dialect.
+//
+// BatchDelete("/local/my_table")
+// .Where(GT("Key1", 1))
+func BatchDelete(table string) *DeleteBuilder {
+ return &DeleteBuilder{table: table, isBatch: true}
+}
+
// Schema sets the database name for the table whose row will be deleted.
func (d *DeleteBuilder) Schema(name string) *DeleteBuilder {
d.schema = name
@@ -854,8 +904,32 @@ func (d *DeleteBuilder) Returning(columns ...string) *DeleteBuilder {
// Query returns query representation of a `DELETE` statement.
func (d *DeleteBuilder) Query() (string, []any) {
+ query, args, _ := d.QueryErr()
+ return query, args
+}
+
+func (d *DeleteBuilder) QueryErr() (string, []any, error) {
b := d.Builder.clone()
- b.WriteString("DELETE FROM ")
+
+ // BATCH DELETE (YDB-specific)
+ if d.isBatch {
+ if !b.ydb() {
+ b.AddError(fmt.Errorf("BATCH DELETE: unsupported dialect: %q", b.dialect))
+ return "", nil, b.Err()
+ }
+ if len(d.returning) > 0 {
+ b.AddError(fmt.Errorf("BATCH DELETE: RETURNING clause is not supported"))
+ return "", nil, b.Err()
+ }
+ if d.onSelect != nil {
+ b.AddError(fmt.Errorf("BATCH DELETE: DELETE ON pattern is not supported"))
+ return "", nil, b.Err()
+ }
+ b.WriteString("BATCH DELETE FROM ")
+ } else {
+ b.WriteString("DELETE FROM ")
+ }
+
b.writeSchema(d.schema)
b.Ident(d.table)
@@ -870,7 +944,7 @@ func (d *DeleteBuilder) Query() (string, []any) {
}
joinReturning(d.returning, &b)
- return b.String(), b.args
+ return b.String(), b.args, nil
}
// Predicate is a where predicate.
@@ -3286,9 +3360,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
@@ -3711,6 +3786,19 @@ func (d *DialectBuilder) Update(table string) *UpdateBuilder {
return b
}
+// BatchUpdate creates an UpdateBuilder for the BATCH UPDATE statement with the configured dialect.
+// BATCH UPDATE is only supported in YDB dialect.
+//
+// Dialect(dialect.YDB).
+// BatchUpdate("users").
+// Set("status", "active").
+// Where(GT("created_at", time.Now()))
+func (d *DialectBuilder) BatchUpdate(table string) *UpdateBuilder {
+ b := BatchUpdate(table)
+ b.SetDialect(d.dialect)
+ return b
+}
+
// Delete creates a DeleteBuilder for the configured dialect.
//
// Dialect(dialect.Postgres).
@@ -3721,6 +3809,18 @@ func (d *DialectBuilder) Delete(table string) *DeleteBuilder {
return b
}
+// BatchDelete creates a DeleteBuilder for the BATCH DELETE statement with the configured dialect.
+// BATCH DELETE is only supported in YDB dialect.
+//
+// Dialect(dialect.YDB).
+// BatchDelete("users").
+// Where(GT("Key1", 1))
+func (d *DialectBuilder) BatchDelete(table string) *DeleteBuilder {
+ b := BatchDelete(table)
+ b.SetDialect(d.dialect)
+ return b
+}
+
// Select creates a Selector for the configured dialect.
//
// Dialect(dialect.Postgres).
diff --git a/dialect/sql/builder_test.go b/dialect/sql/builder_test.go
index fbeb9fded5..a58776ab4d 100644
--- a/dialect/sql/builder_test.go
+++ b/dialect/sql/builder_test.go
@@ -2336,6 +2336,121 @@ func TestSelector_VIEW_SecondaryIndex_YDB(t *testing.T) {
})
}
+func TestBatchUpdate_YDB(t *testing.T) {
+ t.Run("Basic BATCH UPDATE with SET and WHERE", func(t *testing.T) {
+ d := Dialect(dialect.YDB)
+ query, args := d.BatchUpdate("my_table").
+ Set("Value1", "foo").
+ Set("Value2", 0).
+ Where(GT("Key1", 1)).
+ Query()
+
+ require.Equal(t, "BATCH UPDATE `my_table` SET `Value1` = $p0, `Value2` = $p1 WHERE `Key1` > $p2", query)
+ require.Equal(t, []any{
+ driver.NamedValue{Name: "p0", Value: "foo"},
+ driver.NamedValue{Name: "p1", Value: 0},
+ driver.NamedValue{Name: "p2", Value: 1},
+ }, args)
+ })
+
+ t.Run("BATCH UPDATE on non-YDB dialect should error", func(t *testing.T) {
+ builder := Dialect(dialect.MySQL).
+ BatchUpdate("users").
+ Set("status", "active").
+ Where(GT("created_at", "2024-01-01"))
+
+ query, args, err := builder.QueryErr()
+
+ require.Empty(t, query)
+ require.Empty(t, args)
+ require.Error(t, err)
+ })
+
+ t.Run("BATCH UPDATE with RETURNING should error", func(t *testing.T) {
+ builder := Dialect(dialect.YDB).
+ BatchUpdate("users").
+ Set("status", "active").
+ Returning("id", "status")
+
+ query, args, err := builder.QueryErr()
+
+ require.Empty(t, query)
+ require.Empty(t, args)
+ require.Error(t, err)
+ })
+
+ t.Run("BATCH UPDATE with UPDATE ON pattern should error", func(t *testing.T) {
+ d := Dialect(dialect.YDB)
+ subquery := d.Select("id").From(Table("orders")).Where(EQ("status", "pending"))
+
+ builder := d.BatchUpdate("users").
+ Set("status", "active").
+ On(subquery)
+
+ query, args, err := builder.QueryErr()
+
+ require.Empty(t, query)
+ require.Empty(t, args)
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "BATCH UPDATE: UPDATE ON pattern is not supported")
+ })
+}
+
+func TestBatchDelete_YDB(t *testing.T) {
+ t.Run("Basic BATCH DELETE", func(t *testing.T) {
+ d := Dialect(dialect.YDB)
+ query, args := d.BatchDelete("my_table").
+ Where(And(GT("Key1", 1), GTE("Key2", "One"))).
+ Query()
+
+ require.Equal(t, "BATCH DELETE FROM `my_table` WHERE `Key1` > $p0 AND `Key2` >= $p1", query)
+ require.Equal(t, []any{
+ driver.NamedValue{Name: "p0", Value: 1},
+ driver.NamedValue{Name: "p1", Value: "One"},
+ }, args)
+ })
+
+ t.Run("BATCH DELETE on non-YDB dialect should error", func(t *testing.T) {
+ builder := Dialect(dialect.MySQL).
+ BatchDelete("users").
+ Where(GT("id", 100))
+
+ query, args, err := builder.QueryErr()
+
+ require.Empty(t, query)
+ require.Empty(t, args)
+ require.Error(t, err)
+ })
+
+ t.Run("BATCH DELETE with RETURNING should error", func(t *testing.T) {
+ builder := Dialect(dialect.YDB).
+ BatchDelete("users").
+ Where(GT("id", 100)).
+ Returning("id")
+
+ query, args, err := builder.QueryErr()
+
+ require.Empty(t, query)
+ require.Empty(t, args)
+ require.Error(t, err)
+ })
+
+ t.Run("BATCH DELETE with DELETE ON pattern should error", func(t *testing.T) {
+ d := Dialect(dialect.YDB)
+ subquery := d.Select("id").From(Table("users")).Where(EQ("status", "deleted"))
+
+ builder := d.BatchDelete("users").
+ On(subquery)
+
+ query, args, err := builder.QueryErr()
+
+ require.Empty(t, query)
+ require.Empty(t, args)
+ require.Error(t, err)
+ require.Contains(t, err.Error(), "BATCH DELETE: DELETE ON pattern is not supported")
+ })
+}
+
func TestCreateView_YDB(t *testing.T) {
t.Run("Basic view with security_invoker", func(t *testing.T) {
d := Dialect(dialect.YDB)
From ea29237a390e1aceee8f0a8d86319531bf31ba3e Mon Sep 17 00:00:00 2001
From: Egor Danilov <63148392+LostImagin4tion@users.noreply.github.com>
Date: Mon, 1 Dec 2025 12:32:11 +0300
Subject: [PATCH 05/14] dialect/sql: added checks for clauses which are not
supported by YQL (#8)
---
dialect/sql/builder.go | 95 +++++++++++++++++++++++--------------
dialect/sql/builder_test.go | 2 +-
2 files changed, 61 insertions(+), 36 deletions(-)
diff --git a/dialect/sql/builder.go b/dialect/sql/builder.go
index bb661d1d8d..72f5d17aba 100644
--- a/dialect/sql/builder.go
+++ b/dialect/sql/builder.go
@@ -229,7 +229,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
}
@@ -404,6 +408,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{}
}
@@ -486,13 +494,13 @@ func (i *InsertBuilder) QueryErr() (string, []any, error) {
switch {
case i.isUpsert:
if !b.ydb() {
- b.AddError(fmt.Errorf("UPSERT INTO: unsupported dialect: %q", b.dialect))
+ b.AddError(fmt.Errorf("UPSERT INTO is not supported by %q", b.dialect))
return "", nil, b.Err()
}
b.WriteString("UPSERT INTO ")
case i.isReplace:
if !b.ydb() {
- b.AddError(fmt.Errorf("REPLACE INTO: unsupported dialect: %q", b.dialect))
+ b.AddError(fmt.Errorf("REPLACE INTO is not supported by %q", b.dialect))
return "", nil, b.Err()
}
b.WriteString("REPLACE INTO ")
@@ -676,8 +684,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 {
@@ -689,8 +697,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
@@ -724,7 +732,7 @@ func (u *UpdateBuilder) On(s *Selector) *UpdateBuilder {
if u.ydb() {
u.onSelect = s
} else {
- u.AddError(fmt.Errorf("UPDATE ON: unsupported dialect: %q", u.dialect))
+ u.AddError(fmt.Errorf("UPDATE ON is not supported by %q", u.dialect))
}
return u
}
@@ -745,7 +753,7 @@ func (u *UpdateBuilder) QueryErr() (string, []any, error) {
// BATCH UPDATE (YDB-specific)
if u.isBatch {
if !b.ydb() {
- b.AddError(fmt.Errorf("BATCH UPDATE: unsupported dialect: %q", b.dialect))
+ b.AddError(fmt.Errorf("BATCH UPDATE is not supported by %q", b.dialect))
return "", nil, b.Err()
}
if len(u.returning) > 0 {
@@ -846,8 +854,8 @@ func Delete(table string) *DeleteBuilder { return &DeleteBuilder{table: table} }
//
// Note: BATCH DELETE is only supported in YDB dialect.
//
-// BatchDelete("/local/my_table")
-// .Where(GT("Key1", 1))
+// BatchDelete("/local/my_table").
+// Where(GT("Key1", 1))
func BatchDelete(table string) *DeleteBuilder {
return &DeleteBuilder{table: table, isBatch: true}
}
@@ -886,7 +894,7 @@ func (d *DeleteBuilder) On(s *Selector) *DeleteBuilder {
if d.ydb() {
d.onSelect = s
} else {
- d.AddError(fmt.Errorf("DELETE ON: unsupported dialect: %q", d.dialect))
+ d.AddError(fmt.Errorf("DELETE ON is not supported by %q", d.dialect))
}
return d
}
@@ -897,7 +905,7 @@ func (d *DeleteBuilder) Returning(columns ...string) *DeleteBuilder {
if d.ydb() {
d.returning = columns
} else {
- d.AddError(fmt.Errorf("DELETE RETURNING: unsupported dialect: %q", d.dialect))
+ d.AddError(fmt.Errorf("DELETE RETURNING is not supported by %q", d.dialect))
}
return d
}
@@ -914,7 +922,7 @@ func (d *DeleteBuilder) QueryErr() (string, []any, error) {
// BATCH DELETE (YDB-specific)
if d.isBatch {
if !b.ydb() {
- b.AddError(fmt.Errorf("BATCH DELETE: unsupported dialect: %q", b.dialect))
+ b.AddError(fmt.Errorf("BATCH DELETE is not supported by %q", b.dialect))
return "", nil, b.Err()
}
if len(d.returning) > 0 {
@@ -1323,6 +1331,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)
}
@@ -1338,6 +1348,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)
}
@@ -1411,7 +1423,7 @@ func (p *Predicate) escapedLikeFold(col, left, substr, right string) *Predicate
// 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:
+ case dialect.Postgres, dialect.YDB:
b.Ident(col).WriteString(" ILIKE ")
b.Arg(left + strings.ToLower(w) + right)
default: // SQLite.
@@ -1468,7 +1480,7 @@ func (p *Predicate) ColumnsHasPrefix(col, prefixC string) *Predicate {
p.WriteString(" ESCAPE ").Arg("\\")
}
default:
- b.AddError(fmt.Errorf("ColumnsHasPrefix: unsupported dialect: %q", p.dialect))
+ b.AddError(fmt.Errorf("ColumnsHasPrefix is not supported by %q", p.dialect))
}
})
}
@@ -1815,7 +1827,7 @@ func (s *SelectTable) View(index string) *SelectTable {
if s.ydb() {
s.index = index
} else {
- s.AddError(fmt.Errorf("VIEW: unsupported dialect: %q", s.dialect))
+ s.AddError(fmt.Errorf("VIEW is not supported by %q", s.dialect))
}
return s
}
@@ -2111,9 +2123,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
}
@@ -2431,17 +2447,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,
@@ -2454,17 +2475,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,
@@ -2616,8 +2641,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 {
@@ -2754,7 +2779,7 @@ func (s *Selector) AssumeOrderBy(columns ...string) *Selector {
s.assumeOrder = append(s.assumeOrder, columns...)
} else {
- s.AddError(fmt.Errorf("ASSUME ORDER BY: unsupported dialect: %q", s.dialect))
+ s.AddError(fmt.Errorf("ASSUME ORDER BY is not supported by %q", s.dialect))
}
return s
}
diff --git a/dialect/sql/builder_test.go b/dialect/sql/builder_test.go
index a58776ab4d..028b6d10ee 100644
--- a/dialect/sql/builder_test.go
+++ b/dialect/sql/builder_test.go
@@ -2598,7 +2598,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) {
From c442e8609acc99109a36f24bfeab13be6b3bba4c Mon Sep 17 00:00:00 2001
From: Egor Danilov <63148392+LostImagin4tion@users.noreply.github.com>
Date: Fri, 16 Jan 2026 16:57:36 +0300
Subject: [PATCH 06/14] dialect/sql/schema: added support for ydb schema
migrations (#9)
---
.github/workflows/ci.yml | 2 +-
dialect/sql/schema/atlas.go | 2 +
dialect/sql/schema/schema.go | 9 ++
dialect/sql/schema/ydb.go | 255 +++++++++++++++++++++++++++++++++++
dialect/ydb/driver.go | 2 +-
entc/integration/go.mod | 23 +++-
entc/integration/go.sum | 185 ++++++++++++++++++++++---
examples/go.mod | 27 ++--
examples/go.sum | 84 +++++++-----
go.mod | 30 +++--
go.sum | 76 +++++------
11 files changed, 576 insertions(+), 119 deletions(-)
create mode 100644 dialect/sql/schema/ydb.go
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5d317d0bb2..5c09c7285b 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
diff --git a/dialect/sql/schema/atlas.go b/dialect/sql/schema/atlas.go
index d1704ca192..af72e56b83 100644
--- a/dialect/sql/schema/atlas.go
+++ b/dialect/sql/schema/atlas.go
@@ -1126,6 +1126,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..94b1a0a064
--- /dev/null
+++ b/dialect/sql/schema/ydb.go
@@ -0,0 +1,255 @@
+// 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"
+ "errors"
+ "fmt"
+ "strings"
+
+ "entgo.io/ent/dialect"
+ entsql "entgo.io/ent/dialect/sql"
+ entdriver "entgo.io/ent/dialect/ydb"
+ "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 := &sql.Rows{}
+ if err := d.Driver.Query(ctx, "SELECT version()", nil, 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) {
+ ydbDriver, ok := conn.(*entdriver.YDBDriver)
+ if !ok {
+ return nil, fmt.Errorf("expected dialect/ydb.YDBDriver, but got %T", conn)
+ }
+
+ return atlas.Open(
+ ydbDriver.NativeDriver(),
+ ydbDriver.DB(),
+ )
+}
+
+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:
+ err = errors.New("ydb: Enum can't be used as column data type for tables")
+ 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 SYNC indexes.
+func (d *YDB) atUniqueC(
+ table1 *Table,
+ column1 *Column,
+ table2 *schema.Table,
+ column2 *schema.Column,
+) {
+ // 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.
+ idxName := fmt.Sprintf("%s_%s_index", table1.Name, column1.Name)
+ index := schema.NewUniqueIndex(idxName).AddColumns(column2)
+
+ // Add YDB-specific attribute for GLOBAL SYNC index type.
+ index.AddAttrs(&atlas.YDBIndexAttributes{Global: true, Sync: true})
+
+ 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 {
+ column.Type.Type = atlas.SerialFromInt(intType)
+ }
+}
+
+// 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 {
+ for _, column1 := range index1.Columns {
+ column2, ok := table2.Column(column1.Name)
+ if !ok {
+ return fmt.Errorf("unexpected index %q column: %q", index1.Name, column1.Name)
+ }
+ index2.AddParts(&schema.IndexPart{C: column2})
+ }
+
+ // Set YDB-specific index attributes.
+ // By default, use GLOBAL SYNC for consistency.
+ idxType := &atlas.YDBIndexAttributes{Global: true, Sync: true}
+
+ // Check for annotation overrides.
+ if index1.Annotation != nil {
+ if indexType, ok := indexType(index1, dialect.YDB); ok {
+ // Parse YDB-specific index type from annotation.
+ switch strings.ToUpper(indexType) {
+ case "GLOBAL ASYNC", "ASYNC":
+ idxType.Sync = false
+ case "LOCAL":
+ idxType.Global = false
+ case "LOCAL ASYNC":
+ idxType.Global = false
+ idxType.Sync = false
+ }
+ }
+ }
+ index2.AddAttrs(idxType)
+ 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, ", "),
+ )
+}
diff --git a/dialect/ydb/driver.go b/dialect/ydb/driver.go
index f0845647c1..14c7e38418 100644
--- a/dialect/ydb/driver.go
+++ b/dialect/ydb/driver.go
@@ -32,7 +32,7 @@ func Open(ctx context.Context, dsn string) (*YDBDriver, error) {
ydb.WithTablePathPrefix(nativeDriver.Name()),
)
if err != nil {
- panic(err)
+ return nil, err
}
dbSQLDriver := sql.OpenDB(conn)
diff --git a/entc/integration/go.mod b/entc/integration/go.mod
index 9167aee375..1e73a8cb46 100644
--- a/entc/integration/go.mod
+++ b/entc/integration/go.mod
@@ -1,6 +1,8 @@
module entgo.io/ent/entc/integration
-go 1.24.0
+go 1.24.9
+
+toolchain go1.24.11
replace entgo.io/ent => ../../
@@ -12,8 +14,8 @@ require (
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.10.0
- golang.org/x/sync v0.17.0
+ github.com/stretchr/testify v1.11.1
+ golang.org/x/sync v0.19.0
)
require (
@@ -22,8 +24,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/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
@@ -32,9 +36,18 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.11.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.0 // 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.28.0 // indirect
- golang.org/x/text v0.30.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/LostImagin4tion/atlas v0.0.5
diff --git a/entc/integration/go.sum b/entc/integration/go.sum
index 878cf011ac..7a58fa2697 100644
--- a/entc/integration/go.sum
+++ b/entc/integration/go.sum
@@ -1,33 +1,87 @@
-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/LostImagin4tion/atlas v0.0.5 h1:SoP7EqpVLCMNCWPIZovdwOQUeJcO8ZY5cDTG5VMuIQM=
+github.com/LostImagin4tion/atlas v0.0.5/go.mod h1:Rco1malutATQGeWEoYFzurfzIvs+galayoZ0+Pz4als=
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/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.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,10 +103,12 @@ 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=
@@ -61,22 +117,119 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
-github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+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/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.0 h1:KPnGV2diuX1A4/1zXLO1UWHJokWC8yICzEfjdkSUWKo=
+github.com/ydb-platform/ydb-go-sdk/v3 v3.125.0/go.mod h1:/LjMxb/rXmoGAAnImoqAFIlhO5ampHacbvDetQitCk4=
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.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
-golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
-golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
-golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
-golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
-golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
-golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
-golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
+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/examples/go.mod b/examples/go.mod
index 15f275af12..74e79123fb 100644
--- a/examples/go.mod
+++ b/examples/go.mod
@@ -1,6 +1,8 @@
module entgo.io/ent/examples
-go 1.24.0
+go 1.24.9
+
+toolchain go1.24.11
replace entgo.io/ent => ../
@@ -11,7 +13,7 @@ require (
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.10.0
+ github.com/stretchr/testify v1.11.1
gocloud.dev v0.28.0
)
@@ -21,24 +23,31 @@ 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/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/ydb-platform/ydb-go-sdk/v3 v3.125.0 // 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.43.0 // indirect
- golang.org/x/mod v0.28.0 // indirect
- golang.org/x/net v0.46.0 // indirect
- golang.org/x/sys v0.37.0 // indirect
- golang.org/x/text v0.30.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.76.0 // indirect
- google.golang.org/protobuf v1.36.10 // 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/LostImagin4tion/atlas v0.0.5
diff --git a/examples/go.sum b/examples/go.sum
index c164037661..df815aaa94 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=
@@ -125,8 +123,8 @@ cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZ
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/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM=
-cloud.google.com/go/compute/metadata v0.7.0 h1:PBWF+iiAerVNe8UCHxdOt6eHLVc3ydFeOCw78U8ytSU=
-cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo=
+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=
@@ -451,6 +449,8 @@ github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/GoogleCloudPlatform/cloudsql-proxy v1.33.1/go.mod h1:n3KDPrdaY2p9Nr0B1allAdjYArwIpXQcitNbsS/Qiok=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
+github.com/LostImagin4tion/atlas v0.0.5 h1:SoP7EqpVLCMNCWPIZovdwOQUeJcO8ZY5cDTG5VMuIQM=
+github.com/LostImagin4tion/atlas v0.0.5/go.mod h1:Rco1malutATQGeWEoYFzurfzIvs+galayoZ0+Pz4als=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
@@ -956,6 +956,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=
@@ -1238,6 +1240,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=
@@ -1560,6 +1564,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=
@@ -1648,8 +1654,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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
-github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+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=
@@ -1691,6 +1697,10 @@ 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/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.0 h1:KPnGV2diuX1A4/1zXLO1UWHJokWC8yICzEfjdkSUWKo=
+github.com/ydb-platform/ydb-go-sdk/v3 v3.125.0/go.mod h1:/LjMxb/rXmoGAAnImoqAFIlhO5ampHacbvDetQitCk4=
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=
@@ -1738,8 +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.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
-go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
+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=
@@ -1751,8 +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.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
-go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
+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=
@@ -1769,26 +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.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
-go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
+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.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
-go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
+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.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
-go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
+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.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
-go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
+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=
@@ -1806,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=
@@ -1857,8 +1869,8 @@ golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0
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/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
-golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04=
-golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0=
+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=
@@ -1900,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.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
-golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
+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=
@@ -1985,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.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
-golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
+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=
@@ -2016,8 +2028,8 @@ golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri
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/go.mod h1:Cwn6afJ8jrQwYMxQDTpISoXmXW9I6qF6vDeuuoX3Ibs=
-golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
-golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
+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=
@@ -2034,8 +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.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
-golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
+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=
@@ -2186,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.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
-golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+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=
@@ -2208,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.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
-golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
+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=
@@ -2555,8 +2567,8 @@ google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCD
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/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww=
-google.golang.org/grpc v1.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A=
-google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c=
+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=
@@ -2573,8 +2585,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
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/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
-google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
+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/go.mod b/go.mod
index 5b224366a8..9513cbfb74 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,8 @@
module entgo.io/ent
-go 1.24.0
+go 1.24.9
+
+toolchain go1.24.11
require (
ariga.io/atlas v0.36.2-0.20250730182955-2c6300d0a3e1
@@ -15,11 +17,11 @@ 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.10.0
- github.com/ydb-platform/ydb-go-sdk/v3 v3.118.0
+ github.com/stretchr/testify v1.11.1
+ github.com/ydb-platform/ydb-go-sdk/v3 v3.125.0
go.opencensus.io v0.24.0
- golang.org/x/sync v0.17.0
- golang.org/x/tools v0.37.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
)
@@ -48,16 +50,18 @@ require (
github.com/sergi/go-diff v1.3.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/objx v0.5.2 // indirect
- github.com/ydb-platform/ydb-go-genproto v0.0.0-20250911135631-b3beddd517d9 // 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.28.0 // indirect
- golang.org/x/net v0.46.0 // indirect
- golang.org/x/sys v0.37.0 // indirect
- golang.org/x/text v0.30.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
golang.org/x/tools/go/expect v0.1.0-deprecated // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda // indirect
- google.golang.org/grpc v1.76.0 // indirect
- google.golang.org/protobuf v1.36.10 // 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/LostImagin4tion/atlas v0.0.5
diff --git a/go.sum b/go.sum
index bfaf07d6dc..b5b7a0e5a1 100644
--- a/go.sum
+++ b/go.sum
@@ -1,10 +1,10 @@
-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/LostImagin4tion/atlas v0.0.5 h1:SoP7EqpVLCMNCWPIZovdwOQUeJcO8ZY5cDTG5VMuIQM=
+github.com/LostImagin4tion/atlas v0.0.5/go.mod h1:Rco1malutATQGeWEoYFzurfzIvs+galayoZ0+Pz4als=
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=
@@ -154,30 +154,30 @@ 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.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
-github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-github.com/ydb-platform/ydb-go-genproto v0.0.0-20250911135631-b3beddd517d9 h1:SKqSRP6/ocY2Z4twOqKEKxpmawVTHTvQiom7hrU6jt0=
-github.com/ydb-platform/ydb-go-genproto v0.0.0-20250911135631-b3beddd517d9/go.mod h1:Er+FePu1dNUieD+XTMDduGpQuCPssK5Q4BjF+IIXJ3I=
-github.com/ydb-platform/ydb-go-sdk/v3 v3.118.0 h1:wLnWJ29yzYdVds3WFRgkzij/2li9dknyRBO7B+reJfY=
-github.com/ydb-platform/ydb-go-sdk/v3 v3.118.0/go.mod h1:UEMMk+JMunUveo2j+zlJEJ5I7ntf2+MbimciVNJYnNs=
+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/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.0 h1:KPnGV2diuX1A4/1zXLO1UWHJokWC8yICzEfjdkSUWKo=
+github.com/ydb-platform/ydb-go-sdk/v3 v3.125.0/go.mod h1:/LjMxb/rXmoGAAnImoqAFIlhO5ampHacbvDetQitCk4=
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.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
-go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
-go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
-go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
-go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
-go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
-go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
-go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
-go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
-go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
-go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
-go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
+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=
@@ -187,8 +187,8 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL
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.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
-golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
+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=
@@ -198,16 +198,16 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
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.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4=
-golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210=
+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.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
-golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
+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=
@@ -217,19 +217,19 @@ golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7w
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.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ=
-golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
+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.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
-golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
+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.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
-golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
+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=
@@ -244,8 +244,8 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA
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-20251029180050-ab9386a59fda h1:i/Q+bfisr7gq6feoJnS/DlpdwEL4ihp41fvRiM3Ork0=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
+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=
@@ -254,8 +254,8 @@ google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTp
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.76.0 h1:UnVkv1+uMLYXoIz6o7chp59WfQUYA2ex/BXQ9rHZu7A=
-google.golang.org/grpc v1.76.0/go.mod h1:Ju12QI8M6iQJtbcsV+awF5a4hfJMLi4X0JLo94ULZ6c=
+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=
@@ -269,8 +269,8 @@ 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.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
-google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
+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=
From b1af6b13a92dec825ebe95f064d64ab89b02ff20 Mon Sep 17 00:00:00 2001
From: Egor Danilov <63148392+LostImagin4tion@users.noreply.github.com>
Date: Wed, 4 Feb 2026 18:46:21 +0300
Subject: [PATCH 07/14] all: added support for ydb in codegen (#10)
---
dialect/sql/schema/atlas.go | 80 +-
dialect/sql/schema/ydb.go | 40 +-
dialect/sql/sqlgraph/graph.go | 310 ++-
dialect/sql/sqlgraph/retry.go | 57 +
dialect/ydb/driver.go | 18 +-
dialect/ydb/retry.go | 110 ++
entc/gen/feature.go | 10 +
entc/gen/storage.go | 3 +-
entc/gen/template/builder/delete.tmpl | 5 +
entc/gen/template/dialect/sql/delete.tmpl | 16 +
.../dialect/sql/feature/retryoptions.tmpl | 155 ++
entc/gen/template/dialect/sql/open.tmpl | 10 +-
entc/integration/cascadelete/ent/client.go | 13 +-
entc/integration/config/ent/client.go | 13 +-
entc/integration/customid/ent/client.go | 13 +-
entc/integration/edgefield/ent/client.go | 13 +-
entc/integration/edgeschema/ent/client.go | 13 +-
entc/integration/ent/api_create.go | 30 +-
entc/integration/ent/api_delete.go | 13 +-
entc/integration/ent/api_query.go | 20 +-
entc/integration/ent/api_update.go | 32 +-
entc/integration/ent/builder_create.go | 30 +-
entc/integration/ent/builder_delete.go | 13 +-
entc/integration/ent/builder_query.go | 20 +-
entc/integration/ent/builder_update.go | 32 +-
entc/integration/ent/card_create.go | 30 +-
entc/integration/ent/card_delete.go | 13 +-
entc/integration/ent/card_query.go | 10 +
entc/integration/ent/card_update.go | 32 +-
entc/integration/ent/client.go | 13 +-
entc/integration/ent/comment_create.go | 30 +-
entc/integration/ent/comment_delete.go | 13 +-
entc/integration/ent/comment_query.go | 20 +-
entc/integration/ent/comment_update.go | 32 +-
entc/integration/ent/exvaluescan_create.go | 30 +-
entc/integration/ent/exvaluescan_delete.go | 13 +-
entc/integration/ent/exvaluescan_query.go | 20 +-
entc/integration/ent/exvaluescan_update.go | 32 +-
entc/integration/ent/fieldtype_create.go | 30 +-
entc/integration/ent/fieldtype_delete.go | 13 +-
entc/integration/ent/fieldtype_query.go | 22 +-
entc/integration/ent/fieldtype_update.go | 32 +-
entc/integration/ent/file_create.go | 30 +-
entc/integration/ent/file_delete.go | 13 +-
entc/integration/ent/file_query.go | 10 +
entc/integration/ent/file_update.go | 32 +-
entc/integration/ent/filetype_create.go | 30 +-
entc/integration/ent/filetype_delete.go | 13 +-
entc/integration/ent/filetype_query.go | 10 +
entc/integration/ent/filetype_update.go | 32 +-
entc/integration/ent/generate.go | 2 +-
entc/integration/ent/goods_create.go | 30 +-
entc/integration/ent/goods_delete.go | 13 +-
entc/integration/ent/goods_query.go | 20 +-
entc/integration/ent/goods_update.go | 32 +-
entc/integration/ent/group_create.go | 30 +-
entc/integration/ent/group_delete.go | 13 +-
entc/integration/ent/group_query.go | 10 +
entc/integration/ent/group_update.go | 32 +-
entc/integration/ent/groupinfo_create.go | 30 +-
entc/integration/ent/groupinfo_delete.go | 13 +-
entc/integration/ent/groupinfo_query.go | 10 +
entc/integration/ent/groupinfo_update.go | 32 +-
entc/integration/ent/item_create.go | 30 +-
entc/integration/ent/item_delete.go | 13 +-
entc/integration/ent/item_query.go | 20 +-
entc/integration/ent/item_update.go | 32 +-
entc/integration/ent/license_create.go | 30 +-
entc/integration/ent/license_delete.go | 13 +-
entc/integration/ent/license_query.go | 20 +-
entc/integration/ent/license_update.go | 32 +-
entc/integration/ent/node_create.go | 30 +-
entc/integration/ent/node_delete.go | 13 +-
entc/integration/ent/node_query.go | 26 +-
entc/integration/ent/node_update.go | 32 +-
entc/integration/ent/pc_create.go | 30 +-
entc/integration/ent/pc_delete.go | 13 +-
entc/integration/ent/pc_query.go | 20 +-
entc/integration/ent/pc_update.go | 32 +-
entc/integration/ent/pet_create.go | 30 +-
entc/integration/ent/pet_delete.go | 13 +-
entc/integration/ent/pet_query.go | 26 +-
entc/integration/ent/pet_update.go | 32 +-
entc/integration/ent/spec_create.go | 30 +-
entc/integration/ent/spec_delete.go | 13 +-
entc/integration/ent/spec_query.go | 10 +
entc/integration/ent/spec_update.go | 32 +-
entc/integration/ent/task_create.go | 30 +-
entc/integration/ent/task_delete.go | 13 +-
entc/integration/ent/task_query.go | 20 +-
entc/integration/ent/task_update.go | 32 +-
entc/integration/ent/user_create.go | 30 +-
entc/integration/ent/user_delete.go | 13 +-
entc/integration/ent/user_query.go | 10 +
entc/integration/ent/user_update.go | 32 +-
entc/integration/go.mod | 4 +-
entc/integration/go.sum | 8 +-
entc/integration/hooks/ent/client.go | 13 +-
entc/integration/idtype/ent/client.go | 13 +-
entc/integration/json/ent/client.go | 13 +-
entc/integration/migrate/entv1/client.go | 13 +-
entc/integration/migrate/entv2/blog_create.go | 2 +-
entc/integration/migrate/entv2/client.go | 13 +-
entc/integration/migrate/versioned/client.go | 13 +-
entc/integration/multischema/ent/client.go | 13 +-
.../multischema/versioned/client.go | 13 +-
entc/integration/privacy/ent/client.go | 13 +-
entc/integration/template/ent/client.go | 13 +-
examples/compositetypes/ent/client.go | 13 +-
examples/domaintypes/ent/client.go | 13 +-
examples/edgeindex/ent/client.go | 13 +-
examples/encryptfield/ent/client.go | 13 +-
examples/entcpkg/ent/client.go | 13 +-
examples/enumtypes/ent/client.go | 13 +-
examples/extensions/ent/client.go | 13 +-
examples/fs/ent/client.go | 13 +-
examples/functionalidx/ent/client.go | 13 +-
examples/go.mod | 4 +-
examples/go.sum | 8 +-
examples/jsonencode/ent/client.go | 13 +-
examples/m2m2types/ent/client.go | 13 +-
examples/m2mbidi/ent/client.go | 13 +-
examples/m2mrecur/ent/client.go | 13 +-
examples/migration/ent/client.go | 13 +-
examples/o2m2types/ent/client.go | 13 +-
examples/o2mrecur/ent/client.go | 13 +-
examples/o2o2types/ent/client.go | 13 +-
examples/o2obidi/ent/client.go | 13 +-
examples/o2orecur/ent/client.go | 13 +-
examples/privacyadmin/ent/client.go | 13 +-
examples/privacytenant/ent/client.go | 13 +-
examples/rls/ent/client.go | 13 +-
examples/start/ent/client.go | 13 +-
examples/traversal/ent/client.go | 13 +-
examples/triggers/ent/client.go | 13 +-
examples/version/ent/client.go | 13 +-
examples/viewcomposite/ent/client.go | 13 +-
examples/viewschema/ent/client.go | 13 +-
examples/ydb/README.md | 59 +
examples/ydb/ent/client.go | 704 +++++++
examples/ydb/ent/ent.go | 616 ++++++
examples/ydb/ent/entc.go | 31 +
examples/ydb/ent/enttest/enttest.go | 88 +
examples/ydb/ent/episode.go | 161 ++
examples/ydb/ent/episode/episode.go | 96 +
examples/ydb/ent/episode/where.go | 238 +++
examples/ydb/ent/episode_create.go | 271 +++
examples/ydb/ent/episode_delete.go | 101 +
examples/ydb/ent/episode_query.go | 620 ++++++
examples/ydb/ent/episode_update.go | 407 ++++
examples/ydb/ent/generate.go | 7 +
examples/ydb/ent/hook/hook.go | 227 +++
examples/ydb/ent/migrate/migrate.go | 68 +
examples/ydb/ent/migrate/schema.go | 92 +
examples/ydb/ent/mutation.go | 1724 +++++++++++++++++
examples/ydb/ent/predicate/predicate.go | 20 +
examples/ydb/ent/runtime.go | 38 +
examples/ydb/ent/runtime/runtime.go | 13 +
examples/ydb/ent/schema/episode.go | 47 +
examples/ydb/ent/schema/season.go | 49 +
examples/ydb/ent/schema/series.go | 44 +
examples/ydb/ent/season.go | 188 ++
examples/ydb/ent/season/season.go | 134 ++
examples/ydb/ent/season/where.go | 306 +++
examples/ydb/ent/season_create.go | 316 +++
examples/ydb/ent/season_delete.go | 101 +
examples/ydb/ent/season_query.go | 695 +++++++
examples/ydb/ent/season_update.go | 604 ++++++
examples/ydb/ent/series.go | 158 ++
examples/ydb/ent/series/series.go | 103 +
examples/ydb/ent/series/where.go | 293 +++
examples/ydb/ent/series_create.go | 286 +++
examples/ydb/ent/series_delete.go | 101 +
examples/ydb/ent/series_query.go | 620 ++++++
examples/ydb/ent/series_update.go | 507 +++++
examples/ydb/ent/tx.go | 220 +++
examples/ydb/example.go | 194 ++
go.mod | 4 +-
go.sum | 8 +-
179 files changed, 13143 insertions(+), 579 deletions(-)
create mode 100644 dialect/sql/sqlgraph/retry.go
create mode 100644 dialect/ydb/retry.go
create mode 100644 entc/gen/template/dialect/sql/feature/retryoptions.tmpl
create mode 100644 examples/ydb/README.md
create mode 100644 examples/ydb/ent/client.go
create mode 100644 examples/ydb/ent/ent.go
create mode 100644 examples/ydb/ent/entc.go
create mode 100644 examples/ydb/ent/enttest/enttest.go
create mode 100644 examples/ydb/ent/episode.go
create mode 100644 examples/ydb/ent/episode/episode.go
create mode 100644 examples/ydb/ent/episode/where.go
create mode 100644 examples/ydb/ent/episode_create.go
create mode 100644 examples/ydb/ent/episode_delete.go
create mode 100644 examples/ydb/ent/episode_query.go
create mode 100644 examples/ydb/ent/episode_update.go
create mode 100644 examples/ydb/ent/generate.go
create mode 100644 examples/ydb/ent/hook/hook.go
create mode 100644 examples/ydb/ent/migrate/migrate.go
create mode 100644 examples/ydb/ent/migrate/schema.go
create mode 100644 examples/ydb/ent/mutation.go
create mode 100644 examples/ydb/ent/predicate/predicate.go
create mode 100644 examples/ydb/ent/runtime.go
create mode 100644 examples/ydb/ent/runtime/runtime.go
create mode 100644 examples/ydb/ent/schema/episode.go
create mode 100644 examples/ydb/ent/schema/season.go
create mode 100644 examples/ydb/ent/schema/series.go
create mode 100644 examples/ydb/ent/season.go
create mode 100644 examples/ydb/ent/season/season.go
create mode 100644 examples/ydb/ent/season/where.go
create mode 100644 examples/ydb/ent/season_create.go
create mode 100644 examples/ydb/ent/season_delete.go
create mode 100644 examples/ydb/ent/season_query.go
create mode 100644 examples/ydb/ent/season_update.go
create mode 100644 examples/ydb/ent/series.go
create mode 100644 examples/ydb/ent/series/series.go
create mode 100644 examples/ydb/ent/series/where.go
create mode 100644 examples/ydb/ent/series_create.go
create mode 100644 examples/ydb/ent/series_delete.go
create mode 100644 examples/ydb/ent/series_query.go
create mode 100644 examples/ydb/ent/series_update.go
create mode 100644 examples/ydb/ent/tx.go
create mode 100644 examples/ydb/example.go
diff --git a/dialect/sql/schema/atlas.go b/dialect/sql/schema/atlas.go
index af72e56b83..d0ce2ff502 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.
diff --git a/dialect/sql/schema/ydb.go b/dialect/sql/schema/ydb.go
index 94b1a0a064..c37218ffc9 100644
--- a/dialect/sql/schema/ydb.go
+++ b/dialect/sql/schema/ydb.go
@@ -6,14 +6,13 @@ package schema
import (
"context"
- "database/sql"
"errors"
"fmt"
"strings"
"entgo.io/ent/dialect"
entsql "entgo.io/ent/dialect/sql"
- entdriver "entgo.io/ent/dialect/ydb"
+ entdrv "entgo.io/ent/dialect/ydb"
"entgo.io/ent/schema/field"
"ariga.io/atlas/sql/migrate"
@@ -34,8 +33,8 @@ func (d *YDB) init(ctx context.Context) error {
return nil // already initialized.
}
- rows := &sql.Rows{}
- if err := d.Driver.Query(ctx, "SELECT version()", nil, rows); err != nil {
+ 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()
@@ -69,9 +68,22 @@ func (d *YDB) tableExist(ctx context.Context, conn dialect.ExecQuerier, name str
// atOpen returns a custom Atlas migrate.Driver for YDB.
func (d *YDB) atOpen(conn dialect.ExecQuerier) (migrate.Driver, error) {
- ydbDriver, ok := conn.(*entdriver.YDBDriver)
- if !ok {
- return nil, fmt.Errorf("expected dialect/ydb.YDBDriver, but got %T", conn)
+ var ydbDriver *entdrv.YDBDriver
+
+ switch drv := conn.(type) {
+ case *entdrv.YDBDriver:
+ ydbDriver = drv
+ case *YDB:
+ if ydb, ok := drv.Driver.(*entdrv.YDBDriver); ok {
+ ydbDriver = ydb
+ }
+ }
+ if ydbDriver == nil {
+ if ydb, ok := d.Driver.(*entdrv.YDBDriver); ok {
+ ydbDriver = ydb
+ } else {
+ return nil, fmt.Errorf("expected dialect/ydb.YDBDriver, but got %T", conn)
+ }
}
return atlas.Open(
@@ -145,11 +157,11 @@ func (d *YDB) atTypeC(column1 *Column, column2 *schema.Column) error {
case field.TypeString:
typ = &schema.StringType{T: atlas.TypeUtf8}
case field.TypeJSON:
- typ = &schema.JSONType{T: atlas.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}
+ typ = &schema.UUIDType{T: atlas.TypeUUID}
case field.TypeEnum:
err = errors.New("ydb: Enum can't be used as column data type for tables")
case field.TypeOther:
@@ -186,7 +198,7 @@ func (d *YDB) atUniqueC(
index := schema.NewUniqueIndex(idxName).AddColumns(column2)
// Add YDB-specific attribute for GLOBAL SYNC index type.
- index.AddAttrs(&atlas.YDBIndexAttributes{Global: true, Sync: true})
+ index.AddAttrs(&atlas.IndexAttributes{Global: true, Sync: true})
table2.AddIndexes(index)
}
@@ -195,7 +207,11 @@ func (d *YDB) atUniqueC(
// 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 {
- column.Type.Type = atlas.SerialFromInt(intType)
+ serial, err := atlas.SerialFromInt(intType)
+ if err != nil {
+ panic(err)
+ }
+ column.Type.Type = serial
}
}
@@ -220,7 +236,7 @@ func (d *YDB) atIndex(
// Set YDB-specific index attributes.
// By default, use GLOBAL SYNC for consistency.
- idxType := &atlas.YDBIndexAttributes{Global: true, Sync: true}
+ idxType := &atlas.IndexAttributes{Global: true, Sync: true}
// Check for annotation overrides.
if index1.Annotation != nil {
diff --git a/dialect/sql/sqlgraph/graph.go b/dialect/sql/sqlgraph/graph.go
index c41c6b9ca0..6cb9d04a1c 100644
--- a/dialect/sql/sqlgraph/graph.go
+++ b/dialect/sql/sqlgraph/graph.go
@@ -261,18 +261,30 @@ func HasNeighbors(q *sql.Selector, s *Step) {
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]),
+
+ // YDB doesn't support correlated EXISTS subqueries.
+ // Use IN subquery instead for YDB dialect.
+ if q.Dialect() == dialect.YDB {
+ q.Where(
+ sql.In(
+ q.C(s.From.Column),
+ builder.Select(to.C(s.Edge.Columns[0])).From(to),
+ ),
+ )
+ } else {
+ 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]),
+ ),
),
- ),
- ),
- )
+ ),
+ )
+ }
}
}
@@ -297,6 +309,7 @@ func HasNeighborsWith(q *sql.Selector, s *Step, pred func(*sql.Selector)) {
pred(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)
// Avoid ambiguity in case both source
@@ -312,17 +325,28 @@ func HasNeighborsWith(q *sql.Selector, s *Step, pred func(*sql.Selector)) {
to.As(fmt.Sprintf("%s_edge_%d", s.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))
+
+ // YDB doesn't support correlated EXISTS subqueries.
+ // Use IN subquery instead for YDB dialect.
+ if q.Dialect() == dialect.YDB {
+ matches := builder.Select(to.C(s.To.Column)).From(to)
+ matches.WithContext(q.Context())
+ pred(matches)
+ q.Where(sql.In(q.C(s.Edge.Columns[0]), matches))
+ } else {
+ 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)
// Avoid ambiguity in case both source
@@ -338,17 +362,27 @@ func HasNeighborsWith(q *sql.Selector, s *Step, pred func(*sql.Selector)) {
to.As(fmt.Sprintf("%s_edge_%d", s.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))
+
+ // YDB doesn't support correlated EXISTS subqueries.
+ // Use IN subquery instead for YDB dialect.
+ if q.Dialect() == dialect.YDB {
+ matches := builder.Select(to.C(s.Edge.Columns[0])).From(to)
+ matches.WithContext(q.Context())
+ pred(matches)
+ q.Where(sql.In(q.C(s.From.Column), matches))
+ } else {
+ 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))
+ }
}
}
@@ -711,6 +745,8 @@ type (
// }
//
OnConflict []sql.ConflictOption
+
+ RetryConfig RetryConfig
}
// BatchCreateSpec holds the information for creating
@@ -728,6 +764,8 @@ type (
// }
//
OnConflict []sql.ConflictOption
+
+ RetryConfig RetryConfig
}
)
@@ -748,16 +786,30 @@ 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)
+ op := 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)
+ }
+ return execWithRetryTx(ctx, drv, op, spec.RetryConfig.Options)
}
// 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)
+ op := 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)
+ }
+ return execWithRetryTx(ctx, drv, op, spec.RetryConfig.Options)
+}
+
+// execWithRetryTx executes the operation with retry if available, otherwise executes directly.
+func execWithRetryTx(ctx context.Context, drv dialect.Driver, op func(context.Context, dialect.Driver) error, opts []any) error {
+ if retry := getRetryExecutor(drv); retry != nil {
+ return retry.DoTx(ctx, op, opts...)
+ }
+ return op(ctx, drv)
}
type (
@@ -785,6 +837,8 @@ type (
ScanValues func(columns []string) ([]any, error)
Assign func(columns []string, values []any) error
+
+ RetryConfig RetryConfig
}
)
@@ -840,23 +894,47 @@ 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
+ op := 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()
}
- 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)
+ if retry := getRetryExecutor(drv); retry != nil {
+ return retry.DoTx(ctx, op, spec.RetryConfig.Options...)
}
- return tx.Commit()
+ return op(ctx, drv)
}
// 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 retry := getRetryExecutor(drv); retry != nil {
+ if err := retry.DoTx(ctx, op, spec.RetryConfig.Options...); err != nil {
+ return 0, err
+ }
+ return affected, nil
+ }
+ if err := op(ctx, drv); err != nil {
+ return 0, err
+ }
+ return affected, nil
}
// NotFoundError returns when trying to update an
@@ -873,8 +951,9 @@ func (e *NotFoundError) Error() string {
// 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 RetryConfig
}
// NewDeleteSpec creates a new node deletion spec.
@@ -884,25 +963,39 @@ 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)
+ var affected int
+ op := func(ctx context.Context, d dialect.Driver) 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 := d.Exec(ctx, query, args, &res); err != nil {
+ return err
+ }
+ n, err := res.RowsAffected()
+ if err != nil {
+ return err
+ }
+ affected = int(n)
+ return nil
}
- 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
+ if retry := getRetryExecutor(drv); retry != nil {
+ if err := retry.DoTx(ctx, op, spec.RetryConfig.Options...); err != nil {
+ return 0, err
+ }
+ return affected, nil
}
- affected, err := res.RowsAffected()
- if err != nil {
+ if err := op(ctx, drv); err != nil {
return 0, err
}
- return int(affected), nil
+ return affected, nil
}
// QuerySpec holds the information for querying
@@ -920,6 +1013,8 @@ type QuerySpec struct {
ScanValues func(columns []string) ([]any, error)
Assign func(columns []string, values []any) error
+
+ RetryConfig RetryConfig
}
// NewQuerySpec creates a new node query spec.
@@ -935,16 +1030,40 @@ 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)
+ op := 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)
+ }
+ if retry := getRetryExecutor(drv); retry != nil {
+ return retry.Do(ctx, op, spec.RetryConfig.Options...)
+ }
+ return op(ctx, drv)
}
// 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 retry := getRetryExecutor(drv); retry != nil {
+ if err := retry.Do(ctx, op, spec.RetryConfig.Options...); err != nil {
+ return 0, err
+ }
+ return count, nil
+ }
+ if err := op(ctx, drv); err != nil {
+ return 0, err
+ }
+ return count, nil
}
// EdgeQuerySpec holds the information for querying
@@ -1376,18 +1495,45 @@ 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)).
+ Where(sql.EQ(u.Node.ID.Column, u.Node.ID.Value))
+ u.Predicate(selector)
+
+ var query string
+ var args []any
+
+ // YDB doesn't fully support EXISTS in all contexts.
+ // Use COUNT(*) > 0 approach instead for better compatibility.
+ if selector.Dialect() == dialect.YDB {
+ selector.Count("*")
+ query, args = selector.Query()
+ } else {
+ 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
+
+ var found bool
+ if selector.Dialect() == dialect.YDB {
+ count, err := sql.ScanInt(rows)
+ if err != nil {
+ return err
+ }
+ found = count > 0
+ } else {
+ var err error
+ found, err = sql.ScanBool(rows)
+ if err != nil {
+ return err
+ }
}
+
if !found {
return &NotFoundError{table: u.Node.Table, id: u.Node.ID.Value}
}
@@ -1728,7 +1874,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()
@@ -1763,7 +1910,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())
}
}
diff --git a/dialect/sql/sqlgraph/retry.go b/dialect/sql/sqlgraph/retry.go
new file mode 100644
index 0000000000..449e4dffbd
--- /dev/null
+++ b/dialect/sql/sqlgraph/retry.go
@@ -0,0 +1,57 @@
+// 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 sqlgraph
+
+import (
+ "context"
+
+ "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
+}
+
+// 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.
+func getRetryExecutor(drv dialect.Driver) RetryExecutor {
+ if reg, ok := drv.(RetryExecutorGetter); ok {
+ return reg.RetryExecutor()
+ }
+ return 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/ydb/driver.go b/dialect/ydb/driver.go
index 14c7e38418..1a8a6f12df 100644
--- a/dialect/ydb/driver.go
+++ b/dialect/ydb/driver.go
@@ -10,6 +10,7 @@ import (
"entgo.io/ent/dialect"
entSql "entgo.io/ent/dialect/sql"
+ "entgo.io/ent/dialect/sql/sqlgraph"
ydb "github.com/ydb-platform/ydb-go-sdk/v3"
)
@@ -17,9 +18,12 @@ import (
type YDBDriver struct {
*entSql.Driver
- nativeDriver *ydb.Driver
+ nativeDriver *ydb.Driver
+ retryExecutor *RetryExecutor
}
+var _ sqlgraph.RetryExecutorGetter = (*YDBDriver)(nil)
+
func Open(ctx context.Context, dsn string) (*YDBDriver, error) {
nativeDriver, err := ydb.Open(ctx, dsn)
if err != nil {
@@ -30,6 +34,7 @@ func Open(ctx context.Context, dsn string) (*YDBDriver, error) {
nativeDriver,
ydb.WithAutoDeclare(),
ydb.WithTablePathPrefix(nativeDriver.Name()),
+ ydb.WithQueryService(true),
)
if err != nil {
return nil, err
@@ -38,11 +43,18 @@ func Open(ctx context.Context, dsn string) (*YDBDriver, error) {
dbSQLDriver := sql.OpenDB(conn)
return &YDBDriver{
- Driver: entSql.OpenDB(dialect.YDB, dbSQLDriver),
- nativeDriver: nativeDriver,
+ Driver: entSql.OpenDB(dialect.YDB, dbSQLDriver),
+ nativeDriver: nativeDriver,
+ retryExecutor: NewRetryExecutor(dbSQLDriver),
}, nil
}
func (y *YDBDriver) NativeDriver() *ydb.Driver {
return y.nativeDriver
}
+
+// RetryExecutor returns the RetryExecutor for this driver.
+// This allows sqlgraph to automatically wrap operations with YDB retry logic.
+func (y *YDBDriver) RetryExecutor() sqlgraph.RetryExecutor {
+ return y.retryExecutor
+}
diff --git a/dialect/ydb/retry.go b/dialect/ydb/retry.go
new file mode 100644
index 0000000000..dc0dde85e0
--- /dev/null
+++ b/dialect/ydb/retry.go
@@ -0,0 +1,110 @@
+// 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 ydb
+
+import (
+ "context"
+ "database/sql"
+
+ "entgo.io/ent/dialect"
+ entSql "entgo.io/ent/dialect/sql"
+ "github.com/ydb-platform/ydb-go-sdk/v3/retry"
+)
+
+// RetryExecutor implements sqlgraph.RetryExecutor for YDB
+type RetryExecutor struct {
+ db *sql.DB
+}
+
+// NewRetryExecutor creates a new RetryExecutor with the given database connection
+func NewRetryExecutor(db *sql.DB) *RetryExecutor {
+ return &RetryExecutor{db: 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 *RetryExecutor) 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, NewRetryDriver(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 *RetryExecutor) 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
+}
+
+// RetryDriver is designed for use only in sqlgraph,
+// specifically - in retry.DoTx callbacks
+type RetryDriver struct {
+ entSql.Conn
+}
+
+var _ dialect.Driver = (*RetryDriver)(nil)
+
+// NewTxRetryDriver creates a new RetryDriver from a transaction.
+func NewTxRetryDriver(tx *sql.Tx) *RetryDriver {
+ return &RetryDriver{
+ Conn: entSql.Conn{ExecQuerier: tx},
+ }
+}
+
+// NewRetryDriver creates a new RetryDriver from a database connection.
+func NewRetryDriver(conn *sql.Conn) *RetryDriver {
+ return &RetryDriver{
+ Conn: entSql.Conn{ExecQuerier: conn},
+ }
+}
+
+// sqlgraph creates nested transactions in several methods.
+// But YDB doesnt support nested transactions.
+// Therefore, this methods returns no-op tx
+func (d *RetryDriver) 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 *RetryDriver) Close() error {
+ return nil
+}
+
+// Dialect returns the YDB dialect name.
+func (d *RetryDriver) Dialect() string {
+ return dialect.YDB
+}
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..6fcde470fa 100644
--- a/entc/gen/storage.go
+++ b/entc/gen/storage.go
@@ -54,12 +54,13 @@ 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",
"entgo.io/ent/dialect/sql/sqlgraph",
"entgo.io/ent/dialect/sql/sqljson",
+ "entgo.io/ent/dialect/ydb",
"entgo.io/ent/schema/field",
},
SchemaMode: Unique | Indexes | Cascade | Migrate,
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..fa066279da
--- /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 sqlgraph.RetryConfig
+ {{- end }}
+{{- end }}
+
+{{/* Additional fields for the create_bulk builder. */}}
+{{ define "dialect/sql/create_bulk/fields/additional/retryoptions" -}}
+ {{- if $.FeatureEnabled "sql/retryoptions" }}
+ retryConfig sqlgraph.RetryConfig
+ {{- end }}
+{{- end }}
+
+{{/* Additional fields for the update builder. */}}
+{{ define "dialect/sql/update/fields/additional/retryoptions" -}}
+ {{- if $.FeatureEnabled "sql/retryoptions" }}
+ retryConfig sqlgraph.RetryConfig
+ {{- end }}
+{{- end }}
+
+{{/* Additional fields for the query builder. */}}
+{{ define "dialect/sql/query/fields/additional/retryoptions" -}}
+ {{- if $.FeatureEnabled "sql/retryoptions" }}
+ retryConfig sqlgraph.RetryConfig
+ {{- end }}
+{{- end }}
+
+{{/* Additional fields for the delete builder. */}}
+{{ define "dialect/sql/delete/fields/additional/retryoptions" -}}
+ {{- if $.FeatureEnabled "sql/retryoptions" }}
+ retryConfig sqlgraph.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/open.tmpl b/entc/gen/template/dialect/sql/open.tmpl
index d64b2417be..9be135d5b2 100644
--- a/entc/gen/template/dialect/sql/open.tmpl
+++ b/entc/gen/template/dialect/sql/open.tmpl
@@ -7,7 +7,15 @@ in the LICENSE file in the root directory of this source tree.
{{/* gotype: entgo.io/ent/entc/gen.Graph */}}
{{ define "dialect/sql/client/open" }}
- drv, err := sql.Open(driverName, dataSourceName)
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/entc/integration/cascadelete/ent/client.go b/entc/integration/cascadelete/ent/client.go
index 1d4ef1f1e7..554ee80e20 100644
--- a/entc/integration/cascadelete/ent/client.go
+++ b/entc/integration/cascadelete/ent/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/cascadelete/ent/comment"
"entgo.io/ent/entc/integration/cascadelete/ent/post"
"entgo.io/ent/entc/integration/cascadelete/ent/user"
@@ -112,8 +113,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/entc/integration/config/ent/client.go b/entc/integration/config/ent/client.go
index 53fdadb55a..1b9dee98cb 100644
--- a/entc/integration/config/ent/client.go
+++ b/entc/integration/config/ent/client.go
@@ -18,6 +18,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/config/ent/user"
)
@@ -103,8 +104,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/entc/integration/customid/ent/client.go b/entc/integration/customid/ent/client.go
index af08dc9747..85427b4f00 100644
--- a/entc/integration/customid/ent/client.go
+++ b/entc/integration/customid/ent/client.go
@@ -23,6 +23,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/customid/ent/account"
"entgo.io/ent/entc/integration/customid/ent/blob"
"entgo.io/ent/entc/integration/customid/ent/bloblink"
@@ -172,8 +173,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/entc/integration/edgefield/ent/client.go b/entc/integration/edgefield/ent/client.go
index ca24675669..eaf9bcb348 100644
--- a/entc/integration/edgefield/ent/client.go
+++ b/entc/integration/edgefield/ent/client.go
@@ -20,6 +20,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/edgefield/ent/car"
"entgo.io/ent/entc/integration/edgefield/ent/card"
"entgo.io/ent/entc/integration/edgefield/ent/info"
@@ -137,8 +138,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/entc/integration/edgeschema/ent/client.go b/entc/integration/edgeschema/ent/client.go
index 0d084d1535..3a8ad32449 100644
--- a/entc/integration/edgeschema/ent/client.go
+++ b/entc/integration/edgeschema/ent/client.go
@@ -20,6 +20,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/edgeschema/ent/attachedfile"
"entgo.io/ent/entc/integration/edgeschema/ent/file"
"entgo.io/ent/entc/integration/edgeschema/ent/friendship"
@@ -169,8 +170,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/entc/integration/ent/api_create.go b/entc/integration/ent/api_create.go
index ec60346db8..11995cb813 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 sqlgraph.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 sqlgraph.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..ea896eca93 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 sqlgraph.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..256d3f8281 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 sqlgraph.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..ad788a6f45 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 sqlgraph.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,6 +88,7 @@ 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 {
err = &NotFoundError{api.Label}
@@ -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 sqlgraph.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,6 +196,7 @@ 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
diff --git a/entc/integration/ent/builder_create.go b/entc/integration/ent/builder_create.go
index bc698496b2..ce42a6c5c8 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 sqlgraph.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 sqlgraph.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..e2df610c9b 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 sqlgraph.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..111b69a9d8 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 sqlgraph.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..b543367ef3 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 sqlgraph.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,6 +88,7 @@ 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 {
err = &NotFoundError{builder.Label}
@@ -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 sqlgraph.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,6 +196,7 @@ 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
diff --git a/entc/integration/ent/card_create.go b/entc/integration/ent/card_create.go
index 793ccc994c..eb559b8334 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 sqlgraph.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 sqlgraph.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..d6479ec76d 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 sqlgraph.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..b15621ff4b 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 sqlgraph.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..679c383abf 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 sqlgraph.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,6 +310,7 @@ 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 {
err = &NotFoundError{card.Label}
@@ -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 sqlgraph.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,6 +637,7 @@ 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
diff --git a/entc/integration/ent/client.go b/entc/integration/ent/client.go
index c848a9fe37..199db87d67 100644
--- a/entc/integration/ent/client.go
+++ b/entc/integration/ent/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/ent/api"
"entgo.io/ent/entc/integration/ent/builder"
"entgo.io/ent/entc/integration/ent/card"
@@ -179,8 +180,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ 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..d06f067950 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 sqlgraph.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 sqlgraph.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..f4f2270eb2 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 sqlgraph.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..166542f3a2 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 sqlgraph.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..acc785dedc 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 sqlgraph.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,6 +257,7 @@ 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 {
err = &NotFoundError{comment.Label}
@@ -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 sqlgraph.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,6 +533,7 @@ 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
diff --git a/entc/integration/ent/exvaluescan_create.go b/entc/integration/ent/exvaluescan_create.go
index 55fb92073f..f3137aa574 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 sqlgraph.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 sqlgraph.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..3a6556e16e 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 sqlgraph.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..65590152e2 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 sqlgraph.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..4e61748b2f 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 sqlgraph.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,6 +245,7 @@ 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 {
err = &NotFoundError{exvaluescan.Label}
@@ -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 sqlgraph.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,6 +508,7 @@ 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
diff --git a/entc/integration/ent/fieldtype_create.go b/entc/integration/ent/fieldtype_create.go
index 5b4f8776e9..dcba23b626 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 sqlgraph.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 sqlgraph.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..0dd3867853 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 sqlgraph.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..ac8b169052 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 sqlgraph.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..81890a7dd9 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 sqlgraph.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,6 +1926,7 @@ 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 {
err = &NotFoundError{fieldtype.Label}
@@ -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 sqlgraph.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,6 +3865,7 @@ 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
diff --git a/entc/integration/ent/file_create.go b/entc/integration/ent/file_create.go
index 6130182028..6b7c44fcc8 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 sqlgraph.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 sqlgraph.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..7af494bf69 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 sqlgraph.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..ac61788e95 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 sqlgraph.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..da45d1c6b5 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 sqlgraph.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,6 +519,7 @@ 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 {
err = &NotFoundError{file.Label}
@@ -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 sqlgraph.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,6 +1054,7 @@ 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
diff --git a/entc/integration/ent/filetype_create.go b/entc/integration/ent/filetype_create.go
index 8b7923bc37..04bc53ab60 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 sqlgraph.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 sqlgraph.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..a95d2f4df1 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 sqlgraph.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..3823927bd2 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 sqlgraph.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..10cf3c1996 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 sqlgraph.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,6 +239,7 @@ 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 {
err = &NotFoundError{filetype.Label}
@@ -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 sqlgraph.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,6 +497,7 @@ 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
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..ce57d59b77 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 sqlgraph.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 sqlgraph.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..f9e49134df 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 sqlgraph.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..c28b06688d 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 sqlgraph.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..37732b6254 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 sqlgraph.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,6 +88,7 @@ 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 {
err = &NotFoundError{goods.Label}
@@ -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 sqlgraph.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,6 +196,7 @@ 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
diff --git a/entc/integration/ent/group_create.go b/entc/integration/ent/group_create.go
index 5b5506a68c..8d2be28c49 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 sqlgraph.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 sqlgraph.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..353ed4e359 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 sqlgraph.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..99c333cd9c 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 sqlgraph.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..1fb546a0c2 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 sqlgraph.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,6 +520,7 @@ 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 {
err = &NotFoundError{group.Label}
@@ -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 sqlgraph.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,6 +1056,7 @@ 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
diff --git a/entc/integration/ent/groupinfo_create.go b/entc/integration/ent/groupinfo_create.go
index ede6d1706a..8162668e19 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 sqlgraph.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 sqlgraph.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..9be9235d12 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 sqlgraph.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..16bc6bc9b3 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 sqlgraph.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..d464deded5 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 sqlgraph.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,6 +214,7 @@ 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 {
err = &NotFoundError{groupinfo.Label}
@@ -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 sqlgraph.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,6 +447,7 @@ 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
diff --git a/entc/integration/ent/item_create.go b/entc/integration/ent/item_create.go
index 07ab7e886f..b5a7dcd441 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 sqlgraph.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 sqlgraph.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..2fc36cc402 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 sqlgraph.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..55761a6193 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 sqlgraph.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..80c3fcafb0 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 sqlgraph.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,6 +127,7 @@ 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 {
err = &NotFoundError{item.Label}
@@ -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 sqlgraph.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,6 +274,7 @@ 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
diff --git a/entc/integration/ent/license_create.go b/entc/integration/ent/license_create.go
index be85871465..82a8a5f50b 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 sqlgraph.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 sqlgraph.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..deb737343e 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 sqlgraph.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..b6488048e7 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 sqlgraph.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..85551abd7b 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 sqlgraph.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,6 +107,7 @@ 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 {
err = &NotFoundError{license.Label}
@@ -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 sqlgraph.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,6 +233,7 @@ 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
diff --git a/entc/integration/ent/node_create.go b/entc/integration/ent/node_create.go
index e1e912644f..cd1d4f23b4 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 sqlgraph.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 sqlgraph.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..dee9b0ba35 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 sqlgraph.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..c39f0b82a2 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 sqlgraph.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..0f22c31517 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 sqlgraph.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,6 +260,7 @@ 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 {
err = &NotFoundError{node.Label}
@@ -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 sqlgraph.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,6 +539,7 @@ 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
diff --git a/entc/integration/ent/pc_create.go b/entc/integration/ent/pc_create.go
index dcf1a5cdbd..6285b1e040 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 sqlgraph.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 sqlgraph.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..6b90014579 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 sqlgraph.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..3ab0ef4610 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 sqlgraph.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..728a59a72d 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 sqlgraph.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,6 +88,7 @@ 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 {
err = &NotFoundError{pc.Label}
@@ -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 sqlgraph.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,6 +196,7 @@ 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
diff --git a/entc/integration/ent/pet_create.go b/entc/integration/ent/pet_create.go
index d2164af6eb..208c2e4a75 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 sqlgraph.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 sqlgraph.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..8cf51235a2 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 sqlgraph.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..b751e89919 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 sqlgraph.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..86d42e92e2 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 sqlgraph.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,6 +338,7 @@ 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 {
err = &NotFoundError{pet.Label}
@@ -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 sqlgraph.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,6 +693,7 @@ 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
diff --git a/entc/integration/ent/spec_create.go b/entc/integration/ent/spec_create.go
index 0d561c1d0b..354231971f 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 sqlgraph.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 sqlgraph.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..4fd2627533 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 sqlgraph.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..50b972e1cf 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 sqlgraph.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..d0ce335f44 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 sqlgraph.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,6 +170,7 @@ 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 {
err = &NotFoundError{spec.Label}
@@ -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 sqlgraph.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,6 +359,7 @@ 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
diff --git a/entc/integration/ent/task_create.go b/entc/integration/ent/task_create.go
index e99ff466c7..d06d1ac267 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 sqlgraph.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 sqlgraph.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..ce2900fac8 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 sqlgraph.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..bdd6ec5540 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 sqlgraph.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..88d8a2b4e2 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 sqlgraph.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,6 +293,7 @@ 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 {
err = &NotFoundError{enttask.Label}
@@ -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 sqlgraph.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,6 +605,7 @@ 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
diff --git a/entc/integration/ent/user_create.go b/entc/integration/ent/user_create.go
index 098bc1e6e8..e9dcb84db3 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 sqlgraph.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 sqlgraph.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..f995536f25 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 sqlgraph.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..0927a941b3 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 sqlgraph.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..6620c6344b 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 sqlgraph.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,6 +1195,7 @@ 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 {
err = &NotFoundError{user.Label}
@@ -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 sqlgraph.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,6 +2406,7 @@ 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
diff --git a/entc/integration/go.mod b/entc/integration/go.mod
index 1e73a8cb46..6ac5a6f8b2 100644
--- a/entc/integration/go.mod
+++ b/entc/integration/go.mod
@@ -37,7 +37,7 @@ require (
github.com/rogpeppe/go-internal v1.11.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.0 // 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.30.0 // indirect
@@ -50,4 +50,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
-replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.5
+replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.18
diff --git a/entc/integration/go.sum b/entc/integration/go.sum
index 7a58fa2697..350fb9eb87 100644
--- a/entc/integration/go.sum
+++ b/entc/integration/go.sum
@@ -5,8 +5,8 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
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/LostImagin4tion/atlas v0.0.5 h1:SoP7EqpVLCMNCWPIZovdwOQUeJcO8ZY5cDTG5VMuIQM=
-github.com/LostImagin4tion/atlas v0.0.5/go.mod h1:Rco1malutATQGeWEoYFzurfzIvs+galayoZ0+Pz4als=
+github.com/LostImagin4tion/atlas v0.0.18 h1:RrLLU6zEXuRZAih3slblKFZ/lPLUDZ+wrHaTrxILqrA=
+github.com/LostImagin4tion/atlas v0.0.18/go.mod h1:Rco1malutATQGeWEoYFzurfzIvs+galayoZ0+Pz4als=
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=
@@ -123,8 +123,8 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
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.0 h1:KPnGV2diuX1A4/1zXLO1UWHJokWC8yICzEfjdkSUWKo=
-github.com/ydb-platform/ydb-go-sdk/v3 v3.125.0/go.mod h1:/LjMxb/rXmoGAAnImoqAFIlhO5ampHacbvDetQitCk4=
+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=
diff --git a/entc/integration/hooks/ent/client.go b/entc/integration/hooks/ent/client.go
index a8e9f11de8..d963edd315 100644
--- a/entc/integration/hooks/ent/client.go
+++ b/entc/integration/hooks/ent/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/hooks/ent/card"
"entgo.io/ent/entc/integration/hooks/ent/pet"
"entgo.io/ent/entc/integration/hooks/ent/user"
@@ -112,8 +113,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/entc/integration/idtype/ent/client.go b/entc/integration/idtype/ent/client.go
index 18cfcf6566..93a3e0181e 100644
--- a/entc/integration/idtype/ent/client.go
+++ b/entc/integration/idtype/ent/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/idtype/ent/user"
)
@@ -104,8 +105,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/entc/integration/json/ent/client.go b/entc/integration/json/ent/client.go
index 36ba6679f9..a9e54fe3c7 100644
--- a/entc/integration/json/ent/client.go
+++ b/entc/integration/json/ent/client.go
@@ -18,6 +18,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/json/ent/user"
)
@@ -103,8 +104,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/entc/integration/migrate/entv1/client.go b/entc/integration/migrate/entv1/client.go
index d3cae2b84f..7e75175637 100644
--- a/entc/integration/migrate/entv1/client.go
+++ b/entc/integration/migrate/entv1/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/migrate/entv1/car"
"entgo.io/ent/entc/integration/migrate/entv1/conversion"
"entgo.io/ent/entc/integration/migrate/entv1/customtype"
@@ -116,8 +117,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, 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/client.go b/entc/integration/migrate/entv2/client.go
index ed15ab6937..2c1b3777c9 100644
--- a/entc/integration/migrate/entv2/client.go
+++ b/entc/integration/migrate/entv2/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/migrate/entv2/blog"
"entgo.io/ent/entc/integration/migrate/entv2/car"
"entgo.io/ent/entc/integration/migrate/entv2/conversion"
@@ -136,8 +137,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/entc/integration/migrate/versioned/client.go b/entc/integration/migrate/versioned/client.go
index d745e43d82..d5afb29b91 100644
--- a/entc/integration/migrate/versioned/client.go
+++ b/entc/integration/migrate/versioned/client.go
@@ -18,6 +18,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/migrate/versioned/group"
"entgo.io/ent/entc/integration/migrate/versioned/user"
)
@@ -107,8 +108,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/entc/integration/multischema/ent/client.go b/entc/integration/multischema/ent/client.go
index 50c593dd0b..8e1bcbc8ab 100644
--- a/entc/integration/multischema/ent/client.go
+++ b/entc/integration/multischema/ent/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/multischema/ent/friendship"
"entgo.io/ent/entc/integration/multischema/ent/group"
"entgo.io/ent/entc/integration/multischema/ent/parent"
@@ -128,8 +129,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/entc/integration/multischema/versioned/client.go b/entc/integration/multischema/versioned/client.go
index 95f3b4cbc3..4fc86d49ae 100644
--- a/entc/integration/multischema/versioned/client.go
+++ b/entc/integration/multischema/versioned/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/multischema/versioned/friendship"
"entgo.io/ent/entc/integration/multischema/versioned/group"
"entgo.io/ent/entc/integration/multischema/versioned/pet"
@@ -121,8 +122,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/entc/integration/privacy/ent/client.go b/entc/integration/privacy/ent/client.go
index 47091c9b3a..cac43ddb40 100644
--- a/entc/integration/privacy/ent/client.go
+++ b/entc/integration/privacy/ent/client.go
@@ -21,6 +21,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/privacy/ent/task"
"entgo.io/ent/entc/integration/privacy/ent/team"
"entgo.io/ent/entc/integration/privacy/ent/user"
@@ -122,8 +123,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/entc/integration/template/ent/client.go b/entc/integration/template/ent/client.go
index e15974b4c6..306c44f2cd 100644
--- a/entc/integration/template/ent/client.go
+++ b/entc/integration/template/ent/client.go
@@ -20,6 +20,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/template/ent/group"
"entgo.io/ent/entc/integration/template/ent/pet"
"entgo.io/ent/entc/integration/template/ent/user"
@@ -126,8 +127,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/compositetypes/ent/client.go b/examples/compositetypes/ent/client.go
index fb5d416157..6efaac3f20 100644
--- a/examples/compositetypes/ent/client.go
+++ b/examples/compositetypes/ent/client.go
@@ -14,6 +14,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/compositetypes/ent/user"
)
@@ -99,8 +100,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/domaintypes/ent/client.go b/examples/domaintypes/ent/client.go
index 205c437fad..5f9a38bb02 100644
--- a/examples/domaintypes/ent/client.go
+++ b/examples/domaintypes/ent/client.go
@@ -14,6 +14,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/domaintypes/ent/user"
)
@@ -99,8 +100,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/edgeindex/ent/client.go b/examples/edgeindex/ent/client.go
index d076f8201d..14decdaa89 100644
--- a/examples/edgeindex/ent/client.go
+++ b/examples/edgeindex/ent/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/edgeindex/ent/city"
"entgo.io/ent/examples/edgeindex/ent/street"
)
@@ -108,8 +109,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/encryptfield/ent/client.go b/examples/encryptfield/ent/client.go
index 0d9cfbde4c..858ec80a64 100644
--- a/examples/encryptfield/ent/client.go
+++ b/examples/encryptfield/ent/client.go
@@ -18,6 +18,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/encryptfield/ent/user"
"gocloud.dev/secrets"
)
@@ -112,8 +113,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/entcpkg/ent/client.go b/examples/entcpkg/ent/client.go
index dfde64daa0..166e4a68e8 100644
--- a/examples/entcpkg/ent/client.go
+++ b/examples/entcpkg/ent/client.go
@@ -21,6 +21,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/entcpkg/ent/user"
)
@@ -122,8 +123,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/enumtypes/ent/client.go b/examples/enumtypes/ent/client.go
index 0b08f4cfc8..ffdd2ec8c0 100644
--- a/examples/enumtypes/ent/client.go
+++ b/examples/enumtypes/ent/client.go
@@ -14,6 +14,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/enumtypes/ent/user"
)
@@ -99,8 +100,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/extensions/ent/client.go b/examples/extensions/ent/client.go
index b02d53c6ec..698414bc64 100644
--- a/examples/extensions/ent/client.go
+++ b/examples/extensions/ent/client.go
@@ -14,6 +14,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/extensions/ent/user"
)
@@ -99,8 +100,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/fs/ent/client.go b/examples/fs/ent/client.go
index 31c33c4669..9dd4076549 100644
--- a/examples/fs/ent/client.go
+++ b/examples/fs/ent/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/fs/ent/file"
)
@@ -104,8 +105,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/functionalidx/ent/client.go b/examples/functionalidx/ent/client.go
index 678aa3dfb7..a09fe0c34b 100644
--- a/examples/functionalidx/ent/client.go
+++ b/examples/functionalidx/ent/client.go
@@ -14,6 +14,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/functionalidx/ent/user"
)
@@ -99,8 +100,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/go.mod b/examples/go.mod
index 74e79123fb..88748103b7 100644
--- a/examples/go.mod
+++ b/examples/go.mod
@@ -14,6 +14,7 @@ require (
github.com/lib/pq v1.10.7
github.com/mattn/go-sqlite3 v1.14.28
github.com/stretchr/testify v1.11.1
+ github.com/ydb-platform/ydb-go-sdk/v3 v3.125.4
gocloud.dev v0.28.0
)
@@ -32,7 +33,6 @@ require (
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/ydb-platform/ydb-go-sdk/v3 v3.125.0 // 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
@@ -50,4 +50,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
-replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.5
+replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.18
diff --git a/examples/go.sum b/examples/go.sum
index df815aaa94..3f5bdb7f00 100644
--- a/examples/go.sum
+++ b/examples/go.sum
@@ -449,8 +449,8 @@ github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/GoogleCloudPlatform/cloudsql-proxy v1.33.1/go.mod h1:n3KDPrdaY2p9Nr0B1allAdjYArwIpXQcitNbsS/Qiok=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
-github.com/LostImagin4tion/atlas v0.0.5 h1:SoP7EqpVLCMNCWPIZovdwOQUeJcO8ZY5cDTG5VMuIQM=
-github.com/LostImagin4tion/atlas v0.0.5/go.mod h1:Rco1malutATQGeWEoYFzurfzIvs+galayoZ0+Pz4als=
+github.com/LostImagin4tion/atlas v0.0.18 h1:RrLLU6zEXuRZAih3slblKFZ/lPLUDZ+wrHaTrxILqrA=
+github.com/LostImagin4tion/atlas v0.0.18/go.mod h1:Rco1malutATQGeWEoYFzurfzIvs+galayoZ0+Pz4als=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
@@ -1699,8 +1699,8 @@ github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
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.0 h1:KPnGV2diuX1A4/1zXLO1UWHJokWC8yICzEfjdkSUWKo=
-github.com/ydb-platform/ydb-go-sdk/v3 v3.125.0/go.mod h1:/LjMxb/rXmoGAAnImoqAFIlhO5ampHacbvDetQitCk4=
+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=
diff --git a/examples/jsonencode/ent/client.go b/examples/jsonencode/ent/client.go
index 77ee8dfb9e..2414de9cf1 100644
--- a/examples/jsonencode/ent/client.go
+++ b/examples/jsonencode/ent/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/jsonencode/ent/card"
"entgo.io/ent/examples/jsonencode/ent/pet"
"entgo.io/ent/examples/jsonencode/ent/user"
@@ -112,8 +113,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/m2m2types/ent/client.go b/examples/m2m2types/ent/client.go
index 9704c44664..6622a651ee 100644
--- a/examples/m2m2types/ent/client.go
+++ b/examples/m2m2types/ent/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/m2m2types/ent/group"
"entgo.io/ent/examples/m2m2types/ent/user"
)
@@ -108,8 +109,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/m2mbidi/ent/client.go b/examples/m2mbidi/ent/client.go
index 51bb71efca..844fa092af 100644
--- a/examples/m2mbidi/ent/client.go
+++ b/examples/m2mbidi/ent/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/m2mbidi/ent/user"
)
@@ -104,8 +105,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/m2mrecur/ent/client.go b/examples/m2mrecur/ent/client.go
index 9ee17212e3..a091524684 100644
--- a/examples/m2mrecur/ent/client.go
+++ b/examples/m2mrecur/ent/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/m2mrecur/ent/user"
)
@@ -104,8 +105,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/migration/ent/client.go b/examples/migration/ent/client.go
index b9391670bd..4e9a791272 100644
--- a/examples/migration/ent/client.go
+++ b/examples/migration/ent/client.go
@@ -20,6 +20,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/migration/ent/card"
"entgo.io/ent/examples/migration/ent/payment"
"entgo.io/ent/examples/migration/ent/pet"
@@ -125,8 +126,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/o2m2types/ent/client.go b/examples/o2m2types/ent/client.go
index fcd9f865a4..ba285138f6 100644
--- a/examples/o2m2types/ent/client.go
+++ b/examples/o2m2types/ent/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/o2m2types/ent/pet"
"entgo.io/ent/examples/o2m2types/ent/user"
)
@@ -108,8 +109,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/o2mrecur/ent/client.go b/examples/o2mrecur/ent/client.go
index 534ef5bc91..61e5ee76b8 100644
--- a/examples/o2mrecur/ent/client.go
+++ b/examples/o2mrecur/ent/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/o2mrecur/ent/node"
)
@@ -104,8 +105,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/o2o2types/ent/client.go b/examples/o2o2types/ent/client.go
index 6c036fd847..1a229c421f 100644
--- a/examples/o2o2types/ent/client.go
+++ b/examples/o2o2types/ent/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/o2o2types/ent/card"
"entgo.io/ent/examples/o2o2types/ent/user"
)
@@ -108,8 +109,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/o2obidi/ent/client.go b/examples/o2obidi/ent/client.go
index 688c30f135..6481b24719 100644
--- a/examples/o2obidi/ent/client.go
+++ b/examples/o2obidi/ent/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/o2obidi/ent/user"
)
@@ -104,8 +105,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/o2orecur/ent/client.go b/examples/o2orecur/ent/client.go
index da01648ece..e3bfd1e0a0 100644
--- a/examples/o2orecur/ent/client.go
+++ b/examples/o2orecur/ent/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/o2orecur/ent/node"
)
@@ -104,8 +105,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/privacyadmin/ent/client.go b/examples/privacyadmin/ent/client.go
index 5d39e39555..ddf6e09ea9 100644
--- a/examples/privacyadmin/ent/client.go
+++ b/examples/privacyadmin/ent/client.go
@@ -18,6 +18,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/privacyadmin/ent/user"
)
@@ -103,8 +104,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/privacytenant/ent/client.go b/examples/privacytenant/ent/client.go
index 1cc37d7a01..3049f613d8 100644
--- a/examples/privacytenant/ent/client.go
+++ b/examples/privacytenant/ent/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/privacytenant/ent/group"
"entgo.io/ent/examples/privacytenant/ent/tenant"
"entgo.io/ent/examples/privacytenant/ent/user"
@@ -112,8 +113,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/rls/ent/client.go b/examples/rls/ent/client.go
index 2a22d9a75c..844735ece7 100644
--- a/examples/rls/ent/client.go
+++ b/examples/rls/ent/client.go
@@ -14,6 +14,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/rls/ent/tenant"
"entgo.io/ent/examples/rls/ent/user"
)
@@ -103,8 +104,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/start/ent/client.go b/examples/start/ent/client.go
index b74da8d2dd..07c0d8ded0 100644
--- a/examples/start/ent/client.go
+++ b/examples/start/ent/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/start/ent/car"
"entgo.io/ent/examples/start/ent/group"
"entgo.io/ent/examples/start/ent/user"
@@ -112,8 +113,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/traversal/ent/client.go b/examples/traversal/ent/client.go
index bfffe379e9..61d53840eb 100644
--- a/examples/traversal/ent/client.go
+++ b/examples/traversal/ent/client.go
@@ -19,6 +19,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/traversal/ent/group"
"entgo.io/ent/examples/traversal/ent/pet"
"entgo.io/ent/examples/traversal/ent/user"
@@ -112,8 +113,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/triggers/ent/client.go b/examples/triggers/ent/client.go
index 0d84c8e66b..441a83a35a 100644
--- a/examples/triggers/ent/client.go
+++ b/examples/triggers/ent/client.go
@@ -14,6 +14,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/triggers/ent/user"
"entgo.io/ent/examples/triggers/ent/userauditlog"
)
@@ -103,8 +104,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/version/ent/client.go b/examples/version/ent/client.go
index a7e19b5699..09d70f04f1 100644
--- a/examples/version/ent/client.go
+++ b/examples/version/ent/client.go
@@ -18,6 +18,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/version/ent/user"
)
@@ -103,8 +104,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/viewcomposite/ent/client.go b/examples/viewcomposite/ent/client.go
index 826fed061d..ff92994b59 100644
--- a/examples/viewcomposite/ent/client.go
+++ b/examples/viewcomposite/ent/client.go
@@ -14,6 +14,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/viewcomposite/ent/pet"
"entgo.io/ent/examples/viewcomposite/ent/user"
)
@@ -109,8 +110,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, err
}
diff --git a/examples/viewschema/ent/client.go b/examples/viewschema/ent/client.go
index 4144b1d068..e0f2bde1d8 100644
--- a/examples/viewschema/ent/client.go
+++ b/examples/viewschema/ent/client.go
@@ -14,6 +14,7 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
+ "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/viewschema/ent/pet"
"entgo.io/ent/examples/viewschema/ent/user"
)
@@ -109,8 +110,16 @@ 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:
- drv, err := sql.Open(driverName, dataSourceName)
+ case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ drv, err = sql.Open(driverName, dataSourceName)
+ }
if err != nil {
return nil, 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..d378e901b7
--- /dev/null
+++ b/examples/ydb/ent/client.go
@@ -0,0 +1,704 @@
+// 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/dialect/ydb"
+ "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:
+ var (
+ drv dialect.Driver
+ err error
+ )
+ if driverName == dialect.YDB {
+ drv, err = ydb.Open(context.Background(), dataSourceName)
+ } else {
+ 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..0cb9c190c2
--- /dev/null
+++ b/examples/ydb/ent/episode_create.go
@@ -0,0 +1,271 @@
+// 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/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 sqlgraph.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 sqlgraph.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..2720770e34
--- /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 sqlgraph.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..7c7a3d5830
--- /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 sqlgraph.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..16cd9f1359
--- /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 sqlgraph.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 _, ok := err.(*sqlgraph.NotFoundError); ok {
+ 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 sqlgraph.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 _, ok := err.(*sqlgraph.NotFoundError); ok {
+ 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..bb49606788
--- /dev/null
+++ b/examples/ydb/ent/season_create.go
@@ -0,0 +1,316 @@
+// 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/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 sqlgraph.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 sqlgraph.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..89a1d5ee9c
--- /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 sqlgraph.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..34a45ed74b
--- /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 sqlgraph.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..b9f44283dd
--- /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 sqlgraph.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 _, ok := err.(*sqlgraph.NotFoundError); ok {
+ 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 sqlgraph.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 _, ok := err.(*sqlgraph.NotFoundError); ok {
+ 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..6d4352e662
--- /dev/null
+++ b/examples/ydb/ent/series_create.go
@@ -0,0 +1,286 @@
+// 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/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 sqlgraph.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 sqlgraph.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..a66adf80f7
--- /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 sqlgraph.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..c3c484ba5b
--- /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 sqlgraph.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..9c53f19fc0
--- /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 sqlgraph.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 _, ok := err.(*sqlgraph.NotFoundError); ok {
+ 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 sqlgraph.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 _, ok := err.(*sqlgraph.NotFoundError); ok {
+ 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 9513cbfb74..b5843804c1 100644
--- a/go.mod
+++ b/go.mod
@@ -18,7 +18,7 @@ require (
github.com/olekukonko/tablewriter v1.0.8
github.com/spf13/cobra v1.7.0
github.com/stretchr/testify v1.11.1
- github.com/ydb-platform/ydb-go-sdk/v3 v3.125.0
+ github.com/ydb-platform/ydb-go-sdk/v3 v3.125.4
go.opencensus.io v0.24.0
golang.org/x/sync v0.19.0
golang.org/x/tools v0.39.0
@@ -64,4 +64,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
-replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.5
+replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.18
diff --git a/go.sum b/go.sum
index b5b7a0e5a1..6a778248bb 100644
--- a/go.sum
+++ b/go.sum
@@ -3,8 +3,8 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
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/LostImagin4tion/atlas v0.0.5 h1:SoP7EqpVLCMNCWPIZovdwOQUeJcO8ZY5cDTG5VMuIQM=
-github.com/LostImagin4tion/atlas v0.0.5/go.mod h1:Rco1malutATQGeWEoYFzurfzIvs+galayoZ0+Pz4als=
+github.com/LostImagin4tion/atlas v0.0.18 h1:RrLLU6zEXuRZAih3slblKFZ/lPLUDZ+wrHaTrxILqrA=
+github.com/LostImagin4tion/atlas v0.0.18/go.mod h1:Rco1malutATQGeWEoYFzurfzIvs+galayoZ0+Pz4als=
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=
@@ -158,8 +158,8 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
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.0 h1:KPnGV2diuX1A4/1zXLO1UWHJokWC8yICzEfjdkSUWKo=
-github.com/ydb-platform/ydb-go-sdk/v3 v3.125.0/go.mod h1:/LjMxb/rXmoGAAnImoqAFIlhO5ampHacbvDetQitCk4=
+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=
From 7bd3cb74c6267cff83bb49036b170189dc66d1a4 Mon Sep 17 00:00:00 2001
From: Egor Danilov <63148392+LostImagin4tion@users.noreply.github.com>
Date: Wed, 4 Feb 2026 18:53:34 +0300
Subject: [PATCH 08/14] all: fixed integration tests for ydb (#11)
---
.github/workflows/ci.yml | 28 ++
dialect/entsql/annotation.go | 6 +-
dialect/sql/builder.go | 519 ++++++++++++++++++++---
dialect/sql/builder_test.go | 56 +--
dialect/sql/schema/atlas.go | 5 +
dialect/sql/schema/ydb.go | 143 +++++--
dialect/sql/sqlgraph/errors.go | 1 +
dialect/sql/sqlgraph/graph.go | 491 +++++++++++++--------
dialect/sql/sqlgraph/graph_test.go | 4 +-
entc/integration/docker-compose.yaml | 18 +
entc/integration/ent/migrate/schema.go | 10 +-
entc/integration/ent/schema/fieldtype.go | 9 +-
entc/integration/go.mod | 2 +-
entc/integration/go.sum | 4 +-
entc/integration/integration_test.go | 171 ++++++--
entc/integration/relation_test.go | 53 ++-
entc/integration/type_test.go | 39 +-
examples/go.mod | 2 +-
examples/go.sum | 4 +-
go.mod | 2 +-
go.sum | 4 +-
21 files changed, 1202 insertions(+), 369 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5c09c7285b..06ca3317b7 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -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/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 72f5d17aba..0a3264e468 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
@@ -854,8 +857,7 @@ func Delete(table string) *DeleteBuilder { return &DeleteBuilder{table: table} }
//
// Note: BATCH DELETE is only supported in YDB dialect.
//
-// BatchDelete("/local/my_table").
-// Where(GT("Key1", 1))
+// BatchDelete("/local/my_table").Where(GT("Key1", 1))
func BatchDelete(table string) *DeleteBuilder {
return &DeleteBuilder{table: table, isBatch: true}
}
@@ -1377,38 +1379,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 '#'")
+ }
}
})
}
@@ -1416,17 +1444,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, dialect.YDB:
+ 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)
@@ -1479,6 +1516,12 @@ 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 is not supported by %q", p.dialect))
}
@@ -1660,7 +1703,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.
@@ -1795,7 +1885,10 @@ type SelectTable struct {
name string
schema string
quote bool
- index string // YDB-specific: secondary index name for VIEW clause
+
+ // YDB-specific:
+ index string // secondary index name for VIEW clause
+ isCte bool // YDB-specific: marks this as a CTE reference
}
// Table returns a new table selector.
@@ -1870,6 +1963,23 @@ 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)
// YDB-specific: VIEW clause for secondary indexes
@@ -1911,7 +2021,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
@@ -1977,17 +2087,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
}
@@ -2000,23 +2110,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
}
@@ -2024,7 +2134,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
}
@@ -2037,9 +2147,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
}
@@ -2067,16 +2177,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
@@ -2086,7 +2196,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)
}
}
@@ -2098,7 +2208,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
}
@@ -2689,7 +2799,7 @@ func (s *Selector) Clone() *Selector {
group: append([]string{}, s.group...),
order: append([]any{}, s.order...),
assumeOrder: append([]string{}, s.assumeOrder...),
- selection: append([]selection{}, s.selection...),
+ selection: append([]*selection{}, s.selection...),
}
}
@@ -2799,6 +2909,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 {
@@ -2873,6 +2987,9 @@ func (s *Selector) Query() (string, []any) {
if len(s.setOps) > 0 {
s.joinSetOps(&b)
}
+ if b.ydb() {
+ s.applyAliasesToOrder()
+ }
joinOrder(s.order, &b)
s.joinAssumeOrder(&b)
if s.limit != nil {
@@ -2896,6 +3013,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
@@ -2976,21 +3132,145 @@ 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.
@@ -3065,6 +3345,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 ")
@@ -3087,6 +3371,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() {}
@@ -3526,8 +3859,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
@@ -3540,19 +3873,78 @@ func (b *Builder) Argf(format string, a any) *Builder {
}
b.total++
- // YDB requires named parameters
+ // YDB requires named parameters with $paramName syntax.
if b.ydb() {
- // Extract parameter name from format (e.g., "$p0" -> "p0")
paramName := strings.TrimPrefix(format, "$")
- b.args = append(b.args, driver.NamedValue{Name: paramName, Value: a})
+ b.args = append(b.args, driver.NamedValue{
+ Name: paramName,
+ Value: b.convertValueYdb(arg),
+ })
} else {
- b.args = append(b.args, a)
+ 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(", ")
@@ -3726,6 +4118,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{}
diff --git a/dialect/sql/builder_test.go b/dialect/sql/builder_test.go
index 028b6d10ee..a3ff15fc98 100644
--- a/dialect/sql/builder_test.go
+++ b/dialect/sql/builder_test.go
@@ -746,7 +746,7 @@ func TestBuilder(t *testing.T) {
Join(t2).
On(t1.C("id"), t2.C("user_id"))
}(),
- wantQuery: "SELECT `u`.`id`, `g`.`name` FROM `users` AS `u` JOIN `groups` AS `g` ON `u`.`id` = `g`.`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 {
@@ -1131,7 +1131,7 @@ func TestBuilder(t *testing.T) {
{
input: Dialect(dialect.YDB).
Select().Count().From(Table("users")),
- wantQuery: "SELECT COUNT(*) FROM `users`",
+ wantQuery: "SELECT COUNT(*) AS `count` FROM `users`",
},
{
input: Select().Count(Distinct("id")).From(Table("users")),
@@ -1205,7 +1205,7 @@ func TestBuilder(t *testing.T) {
Select("name", Count("*")).
From(Table("users")).
GroupBy("name"),
- wantQuery: "SELECT `name`, COUNT(*) FROM `users` GROUP BY `name`",
+ wantQuery: "SELECT `name`, COUNT(*) AS `count` FROM `users` GROUP BY `name`",
},
{
input: Select("name", Count("*")).
@@ -1831,7 +1831,7 @@ AND "users"."id1" < "users"."id2") AND "users"."id1" <= "users"."id2"`, "\n", ""
Join(t2).
On(t1.C("user_id"), t2.C("id"))
}(),
- wantQuery: "SELECT `orders`.`id`, `u`.`name` FROM `orders` JOIN `users` VIEW `idx_email` AS `u` ON `orders`.`user_id` = `u`.`id`",
+ wantQuery: "SELECT `orders`.`id` AS `id`, `u`.`name` AS `name` FROM `orders` JOIN `users` VIEW `idx_email` AS `u` ON `orders`.`user_id` = `u`.`id`",
},
{
input: func() Querier {
@@ -1843,7 +1843,7 @@ AND "users"."id1" < "users"."id2") AND "users"."id1" <= "users"."id2"`, "\n", ""
Join(t2).
On(t1.C("ref"), t2.C("ref"))
}(),
- wantQuery: "SELECT `a`.`value`, `b`.`value` FROM `a_table` AS `a` JOIN `b_table` VIEW `b_index_ref` AS `b` ON `a`.`ref` = `b`.`ref`",
+ wantQuery: "SELECT `a`.`value` AS `value`, `b`.`value` AS `value` FROM `a_table` AS `a` JOIN `b_table` VIEW `b_index_ref` AS `b` ON `a`.`ref` = `b`.`ref`",
},
{
input: func() Querier {
@@ -1869,7 +1869,7 @@ AND "users"."id1" < "users"."id2") AND "users"."id1" <= "users"."id2"`, "\n", ""
LeftSemiJoin(t2).
On(t1.C("id"), t2.C("user_id"))
}(),
- wantQuery: "SELECT `users`.`id`, `users`.`name` FROM `users` LEFT SEMI JOIN `blacklist` AS `t1` ON `users`.`id` = `t1`.`user_id`",
+ wantQuery: "SELECT `users`.`id` AS `id`, `users`.`name` AS `name` FROM `users` LEFT SEMI JOIN `blacklist` AS `t1` ON `users`.`id` = `t1`.`user_id`",
},
{
input: func() Querier {
@@ -1881,7 +1881,7 @@ AND "users"."id1" < "users"."id2") AND "users"."id1" <= "users"."id2"`, "\n", ""
RightSemiJoin(t2).
On(t1.C("user_id"), t2.C("id"))
}(),
- wantQuery: "SELECT `t1`.`id`, `t1`.`email` FROM `orders` RIGHT SEMI JOIN `active_users` AS `t1` ON `orders`.`user_id` = `t1`.`id`",
+ wantQuery: "SELECT `t1`.`id` AS `id`, `t1`.`email` AS `email` FROM `orders` RIGHT SEMI JOIN `active_users` AS `t1` ON `orders`.`user_id` = `t1`.`id`",
},
{
input: func() Querier {
@@ -1893,7 +1893,7 @@ AND "users"."id1" < "users"."id2") AND "users"."id1" <= "users"."id2"`, "\n", ""
LeftOnlyJoin(t2).
On(t1.C("id"), t2.C("id"))
}(),
- wantQuery: "SELECT `users`.`id`, `users`.`name` FROM `users` LEFT ONLY JOIN `deleted_users` AS `t1` ON `users`.`id` = `t1`.`id`",
+ wantQuery: "SELECT `users`.`id` AS `id`, `users`.`name` AS `name` FROM `users` LEFT ONLY JOIN `deleted_users` AS `t1` ON `users`.`id` = `t1`.`id`",
},
{
input: func() Querier {
@@ -1905,7 +1905,7 @@ AND "users"."id1" < "users"."id2") AND "users"."id1" <= "users"."id2"`, "\n", ""
RightOnlyJoin(t2).
On(t1.C("user_id"), t2.C("id"))
}(),
- wantQuery: "SELECT `t1`.`id`, `t1`.`status` FROM `archived` RIGHT ONLY JOIN `users` AS `t1` ON `archived`.`user_id` = `t1`.`id`",
+ wantQuery: "SELECT `t1`.`id` AS `id`, `t1`.`status` AS `status` FROM `archived` RIGHT ONLY JOIN `users` AS `t1` ON `archived`.`user_id` = `t1`.`id`",
},
{
input: func() Querier {
@@ -1917,7 +1917,7 @@ AND "users"."id1" < "users"."id2") AND "users"."id1" <= "users"."id2"`, "\n", ""
ExclusionJoin(t2).
On(t1.C("key"), t2.C("key"))
}(),
- wantQuery: "SELECT `a`.`key`, `b`.`key` FROM `table_a` AS `a` EXCLUSION JOIN `table_b` AS `b` ON `a`.`key` = `b`.`key`",
+ wantQuery: "SELECT `a`.`key` AS `key`, `b`.`key` AS `key` FROM `table_a` AS `a` EXCLUSION JOIN `table_b` AS `b` ON `a`.`key` = `b`.`key`",
},
{
input: func() Querier {
@@ -1941,7 +1941,7 @@ AND "users"."id1" < "users"."id2") AND "users"."id1" <= "users"."id2"`, "\n", ""
LeftJoin(t3).
OnP(And(EQ(t3.C("ref"), Expr(t1.C("key"))), EQ(t3.C("column1"), Expr(t2.C("value")))))
}(),
- wantQuery: "SELECT `a`.`value`, `b`.`value`, `c`.`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`",
+ 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).
@@ -2323,7 +2323,7 @@ func TestSelector_VIEW_SecondaryIndex_YDB(t *testing.T) {
Where(EQ(users.C("name"), "John Doe")).
Query()
- require.Equal(t, "SELECT `t1`.`series_id`, `t1`.`title` FROM `series` VIEW `users_index` AS `t1` JOIN `users` VIEW `name_index` AS `t2` ON `t1`.`uploaded_user_id` = `t2`.`user_id` WHERE `t2`.`name` = $p0", query)
+ require.Equal(t, "SELECT `t1`.`series_id` AS `series_id`, `t1`.`title` AS `title` FROM `series` VIEW `users_index` AS `t1` JOIN `users` VIEW `name_index` AS `t2` ON `t1`.`uploaded_user_id` = `t2`.`user_id` WHERE `t2`.`name` = $p0", query)
require.Equal(t, []any{driver.NamedValue{Name: "p0", Value: "John Doe"}}, args)
})
@@ -2344,7 +2344,7 @@ func TestBatchUpdate_YDB(t *testing.T) {
Set("Value2", 0).
Where(GT("Key1", 1)).
Query()
-
+
require.Equal(t, "BATCH UPDATE `my_table` SET `Value1` = $p0, `Value2` = $p1 WHERE `Key1` > $p2", query)
require.Equal(t, []any{
driver.NamedValue{Name: "p0", Value: "foo"},
@@ -2358,9 +2358,9 @@ func TestBatchUpdate_YDB(t *testing.T) {
BatchUpdate("users").
Set("status", "active").
Where(GT("created_at", "2024-01-01"))
-
+
query, args, err := builder.QueryErr()
-
+
require.Empty(t, query)
require.Empty(t, args)
require.Error(t, err)
@@ -2371,9 +2371,9 @@ func TestBatchUpdate_YDB(t *testing.T) {
BatchUpdate("users").
Set("status", "active").
Returning("id", "status")
-
+
query, args, err := builder.QueryErr()
-
+
require.Empty(t, query)
require.Empty(t, args)
require.Error(t, err)
@@ -2382,13 +2382,13 @@ func TestBatchUpdate_YDB(t *testing.T) {
t.Run("BATCH UPDATE with UPDATE ON pattern should error", func(t *testing.T) {
d := Dialect(dialect.YDB)
subquery := d.Select("id").From(Table("orders")).Where(EQ("status", "pending"))
-
+
builder := d.BatchUpdate("users").
Set("status", "active").
On(subquery)
-
+
query, args, err := builder.QueryErr()
-
+
require.Empty(t, query)
require.Empty(t, args)
require.Error(t, err)
@@ -2402,7 +2402,7 @@ func TestBatchDelete_YDB(t *testing.T) {
query, args := d.BatchDelete("my_table").
Where(And(GT("Key1", 1), GTE("Key2", "One"))).
Query()
-
+
require.Equal(t, "BATCH DELETE FROM `my_table` WHERE `Key1` > $p0 AND `Key2` >= $p1", query)
require.Equal(t, []any{
driver.NamedValue{Name: "p0", Value: 1},
@@ -2414,9 +2414,9 @@ func TestBatchDelete_YDB(t *testing.T) {
builder := Dialect(dialect.MySQL).
BatchDelete("users").
Where(GT("id", 100))
-
+
query, args, err := builder.QueryErr()
-
+
require.Empty(t, query)
require.Empty(t, args)
require.Error(t, err)
@@ -2427,9 +2427,9 @@ func TestBatchDelete_YDB(t *testing.T) {
BatchDelete("users").
Where(GT("id", 100)).
Returning("id")
-
+
query, args, err := builder.QueryErr()
-
+
require.Empty(t, query)
require.Empty(t, args)
require.Error(t, err)
@@ -2438,12 +2438,12 @@ func TestBatchDelete_YDB(t *testing.T) {
t.Run("BATCH DELETE with DELETE ON pattern should error", func(t *testing.T) {
d := Dialect(dialect.YDB)
subquery := d.Select("id").From(Table("users")).Where(EQ("status", "deleted"))
-
+
builder := d.BatchDelete("users").
On(subquery)
-
+
query, args, err := builder.QueryErr()
-
+
require.Empty(t, query)
require.Empty(t, args)
require.Error(t, err)
diff --git a/dialect/sql/schema/atlas.go b/dialect/sql/schema/atlas.go
index d0ce2ff502..c4145161b7 100644
--- a/dialect/sql/schema/atlas.go
+++ b/dialect/sql/schema/atlas.go
@@ -1103,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]
diff --git a/dialect/sql/schema/ydb.go b/dialect/sql/schema/ydb.go
index c37218ffc9..df835b415c 100644
--- a/dialect/sql/schema/ydb.go
+++ b/dialect/sql/schema/ydb.go
@@ -6,7 +6,6 @@ package schema
import (
"context"
- "errors"
"fmt"
"strings"
@@ -68,22 +67,12 @@ func (d *YDB) tableExist(ctx context.Context, conn dialect.ExecQuerier, name str
// atOpen returns a custom Atlas migrate.Driver for YDB.
func (d *YDB) atOpen(conn dialect.ExecQuerier) (migrate.Driver, error) {
- var ydbDriver *entdrv.YDBDriver
-
- switch drv := conn.(type) {
- case *entdrv.YDBDriver:
- ydbDriver = drv
- case *YDB:
- if ydb, ok := drv.Driver.(*entdrv.YDBDriver); ok {
- ydbDriver = ydb
- }
+ ydbDriver := unwrapYDBDriver(conn)
+ if ydbDriver == nil {
+ ydbDriver = unwrapYDBDriver(d.Driver)
}
if ydbDriver == nil {
- if ydb, ok := d.Driver.(*entdrv.YDBDriver); ok {
- ydbDriver = ydb
- } else {
- return nil, fmt.Errorf("expected dialect/ydb.YDBDriver, but got %T", conn)
- }
+ return nil, fmt.Errorf("expected dialect/ydb.YDBDriver, but got %T", conn)
}
return atlas.Open(
@@ -92,6 +81,20 @@ func (d *YDB) atOpen(conn dialect.ExecQuerier) (migrate.Driver, error) {
)
}
+func unwrapYDBDriver(driver any) *entdrv.YDBDriver {
+ switch drv := driver.(type) {
+ case *entdrv.YDBDriver:
+ return drv
+ case *YDB:
+ return unwrapYDBDriver(drv.Driver)
+ case *WriteDriver:
+ return unwrapYDBDriver(drv.Driver)
+ case *dialect.DebugDriver:
+ return unwrapYDBDriver(drv.Driver)
+ }
+ return nil
+}
+
func (d *YDB) atTable(table1 *Table, table2 *schema.Table) {
if table1.Annotation != nil {
setAtChecks(table1, table2)
@@ -163,7 +166,9 @@ func (d *YDB) atTypeC(column1 *Column, column2 *schema.Column) error {
case field.TypeUUID:
typ = &schema.UUIDType{T: atlas.TypeUUID}
case field.TypeEnum:
- err = errors.New("ydb: Enum can't be used as column data type for tables")
+ // 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:
@@ -179,13 +184,17 @@ func (d *YDB) atTypeC(column1 *Column, column2 *schema.Column) error {
}
// atUniqueC adds a unique constraint for a column.
-// In YDB, unique constraints are implemented as GLOBAL UNIQUE SYNC indexes.
+// 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 {
@@ -194,11 +203,8 @@ func (d *YDB) atUniqueC(
}
}
// Create a unique index for this column.
- idxName := fmt.Sprintf("%s_%s_index", table1.Name, column1.Name)
- index := schema.NewUniqueIndex(idxName).AddColumns(column2)
-
- // Add YDB-specific attribute for GLOBAL SYNC index type.
- index.AddAttrs(&atlas.IndexAttributes{Global: true, Sync: true})
+ indexName := fmt.Sprintf("%s_%s_uniq_idx", table1.Name, column1.Name)
+ index := schema.NewUniqueIndex(indexName).AddParts(&schema.IndexPart{C: column2})
table2.AddIndexes(index)
}
@@ -226,34 +232,65 @@ func (d *YDB) atIndex(
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.
- idxType := &atlas.IndexAttributes{Global: true, Sync: true}
+ idxAttrs := &atlas.IndexAttributes{}
- // Check for annotation overrides.
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 {
- // Parse YDB-specific index type from annotation.
- switch strings.ToUpper(indexType) {
- case "GLOBAL ASYNC", "ASYNC":
- idxType.Sync = false
- case "LOCAL":
- idxType.Global = false
- case "LOCAL ASYNC":
- idxType.Global = false
- idxType.Sync = false
+ upperIndexType := strings.ToUpper(indexType)
+
+ if strings.Contains(upperIndexType, "ASYNC") {
+ idxAttrs.Async = true
+ }
+ if strings.Contains(upperIndexType, "UNIQUE") {
+ index2.Unique = true
}
}
}
- index2.AddAttrs(idxType)
+
+ index2.Name = fmt.Sprintf(
+ "%s_%s_idx",
+ table2.Name,
+ strings.Join(indexColumns, "_"),
+ )
+
+ index2.AddAttrs(idxAttrs)
return nil
}
@@ -269,3 +306,41 @@ func (*YDB) atTypeRangeSQL(ts ...string) string {
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 6cb9d04a1c..250867c5a4 100644
--- a/dialect/sql/sqlgraph/graph.go
+++ b/dialect/sql/sqlgraph/graph.go
@@ -162,124 +162,146 @@ 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))
- }
-
- // YDB doesn't support correlated EXISTS subqueries.
- // Use IN subquery instead for YDB dialect.
- if q.Dialect() == dialect.YDB {
- q.Where(
+ 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(
- q.C(s.From.Column),
- builder.Select(to.C(s.Edge.Columns[0])).From(to),
+ 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 {
- q.Where(
+ query.Where(
sql.Exists(
- builder.Select(to.C(s.Edge.Columns[0])).
+ builder.Select(to.C(step.Edge.Columns[0])).
From(to).
Where(
sql.ColumnsEQ(
- q.C(s.From.Column),
- to.C(s.Edge.Columns[0]),
+ query.C(step.From.Column),
+ to.C(step.Edge.Columns[0]),
),
),
),
@@ -290,98 +312,105 @@ func HasNeighbors(q *sql.Selector, s *Step) {
// 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))
}
}
- // YDB doesn't support correlated EXISTS subqueries.
- // Use IN subquery instead for YDB dialect.
- if q.Dialect() == dialect.YDB {
- matches := builder.Select(to.C(s.To.Column)).From(to)
- matches.WithContext(q.Context())
- pred(matches)
- q.Where(sql.In(q.C(s.Edge.Columns[0]), matches))
+ 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(s.To.Column)).
+ matches := builder.Select(to.C(step.To.Column)).
From(to)
- matches.WithContext(q.Context())
+ matches.WithContext(query.Context())
matches.Where(
sql.ColumnsEQ(
- q.C(s.Edge.Columns[0]),
- to.C(s.To.Column),
+ query.C(step.Edge.Columns[0]),
+ to.C(step.To.Column),
),
)
- pred(matches)
- q.Where(sql.Exists(matches))
+ predicate(matches)
+ query.Where(sql.Exists(matches))
}
- case s.ToEdgeOwner():
- to := builder.Table(s.Edge.Table).Schema(s.Edge.Schema)
+ 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))
}
}
-
- // YDB doesn't support correlated EXISTS subqueries.
- // Use IN subquery instead for YDB dialect.
- if q.Dialect() == dialect.YDB {
- matches := builder.Select(to.C(s.Edge.Columns[0])).From(to)
- matches.WithContext(q.Context())
- pred(matches)
- q.Where(sql.In(q.C(s.From.Column), 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(s.Edge.Columns[0])).
+ matches := builder.Select(to.C(step.Edge.Columns[0])).
From(to)
- matches.WithContext(q.Context())
+ matches.WithContext(query.Context())
matches.Where(
sql.ColumnsEQ(
- q.C(s.From.Column),
- to.C(s.Edge.Columns[0]),
+ query.C(step.From.Column),
+ to.C(step.Edge.Columns[0]),
),
)
- pred(matches)
- q.Where(sql.Exists(matches))
+ predicate(matches)
+ query.Where(sql.Exists(matches))
}
}
}
@@ -573,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))
@@ -965,17 +995,32 @@ func NewDeleteSpec(table string, id *FieldSpec) *DeleteSpec {
func DeleteNodes(ctx context.Context, drv dialect.Driver, spec *DeleteSpec) (int, error) {
var affected int
op := func(ctx context.Context, d dialect.Driver) error {
- var (
- res sql.Result
- builder = sql.Dialect(drv.Dialect())
- )
+ 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()
+ 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
}
@@ -1261,12 +1306,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
}
@@ -1497,45 +1543,38 @@ func (u *updater) scan(rows *sql.Rows) error {
func (u *updater) ensureExists(ctx context.Context) error {
selector := 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))
+ 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
-
- // YDB doesn't fully support EXISTS in all contexts.
- // Use COUNT(*) > 0 approach instead for better compatibility.
- if selector.Dialect() == dialect.YDB {
- selector.Count("*")
- query, args = selector.Query()
- } else {
- query, args = u.builder.SelectExpr(sql.Exists(selector)).Query()
- }
-
+
+ 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()
-
- var found bool
- if selector.Dialect() == dialect.YDB {
- count, err := sql.ScanInt(rows)
- if err != nil {
- return err
- }
- found = count > 0
- } else {
- var err error
- found, err = sql.ScanBool(rows)
- if err != nil {
- return err
- }
+
+ 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
}
@@ -1548,8 +1587,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
}
@@ -1623,6 +1673,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)
@@ -1689,7 +1743,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 {
@@ -1751,6 +1817,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...)
}
@@ -1854,7 +1924,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.
@@ -1902,7 +1980,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.
@@ -1976,19 +2061,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) {
@@ -2015,6 +2098,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/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/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/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/go.mod b/entc/integration/go.mod
index 6ac5a6f8b2..7b1caee556 100644
--- a/entc/integration/go.mod
+++ b/entc/integration/go.mod
@@ -50,4 +50,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
-replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.18
+replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.33
diff --git a/entc/integration/go.sum b/entc/integration/go.sum
index 350fb9eb87..48b6a96115 100644
--- a/entc/integration/go.sum
+++ b/entc/integration/go.sum
@@ -5,8 +5,8 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
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/LostImagin4tion/atlas v0.0.18 h1:RrLLU6zEXuRZAih3slblKFZ/lPLUDZ+wrHaTrxILqrA=
-github.com/LostImagin4tion/atlas v0.0.18/go.mod h1:Rco1malutATQGeWEoYFzurfzIvs+galayoZ0+Pz4als=
+github.com/LostImagin4tion/atlas v0.0.33 h1:RgcQhGG0MZDwheuFRiZu47ihFRDhtcYmbAT6KU3J3v0=
+github.com/LostImagin4tion/atlas v0.0.33/go.mod h1:FtOd0Ry45l3FeDVGVm8tf2SFWg3vHDztylE0eE3EWQ8=
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=
diff --git a/entc/integration/integration_test.go b/entc/integration/integration_test.go
index 091c125ecf..6bdf330b34 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,6 +351,10 @@ 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")
@@ -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))
}
@@ -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/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/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/go.mod b/examples/go.mod
index 88748103b7..13d183ff1c 100644
--- a/examples/go.mod
+++ b/examples/go.mod
@@ -50,4 +50,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
-replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.18
+replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.33
diff --git a/examples/go.sum b/examples/go.sum
index 3f5bdb7f00..e84eec833f 100644
--- a/examples/go.sum
+++ b/examples/go.sum
@@ -449,8 +449,8 @@ github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/GoogleCloudPlatform/cloudsql-proxy v1.33.1/go.mod h1:n3KDPrdaY2p9Nr0B1allAdjYArwIpXQcitNbsS/Qiok=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
-github.com/LostImagin4tion/atlas v0.0.18 h1:RrLLU6zEXuRZAih3slblKFZ/lPLUDZ+wrHaTrxILqrA=
-github.com/LostImagin4tion/atlas v0.0.18/go.mod h1:Rco1malutATQGeWEoYFzurfzIvs+galayoZ0+Pz4als=
+github.com/LostImagin4tion/atlas v0.0.33 h1:RgcQhGG0MZDwheuFRiZu47ihFRDhtcYmbAT6KU3J3v0=
+github.com/LostImagin4tion/atlas v0.0.33/go.mod h1:FtOd0Ry45l3FeDVGVm8tf2SFWg3vHDztylE0eE3EWQ8=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
diff --git a/go.mod b/go.mod
index b5843804c1..c3d32e35ae 100644
--- a/go.mod
+++ b/go.mod
@@ -64,4 +64,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
-replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.18
+replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.33
diff --git a/go.sum b/go.sum
index 6a778248bb..5f73949be5 100644
--- a/go.sum
+++ b/go.sum
@@ -3,8 +3,8 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
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/LostImagin4tion/atlas v0.0.18 h1:RrLLU6zEXuRZAih3slblKFZ/lPLUDZ+wrHaTrxILqrA=
-github.com/LostImagin4tion/atlas v0.0.18/go.mod h1:Rco1malutATQGeWEoYFzurfzIvs+galayoZ0+Pz4als=
+github.com/LostImagin4tion/atlas v0.0.33 h1:RgcQhGG0MZDwheuFRiZu47ihFRDhtcYmbAT6KU3J3v0=
+github.com/LostImagin4tion/atlas v0.0.33/go.mod h1:FtOd0Ry45l3FeDVGVm8tf2SFWg3vHDztylE0eE3EWQ8=
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=
From 167feafe6f8702af5c97372c0c84273b8d78725e Mon Sep 17 00:00:00 2001
From: Egor Danilov <63148392+LostImagin4tion@users.noreply.github.com>
Date: Tue, 17 Feb 2026 10:18:47 +0300
Subject: [PATCH 09/14] doc/md: added ydb docs (#12)
---
doc/md/dialects.md | 6 ++
doc/md/getting-started.mdx | 33 +++++++
doc/md/ydb.md | 182 +++++++++++++++++++++++++++++++++++++
3 files changed, 221 insertions(+)
create mode 100644 doc/md/ydb.md
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..53b7529b8e
--- /dev/null
+++ b/doc/md/ydb.md
@@ -0,0 +1,182 @@
+---
+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 `ydb.Open()` function from the `entgo.io/ent/dialect/ydb` package:
+
+```go
+package main
+
+import (
+ "context"
+ "log"
+
+ "entdemo/ent"
+
+ "entgo.io/ent/dialect/ydb"
+)
+
+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)
+ }
+}
+```
+
+## Automatic Retry Mechanism
+
+YDB 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.
+
+### 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 |
+
+## YDB-Specific SQL Features
+
+The ent SQL builder supports several YDB-specific SQL constructs that are used internally
+or can be leveraged for advanced use cases.
+
+### UPSERT and REPLACE
+
+YDB doesn't support the standard `ON CONFLICT` clause. Instead, it uses `UPSERT` and `REPLACE` statements:
+
+- **UPSERT**: Inserts a new row or updates an existing row if a conflict occurs
+- **REPLACE**: Replaces the entire row if a conflict occurs
+
+Ent automatically uses `UPSERT` when you configure `OnConflict` options in your create operations.
+
+### BATCH Operations
+
+For large tables, YDB provides `BATCH UPDATE` and `BATCH DELETE` statements that process data
+in batches, minimizing lock invalidation risk. These are used internally by ent when appropriate.
+
+### Special JOIN Types
+
+YDB supports additional JOIN types beyond the standard SQL joins:
+
+| Join Type | Description |
+|-----------|-------------|
+| `LEFT SEMI JOIN` | Returns rows from left table that have matches in right table |
+| `RIGHT SEMI JOIN` | Returns rows from right table that have matches in left table |
+| `LEFT ONLY JOIN` | Returns rows from left table that have no matches in right table |
+| `RIGHT ONLY JOIN` | Returns rows from right table that have no matches in left table |
+| `EXCLUSION JOIN` | Returns rows that don't have matches in either table |
+
+### VIEW Clause for Secondary Indexes
+
+YDB allows explicit use of secondary indexes via the `VIEW` clause. This is an optimization
+hint that tells YDB to use a specific index for the query.
+
+### Named Parameters
+
+YDB uses named parameters with the `$paramName` syntax (e.g., `$p1`, `$p2`) instead of
+positional placeholders. Ent handles this automatically.
+
+## Known Limitations
+
+When using ent with YDB, be aware of the following limitations:
+
+### 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.
+
+### 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.
+
+### 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.
+
+### RowsAffected Behavior
+
+YDB's `RowsAffected()` doesn't return accurate counts. The ent driver uses the `RETURNING`
+clause internally to count affected rows when needed.
+
+### 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
From af1e0844a46e6f32cc144b01c4da7ea2bca998af Mon Sep 17 00:00:00 2001
From: Egor Danilov <63148392+LostImagin4tion@users.noreply.github.com>
Date: Tue, 17 Feb 2026 14:35:03 +0300
Subject: [PATCH 10/14] refactored retries and open template (#13)
---
dialect/dialect.go | 5 +
dialect/sql/driver.go | 64 +++-
dialect/sql/{sqlgraph => }/retry.go | 50 ++-
dialect/sql/retry_debug.go | 47 +++
dialect/{ydb/retry.go => sql/retry_ydb.go} | 50 ++-
dialect/sql/schema/ydb.go | 37 +--
dialect/sql/sqlgraph/graph.go | 232 ++++++++------
dialect/ydb/driver.go | 60 ----
dialect/ydb/driver_test.go | 297 ------------------
entc/gen/storage.go | 1 -
.../dialect/sql/feature/retryoptions.tmpl | 10 +-
entc/gen/template/dialect/sql/open.tmpl | 10 +-
entc/gen/template/dialect/sql/update.tmpl | 2 +-
entc/integration/cascadelete/ent/client.go | 11 +-
.../cascadelete/ent/comment_update.go | 4 +-
.../cascadelete/ent/post_update.go | 4 +-
.../cascadelete/ent/user_update.go | 4 +-
entc/integration/config/ent/client.go | 11 +-
entc/integration/config/ent/user_update.go | 4 +-
.../customid/ent/account_update.go | 4 +-
entc/integration/customid/ent/blob_update.go | 4 +-
.../customid/ent/bloblink_update.go | 4 +-
entc/integration/customid/ent/car_update.go | 4 +-
entc/integration/customid/ent/client.go | 11 +-
.../integration/customid/ent/device_update.go | 4 +-
entc/integration/customid/ent/doc_update.go | 4 +-
entc/integration/customid/ent/group_update.go | 4 +-
.../integration/customid/ent/intsid_update.go | 4 +-
entc/integration/customid/ent/link_update.go | 4 +-
.../customid/ent/mixinid_update.go | 4 +-
entc/integration/customid/ent/note_update.go | 4 +-
entc/integration/customid/ent/other_update.go | 4 +-
entc/integration/customid/ent/pet_update.go | 4 +-
.../customid/ent/revision_update.go | 4 +-
.../customid/ent/session_update.go | 4 +-
entc/integration/customid/ent/token_update.go | 4 +-
entc/integration/customid/ent/user_update.go | 4 +-
entc/integration/edgefield/ent/car_update.go | 4 +-
entc/integration/edgefield/ent/card_update.go | 4 +-
entc/integration/edgefield/ent/client.go | 11 +-
entc/integration/edgefield/ent/info_update.go | 4 +-
.../edgefield/ent/metadata_update.go | 4 +-
entc/integration/edgefield/ent/node_update.go | 4 +-
entc/integration/edgefield/ent/pet_update.go | 4 +-
entc/integration/edgefield/ent/post_update.go | 4 +-
.../edgefield/ent/rental_update.go | 4 +-
entc/integration/edgefield/ent/user_update.go | 4 +-
.../edgeschema/ent/attachedfile_update.go | 4 +-
entc/integration/edgeschema/ent/client.go | 11 +-
.../integration/edgeschema/ent/file_update.go | 4 +-
.../edgeschema/ent/friendship_update.go | 4 +-
.../edgeschema/ent/group_update.go | 4 +-
.../edgeschema/ent/grouptag_update.go | 4 +-
.../edgeschema/ent/process_update.go | 4 +-
.../edgeschema/ent/relationship_update.go | 4 +-
.../edgeschema/ent/relationshipinfo_update.go | 4 +-
.../integration/edgeschema/ent/role_update.go | 4 +-
.../edgeschema/ent/roleuser_update.go | 4 +-
entc/integration/edgeschema/ent/tag_update.go | 4 +-
.../edgeschema/ent/tweet_update.go | 4 +-
.../edgeschema/ent/tweetlike_update.go | 4 +-
.../edgeschema/ent/tweettag_update.go | 4 +-
.../integration/edgeschema/ent/user_update.go | 4 +-
.../edgeschema/ent/usergroup_update.go | 4 +-
.../edgeschema/ent/usertweet_update.go | 4 +-
entc/integration/ent/api_create.go | 4 +-
entc/integration/ent/api_delete.go | 2 +-
entc/integration/ent/api_query.go | 2 +-
entc/integration/ent/api_update.go | 8 +-
entc/integration/ent/builder_create.go | 4 +-
entc/integration/ent/builder_delete.go | 2 +-
entc/integration/ent/builder_query.go | 2 +-
entc/integration/ent/builder_update.go | 8 +-
entc/integration/ent/card_create.go | 4 +-
entc/integration/ent/card_delete.go | 2 +-
entc/integration/ent/card_query.go | 2 +-
entc/integration/ent/card_update.go | 8 +-
entc/integration/ent/client.go | 11 +-
entc/integration/ent/comment_create.go | 4 +-
entc/integration/ent/comment_delete.go | 2 +-
entc/integration/ent/comment_query.go | 2 +-
entc/integration/ent/comment_update.go | 8 +-
entc/integration/ent/exvaluescan_create.go | 4 +-
entc/integration/ent/exvaluescan_delete.go | 2 +-
entc/integration/ent/exvaluescan_query.go | 2 +-
entc/integration/ent/exvaluescan_update.go | 8 +-
entc/integration/ent/fieldtype_create.go | 4 +-
entc/integration/ent/fieldtype_delete.go | 2 +-
entc/integration/ent/fieldtype_query.go | 2 +-
entc/integration/ent/fieldtype_update.go | 8 +-
entc/integration/ent/file_create.go | 4 +-
entc/integration/ent/file_delete.go | 2 +-
entc/integration/ent/file_query.go | 2 +-
entc/integration/ent/file_update.go | 8 +-
entc/integration/ent/filetype_create.go | 4 +-
entc/integration/ent/filetype_delete.go | 2 +-
entc/integration/ent/filetype_query.go | 2 +-
entc/integration/ent/filetype_update.go | 8 +-
entc/integration/ent/goods_create.go | 4 +-
entc/integration/ent/goods_delete.go | 2 +-
entc/integration/ent/goods_query.go | 2 +-
entc/integration/ent/goods_update.go | 8 +-
entc/integration/ent/group_create.go | 4 +-
entc/integration/ent/group_delete.go | 2 +-
entc/integration/ent/group_query.go | 2 +-
entc/integration/ent/group_update.go | 8 +-
entc/integration/ent/groupinfo_create.go | 4 +-
entc/integration/ent/groupinfo_delete.go | 2 +-
entc/integration/ent/groupinfo_query.go | 2 +-
entc/integration/ent/groupinfo_update.go | 8 +-
entc/integration/ent/item_create.go | 4 +-
entc/integration/ent/item_delete.go | 2 +-
entc/integration/ent/item_query.go | 2 +-
entc/integration/ent/item_update.go | 8 +-
entc/integration/ent/license_create.go | 4 +-
entc/integration/ent/license_delete.go | 2 +-
entc/integration/ent/license_query.go | 2 +-
entc/integration/ent/license_update.go | 8 +-
entc/integration/ent/node_create.go | 4 +-
entc/integration/ent/node_delete.go | 2 +-
entc/integration/ent/node_query.go | 2 +-
entc/integration/ent/node_update.go | 8 +-
entc/integration/ent/pc_create.go | 4 +-
entc/integration/ent/pc_delete.go | 2 +-
entc/integration/ent/pc_query.go | 2 +-
entc/integration/ent/pc_update.go | 8 +-
entc/integration/ent/pet_create.go | 4 +-
entc/integration/ent/pet_delete.go | 2 +-
entc/integration/ent/pet_query.go | 2 +-
entc/integration/ent/pet_update.go | 8 +-
entc/integration/ent/spec_create.go | 4 +-
entc/integration/ent/spec_delete.go | 2 +-
entc/integration/ent/spec_query.go | 2 +-
entc/integration/ent/spec_update.go | 8 +-
entc/integration/ent/task_create.go | 4 +-
entc/integration/ent/task_delete.go | 2 +-
entc/integration/ent/task_query.go | 2 +-
entc/integration/ent/task_update.go | 8 +-
entc/integration/ent/user_create.go | 4 +-
entc/integration/ent/user_delete.go | 2 +-
entc/integration/ent/user_query.go | 2 +-
entc/integration/ent/user_update.go | 8 +-
entc/integration/go.mod | 2 +-
entc/integration/go.sum | 4 +-
entc/integration/hooks/ent/card_update.go | 4 +-
entc/integration/hooks/ent/client.go | 11 +-
entc/integration/hooks/ent/pet_update.go | 4 +-
entc/integration/hooks/ent/user_update.go | 4 +-
entc/integration/idtype/ent/client.go | 11 +-
entc/integration/idtype/ent/user_update.go | 4 +-
entc/integration/integration_test.go | 16 +-
entc/integration/json/ent/client.go | 11 +-
entc/integration/json/ent/user_update.go | 4 +-
entc/integration/migrate/entv1/car_update.go | 4 +-
entc/integration/migrate/entv1/client.go | 11 +-
.../migrate/entv1/conversion_update.go | 4 +-
.../migrate/entv1/customtype_update.go | 4 +-
entc/integration/migrate/entv1/user_update.go | 4 +-
entc/integration/migrate/entv2/blog_update.go | 4 +-
entc/integration/migrate/entv2/car_update.go | 4 +-
entc/integration/migrate/entv2/client.go | 11 +-
.../migrate/entv2/conversion_update.go | 4 +-
.../migrate/entv2/customtype_update.go | 4 +-
.../integration/migrate/entv2/group_update.go | 4 +-
.../integration/migrate/entv2/media_update.go | 4 +-
entc/integration/migrate/entv2/pet_update.go | 4 +-
entc/integration/migrate/entv2/user_update.go | 4 +-
entc/integration/migrate/entv2/zoo_update.go | 4 +-
entc/integration/migrate/migrate_test.go | 6 +-
entc/integration/migrate/versioned/client.go | 11 +-
.../migrate/versioned/group_update.go | 4 +-
.../migrate/versioned/user_update.go | 4 +-
entc/integration/multischema/ent/client.go | 11 +-
.../multischema/ent/friendship_update.go | 4 +-
.../multischema/ent/group_update.go | 4 +-
.../multischema/ent/parent_update.go | 4 +-
.../integration/multischema/ent/pet_update.go | 4 +-
.../multischema/ent/user_update.go | 4 +-
.../multischema/versioned/client.go | 11 +-
.../versioned/friendship_update.go | 4 +-
.../multischema/versioned/group_update.go | 4 +-
.../multischema/versioned/pet_update.go | 4 +-
.../multischema/versioned/user_update.go | 4 +-
entc/integration/privacy/ent/client.go | 11 +-
entc/integration/privacy/ent/task_update.go | 4 +-
entc/integration/privacy/ent/team_update.go | 4 +-
entc/integration/privacy/ent/user_update.go | 4 +-
entc/integration/template/ent/client.go | 11 +-
entc/integration/template/ent/group_update.go | 4 +-
entc/integration/template/ent/pet_update.go | 4 +-
entc/integration/template/ent/user_update.go | 4 +-
examples/compositetypes/ent/client.go | 11 +-
examples/compositetypes/ent/user_update.go | 4 +-
examples/domaintypes/ent/client.go | 11 +-
examples/domaintypes/ent/user_update.go | 4 +-
examples/edgeindex/ent/city_update.go | 4 +-
examples/edgeindex/ent/client.go | 11 +-
examples/edgeindex/ent/street_update.go | 4 +-
examples/encryptfield/ent/client.go | 11 +-
examples/encryptfield/ent/user_update.go | 4 +-
examples/entcpkg/ent/client.go | 11 +-
examples/entcpkg/ent/user_update.go | 4 +-
examples/enumtypes/ent/client.go | 11 +-
examples/enumtypes/ent/user_update.go | 4 +-
examples/extensions/ent/client.go | 11 +-
examples/extensions/ent/user_update.go | 4 +-
examples/fs/ent/client.go | 11 +-
examples/fs/ent/file_update.go | 4 +-
examples/functionalidx/ent/client.go | 11 +-
examples/functionalidx/ent/user_update.go | 4 +-
examples/go.mod | 2 +-
examples/go.sum | 4 +-
examples/jsonencode/ent/card_update.go | 4 +-
examples/jsonencode/ent/client.go | 11 +-
examples/jsonencode/ent/pet_update.go | 4 +-
examples/jsonencode/ent/user_update.go | 4 +-
examples/m2m2types/ent/client.go | 11 +-
examples/m2m2types/ent/group_update.go | 4 +-
examples/m2m2types/ent/user_update.go | 4 +-
examples/m2mbidi/ent/client.go | 11 +-
examples/m2mbidi/ent/user_update.go | 4 +-
examples/m2mrecur/ent/client.go | 11 +-
examples/m2mrecur/ent/user_update.go | 4 +-
examples/migration/ent/card_update.go | 4 +-
examples/migration/ent/client.go | 11 +-
examples/migration/ent/payment_update.go | 4 +-
examples/migration/ent/pet_update.go | 4 +-
examples/migration/ent/session_update.go | 4 +-
.../migration/ent/sessiondevice_update.go | 4 +-
examples/migration/ent/user_update.go | 4 +-
examples/o2m2types/ent/client.go | 11 +-
examples/o2m2types/ent/pet_update.go | 4 +-
examples/o2m2types/ent/user_update.go | 4 +-
examples/o2mrecur/ent/client.go | 11 +-
examples/o2mrecur/ent/node_update.go | 4 +-
examples/o2o2types/ent/card_update.go | 4 +-
examples/o2o2types/ent/client.go | 11 +-
examples/o2o2types/ent/user_update.go | 4 +-
examples/o2obidi/ent/client.go | 11 +-
examples/o2obidi/ent/user_update.go | 4 +-
examples/o2orecur/ent/client.go | 11 +-
examples/o2orecur/ent/node_update.go | 4 +-
examples/privacyadmin/ent/client.go | 11 +-
examples/privacyadmin/ent/user_update.go | 4 +-
examples/privacytenant/ent/client.go | 11 +-
examples/privacytenant/ent/group_update.go | 4 +-
examples/privacytenant/ent/tenant_update.go | 4 +-
examples/privacytenant/ent/user_update.go | 4 +-
examples/rls/ent/client.go | 11 +-
examples/rls/ent/tenant_update.go | 4 +-
examples/rls/ent/user_update.go | 4 +-
examples/start/ent/car_update.go | 4 +-
examples/start/ent/client.go | 11 +-
examples/start/ent/group_update.go | 4 +-
examples/start/ent/user_update.go | 4 +-
examples/traversal/ent/client.go | 11 +-
examples/traversal/ent/group_update.go | 4 +-
examples/traversal/ent/pet_update.go | 4 +-
examples/traversal/ent/user_update.go | 4 +-
examples/triggers/ent/client.go | 11 +-
examples/triggers/ent/user_update.go | 4 +-
examples/triggers/ent/userauditlog_update.go | 4 +-
examples/version/ent/client.go | 11 +-
examples/version/ent/user_update.go | 4 +-
examples/viewcomposite/ent/client.go | 11 +-
examples/viewcomposite/ent/pet_update.go | 4 +-
examples/viewcomposite/ent/user_update.go | 4 +-
examples/viewschema/ent/client.go | 11 +-
examples/viewschema/ent/pet_update.go | 4 +-
examples/viewschema/ent/user_update.go | 4 +-
examples/ydb/ent/client.go | 11 +-
examples/ydb/ent/episode_create.go | 5 +-
examples/ydb/ent/episode_delete.go | 2 +-
examples/ydb/ent/episode_query.go | 2 +-
examples/ydb/ent/episode_update.go | 8 +-
examples/ydb/ent/season_create.go | 5 +-
examples/ydb/ent/season_delete.go | 2 +-
examples/ydb/ent/season_query.go | 2 +-
examples/ydb/ent/season_update.go | 8 +-
examples/ydb/ent/series_create.go | 5 +-
examples/ydb/ent/series_delete.go | 2 +-
examples/ydb/ent/series_query.go | 2 +-
examples/ydb/ent/series_update.go | 8 +-
go.mod | 2 +-
go.sum | 4 +-
285 files changed, 835 insertions(+), 1444 deletions(-)
rename dialect/sql/{sqlgraph => }/retry.go (59%)
create mode 100644 dialect/sql/retry_debug.go
rename dialect/{ydb/retry.go => sql/retry_ydb.go} (64%)
delete mode 100644 dialect/ydb/driver.go
delete mode 100644 dialect/ydb/driver_test.go
diff --git a/dialect/dialect.go b/dialect/dialect.go
index 79bceeb405..270b0cfe33 100644
--- a/dialect/dialect.go
+++ b/dialect/dialect.go
@@ -88,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/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/sqlgraph/retry.go b/dialect/sql/retry.go
similarity index 59%
rename from dialect/sql/sqlgraph/retry.go
rename to dialect/sql/retry.go
index 449e4dffbd..22fe7ece75 100644
--- a/dialect/sql/sqlgraph/retry.go
+++ b/dialect/sql/retry.go
@@ -2,10 +2,11 @@
// 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 sqlgraph
+package sql
import (
"context"
+ "database/sql"
"entgo.io/ent/dialect"
)
@@ -31,6 +32,18 @@ type RetryExecutor interface {
) 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,
@@ -41,12 +54,37 @@ type RetryExecutorGetter interface {
RetryExecutor() RetryExecutor
}
-// getRetryExecutor returns the RetryExecutor for the given driver if available.
-func getRetryExecutor(drv dialect.Driver) RetryExecutor {
- if reg, ok := drv.(RetryExecutorGetter); ok {
- return reg.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 nil
+ return drv, nil
}
// RetryConfig holds retry configuration for sqlgraph operations.
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/ydb/retry.go b/dialect/sql/retry_ydb.go
similarity index 64%
rename from dialect/ydb/retry.go
rename to dialect/sql/retry_ydb.go
index dc0dde85e0..c2a58b3a0b 100644
--- a/dialect/ydb/retry.go
+++ b/dialect/sql/retry_ydb.go
@@ -2,31 +2,25 @@
// 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 ydb
+package sql
import (
"context"
"database/sql"
"entgo.io/ent/dialect"
- entSql "entgo.io/ent/dialect/sql"
"github.com/ydb-platform/ydb-go-sdk/v3/retry"
)
-// RetryExecutor implements sqlgraph.RetryExecutor for YDB
-type RetryExecutor struct {
+// YDBRetryExecutor implements sqlgraph.YDBRetryExecutor for YDB
+type YDBRetryExecutor struct {
db *sql.DB
}
-// NewRetryExecutor creates a new RetryExecutor with the given database connection
-func NewRetryExecutor(db *sql.DB) *RetryExecutor {
- return &RetryExecutor{db: 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 *RetryExecutor) Do(
+func (r *YDBRetryExecutor) Do(
ctx context.Context,
fn func(ctx context.Context, drv dialect.Driver) error,
opts ...any,
@@ -35,7 +29,7 @@ func (r *RetryExecutor) Do(
ctx,
r.db,
func(ctx context.Context, conn *sql.Conn) error {
- return fn(ctx, NewRetryDriver(conn))
+ return fn(ctx, newConnRetryDriver(conn))
},
retry.WithDoRetryOptions(toRetryOptions(opts)...),
)
@@ -44,7 +38,7 @@ func (r *RetryExecutor) Do(
// 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 *RetryExecutor) DoTx(
+func (r *YDBRetryExecutor) DoTx(
ctx context.Context,
fn func(ctx context.Context, drv dialect.Driver) error,
opts ...any,
@@ -53,7 +47,7 @@ func (r *RetryExecutor) DoTx(
ctx,
r.db,
func(ctx context.Context, tx *sql.Tx) error {
- return fn(ctx, NewTxRetryDriver(tx))
+ return fn(ctx, newTxRetryDriver(tx))
},
retry.WithDoTxRetryOptions(toRetryOptions(opts)...),
)
@@ -70,41 +64,41 @@ func toRetryOptions(opts []any) []retry.Option {
return retryOpts
}
-// RetryDriver is designed for use only in sqlgraph,
+// ydbRetryDriver is designed for use only in sqlgraph,
// specifically - in retry.DoTx callbacks
-type RetryDriver struct {
- entSql.Conn
+type ydbRetryDriver struct {
+ Conn
}
-var _ dialect.Driver = (*RetryDriver)(nil)
+var _ dialect.Driver = (*ydbRetryDriver)(nil)
-// NewTxRetryDriver creates a new RetryDriver from a transaction.
-func NewTxRetryDriver(tx *sql.Tx) *RetryDriver {
- return &RetryDriver{
- Conn: entSql.Conn{ExecQuerier: tx},
+// newConnRetryDriver creates a new RetryDriver from a database connection.
+func newConnRetryDriver(conn *sql.Conn) *ydbRetryDriver {
+ return &ydbRetryDriver{
+ Conn: Conn{ExecQuerier: conn},
}
}
-// NewRetryDriver creates a new RetryDriver from a database connection.
-func NewRetryDriver(conn *sql.Conn) *RetryDriver {
- return &RetryDriver{
- Conn: entSql.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 *RetryDriver) Tx(ctx context.Context) (dialect.Tx, error) {
+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 *RetryDriver) Close() error {
+func (d *ydbRetryDriver) Close() error {
return nil
}
// Dialect returns the YDB dialect name.
-func (d *RetryDriver) Dialect() string {
+func (d *ydbRetryDriver) Dialect() string {
return dialect.YDB
}
diff --git a/dialect/sql/schema/ydb.go b/dialect/sql/schema/ydb.go
index df835b415c..95a7494d4a 100644
--- a/dialect/sql/schema/ydb.go
+++ b/dialect/sql/schema/ydb.go
@@ -6,12 +6,12 @@ package schema
import (
"context"
+ "database/sql"
"fmt"
"strings"
"entgo.io/ent/dialect"
entsql "entgo.io/ent/dialect/sql"
- entdrv "entgo.io/ent/dialect/ydb"
"entgo.io/ent/schema/field"
"ariga.io/atlas/sql/migrate"
@@ -67,32 +67,29 @@ func (d *YDB) tableExist(ctx context.Context, conn dialect.ExecQuerier, name str
// atOpen returns a custom Atlas migrate.Driver for YDB.
func (d *YDB) atOpen(conn dialect.ExecQuerier) (migrate.Driver, error) {
- ydbDriver := unwrapYDBDriver(conn)
- if ydbDriver == nil {
- ydbDriver = unwrapYDBDriver(d.Driver)
+ sqlDB := unwrapDB(conn)
+ if sqlDB == nil {
+ sqlDB = unwrapDB(d.Driver)
}
- if ydbDriver == nil {
- return nil, fmt.Errorf("expected dialect/ydb.YDBDriver, but got %T", conn)
+ if sqlDB == nil {
+ return nil, fmt.Errorf("ydb: cannot get *sql.DB from %T (driver: %T)", conn, d.Driver)
}
-
- return atlas.Open(
- ydbDriver.NativeDriver(),
- ydbDriver.DB(),
- )
+ return atlas.Open(sqlDB)
}
-func unwrapYDBDriver(driver any) *entdrv.YDBDriver {
- switch drv := driver.(type) {
- case *entdrv.YDBDriver:
- return drv
+func unwrapDB(db any) *sql.DB {
+ switch casted := db.(type) {
+ case interface{ DB() *sql.DB }:
+ return casted.DB()
case *YDB:
- return unwrapYDBDriver(drv.Driver)
- case *WriteDriver:
- return unwrapYDBDriver(drv.Driver)
+ return unwrapDB(casted.Driver)
case *dialect.DebugDriver:
- return unwrapYDBDriver(drv.Driver)
+ return unwrapDB(casted.Driver)
+ case *WriteDriver:
+ return unwrapDB(casted.Driver)
+ default:
+ return nil
}
- return nil
}
func (d *YDB) atTable(table1 *Table, table2 *schema.Table) {
diff --git a/dialect/sql/sqlgraph/graph.go b/dialect/sql/sqlgraph/graph.go
index 250867c5a4..c70293bfc2 100644
--- a/dialect/sql/sqlgraph/graph.go
+++ b/dialect/sql/sqlgraph/graph.go
@@ -776,7 +776,7 @@ type (
//
OnConflict []sql.ConflictOption
- RetryConfig RetryConfig
+ RetryConfig sql.RetryConfig
}
// BatchCreateSpec holds the information for creating
@@ -795,7 +795,7 @@ type (
//
OnConflict []sql.ConflictOption
- RetryConfig RetryConfig
+ RetryConfig sql.RetryConfig
}
)
@@ -816,32 +816,60 @@ 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 {
- op := 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)
- }
- return execWithRetryTx(ctx, drv, op, spec.RetryConfig.Options)
+ 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 {
- op := 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)
- }
- return execWithRetryTx(ctx, drv, op, spec.RetryConfig.Options)
+ 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 if available, otherwise executes directly.
-func execWithRetryTx(ctx context.Context, drv dialect.Driver, op func(context.Context, dialect.Driver) error, opts []any) error {
- if retry := getRetryExecutor(drv); retry != nil {
+// 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 (
// EdgeMut defines edge mutations.
EdgeMut struct {
@@ -868,7 +896,7 @@ type (
ScanValues func(columns []string) ([]any, error)
Assign func(columns []string, values []any) error
- RetryConfig RetryConfig
+ RetryConfig sql.RetryConfig
}
)
@@ -924,22 +952,23 @@ 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 {
- op := 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()
- }
- if retry := getRetryExecutor(drv); retry != nil {
- return retry.DoTx(ctx, op, spec.RetryConfig.Options...)
- }
- return op(ctx, drv)
+ 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.
@@ -955,13 +984,7 @@ func UpdateNodes(ctx context.Context, drv dialect.Driver, spec *UpdateSpec) (int
affected = n
return nil
}
- if retry := getRetryExecutor(drv); retry != nil {
- if err := retry.DoTx(ctx, op, spec.RetryConfig.Options...); err != nil {
- return 0, err
- }
- return affected, nil
- }
- if err := op(ctx, drv); err != nil {
+ if err := execWithRetryTx(ctx, drv, spec.RetryConfig.Options, op); err != nil {
return 0, err
}
return affected, nil
@@ -978,12 +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)
- RetryConfig RetryConfig
+ RetryConfig sql.RetryConfig
}
// NewDeleteSpec creates a new node deletion spec.
@@ -1031,13 +1060,7 @@ func DeleteNodes(ctx context.Context, drv dialect.Driver, spec *DeleteSpec) (int
affected = int(n)
return nil
}
- if retry := getRetryExecutor(drv); retry != nil {
- if err := retry.DoTx(ctx, op, spec.RetryConfig.Options...); err != nil {
- return 0, err
- }
- return affected, nil
- }
- if err := op(ctx, drv); err != nil {
+ if err := execWithRetryTx(ctx, drv, spec.RetryConfig.Options, op); err != nil {
return 0, err
}
return affected, nil
@@ -1059,7 +1082,7 @@ type QuerySpec struct {
ScanValues func(columns []string) ([]any, error)
Assign func(columns []string, values []any) error
- RetryConfig RetryConfig
+ RetryConfig sql.RetryConfig
}
// NewQuerySpec creates a new node query spec.
@@ -1075,15 +1098,16 @@ 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 {
- op := 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)
- }
- if retry := getRetryExecutor(drv); retry != nil {
- return retry.Do(ctx, op, spec.RetryConfig.Options...)
- }
- return op(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.
@@ -1099,13 +1123,7 @@ func CountNodes(ctx context.Context, drv dialect.Driver, spec *QuerySpec) (int,
count = n
return nil
}
- if retry := getRetryExecutor(drv); retry != nil {
- if err := retry.Do(ctx, op, spec.RetryConfig.Options...); err != nil {
- return 0, err
- }
- return count, nil
- }
- if err := op(ctx, drv); err != nil {
+ if err := execWithRetry(ctx, drv, spec.RetryConfig.Options, op); err != nil {
return 0, err
}
return count, nil
@@ -1114,10 +1132,11 @@ func CountNodes(ctx context.Context, drv dialect.Driver, spec *QuerySpec) (int,
// 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.
@@ -1125,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 {
@@ -1439,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
}
diff --git a/dialect/ydb/driver.go b/dialect/ydb/driver.go
deleted file mode 100644
index 1a8a6f12df..0000000000
--- a/dialect/ydb/driver.go
+++ /dev/null
@@ -1,60 +0,0 @@
-// 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 ydb
-
-import (
- "context"
- "database/sql"
-
- "entgo.io/ent/dialect"
- entSql "entgo.io/ent/dialect/sql"
- "entgo.io/ent/dialect/sql/sqlgraph"
- ydb "github.com/ydb-platform/ydb-go-sdk/v3"
-)
-
-// YDBDriver is a [dialect.Driver] implementation for YDB.
-type YDBDriver struct {
- *entSql.Driver
-
- nativeDriver *ydb.Driver
- retryExecutor *RetryExecutor
-}
-
-var _ sqlgraph.RetryExecutorGetter = (*YDBDriver)(nil)
-
-func Open(ctx context.Context, dsn string) (*YDBDriver, error) {
- nativeDriver, err := ydb.Open(ctx, 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
- }
-
- dbSQLDriver := sql.OpenDB(conn)
-
- return &YDBDriver{
- Driver: entSql.OpenDB(dialect.YDB, dbSQLDriver),
- nativeDriver: nativeDriver,
- retryExecutor: NewRetryExecutor(dbSQLDriver),
- }, nil
-}
-
-func (y *YDBDriver) NativeDriver() *ydb.Driver {
- return y.nativeDriver
-}
-
-// RetryExecutor returns the RetryExecutor for this driver.
-// This allows sqlgraph to automatically wrap operations with YDB retry logic.
-func (y *YDBDriver) RetryExecutor() sqlgraph.RetryExecutor {
- return y.retryExecutor
-}
diff --git a/dialect/ydb/driver_test.go b/dialect/ydb/driver_test.go
deleted file mode 100644
index a012925593..0000000000
--- a/dialect/ydb/driver_test.go
+++ /dev/null
@@ -1,297 +0,0 @@
-// 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 ydb
-
-import (
- "context"
- "fmt"
- "testing"
-
- "entgo.io/ent/dialect"
- entSql "entgo.io/ent/dialect/sql"
-
- "github.com/DATA-DOG/go-sqlmock"
- "github.com/stretchr/testify/require"
-)
-
-func TestOpenAndClose(t *testing.T) {
- // Given
- db, mock, err := sqlmock.New()
- require.NoError(t, err)
- defer db.Close()
-
- driver := &YDBDriver{
- Driver: entSql.OpenDB(dialect.YDB, db),
- }
-
- // When
- mock.ExpectClose()
- err = driver.Close()
-
- // Then - verify closed
- require.NoError(t, err, "should close connection")
- require.NoError(t, mock.ExpectationsWereMet())
-}
-
-func TestExecCreateTable(t *testing.T) {
- // Given
- db, mock, err := sqlmock.New()
- require.NoError(t, err)
- defer db.Close()
-
- ctx := context.Background()
- driver := &YDBDriver{Driver: entSql.OpenDB(dialect.YDB, db)}
-
- // When
- mock.ExpectExec("DROP TABLE IF EXISTS test_users").
- WillReturnResult(sqlmock.NewResult(0, 0))
-
- mock.ExpectExec("CREATE TABLE test_users").
- WillReturnResult(sqlmock.NewResult(0, 0))
-
- _ = driver.Exec(ctx, "DROP TABLE IF EXISTS test_users", []any{}, nil)
- err = driver.Exec(ctx, `CREATE TABLE test_users (
- id Int64 NOT NULL,
- name Utf8,
- age Int32,
- PRIMARY KEY (id)
- )`, []any{}, nil)
- require.NoError(t, err, "CREATE TABLE should execute without err")
-
- // Then - verify table created
- mock.ExpectQuery("SELECT 1 FROM test_users").
- WillReturnRows(sqlmock.NewRows([]string{"1"}))
-
- var rows entSql.Rows
- err = driver.Query(ctx, "SELECT 1 FROM test_users", []any{}, &rows)
- require.NoError(t, err, "created table should exist")
- rows.Close()
-
- require.NoError(t, mock.ExpectationsWereMet())
-}
-
-func TestExecInsert(t *testing.T) {
- // Given
- db, mock, err := sqlmock.New()
- require.NoError(t, err)
- defer db.Close()
-
- ctx := context.Background()
- driver := &YDBDriver{Driver: entSql.OpenDB(dialect.YDB, db)}
-
- // When
- mock.ExpectExec("INSERT INTO test_users").
- WillReturnResult(sqlmock.NewResult(1, 1))
-
- insertQuery := `INSERT INTO test_users (id, name, age) VALUES (1, 'Alice', 30)`
- err = driver.Exec(ctx, insertQuery, []any{}, nil)
- require.NoError(t, err, "INSERT data execute without err")
-
- // Then - verify row count
- mock.ExpectQuery("SELECT COUNT\\(\\*\\) AS").
- WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(1))
-
- var rows entSql.Rows
- err = driver.Query(ctx, "SELECT COUNT(*) AS `count` FROM test_users", []any{}, &rows)
- require.NoError(t, err, "SELECT COUNT(*) should execute without err")
-
- require.True(t, rows.Next(), "Result should have at least 1 row")
- var count uint64
- err = rows.Scan(&count)
- require.NoError(t, err)
- require.Equal(t, uint64(1), count, "Table should contain exactly 1 row")
- rows.Close()
-
- require.NoError(t, mock.ExpectationsWereMet())
-}
-
-func TestExecUpdate(t *testing.T) {
- // Given
- db, mock, err := sqlmock.New()
- require.NoError(t, err)
- defer db.Close()
-
- ctx := context.Background()
- drv := &YDBDriver{Driver: entSql.OpenDB(dialect.YDB, db)}
-
- mock.ExpectExec("INSERT INTO test_users").
- WillReturnResult(sqlmock.NewResult(1, 1))
-
- insertDataQuery := "INSERT INTO test_users (id, name, age) VALUES (1, 'Alice', 30)"
- require.NoError(t, drv.Exec(ctx, insertDataQuery, []any{}, nil))
-
- // When
- mock.ExpectExec("UPDATE test_users SET age = 31 WHERE id = 1").
- WillReturnResult(sqlmock.NewResult(0, 1))
-
- updateQuery := `UPDATE test_users SET age = 31 WHERE id = 1`
- err = drv.Exec(ctx, updateQuery, []any{}, nil)
- require.NoError(t, err, "should update data")
-
- // Then
- mock.ExpectQuery("SELECT \\* FROM test_users").
- WillReturnRows(sqlmock.NewRows([]string{"id", "name", "age"}).
- AddRow(1, "Alice", 31))
-
- var rows entSql.Rows
- err = drv.Query(ctx, "SELECT * FROM test_users", []any{}, &rows)
- require.NoError(t, err)
-
- require.True(t, rows.Next())
- var id, age int64
- var name string
- err = rows.Scan(&id, &name, &age)
- require.NoError(t, err)
- require.Equal(t, int64(31), age, "Age should've been changed")
- rows.Close()
-
- require.NoError(t, mock.ExpectationsWereMet())
-}
-
-func TestExecDelete(t *testing.T) {
- // Given
- db, mock, err := sqlmock.New()
- require.NoError(t, err)
- defer db.Close()
-
- ctx := context.Background()
- drv := &YDBDriver{Driver: entSql.OpenDB(dialect.YDB, db)}
-
- mock.ExpectExec("INSERT INTO test_users").
- WillReturnResult(sqlmock.NewResult(1, 1))
-
- insertDataQuery := "INSERT INTO test_users (id, name, age) VALUES (1, 'Alice', 30)"
- require.NoError(t, drv.Exec(ctx, insertDataQuery, []any{}, nil))
-
- // When
- mock.ExpectExec("DELETE FROM test_users WHERE id = 1").
- WillReturnResult(sqlmock.NewResult(0, 1))
-
- deleteQuery := `DELETE FROM test_users WHERE id = 1`
- err = drv.Exec(ctx, deleteQuery, []any{}, nil)
- require.NoError(t, err, "DELETE request should execute without err")
-
- // Then
- mock.ExpectQuery("SELECT COUNT\\(\\*\\)").
- WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(0))
-
- var rows entSql.Rows
- err = drv.Query(ctx, "SELECT COUNT(*) AS `count` FROM test_users", []any{}, &rows)
- require.NoError(t, err)
- require.True(t, rows.Next())
- var count uint64
- err = rows.Scan(&count)
- require.NoError(t, err)
- require.Equal(t, uint64(0), count, "Table should be empty after DELETE")
- rows.Close()
-
- require.NoError(t, mock.ExpectationsWereMet())
-}
-
-func TestQueryEmptyTable(t *testing.T) {
- // Given
- db, mock, err := sqlmock.New()
- require.NoError(t, err)
- defer db.Close()
-
- ctx := context.Background()
- drv := &YDBDriver{Driver: entSql.OpenDB(dialect.YDB, db)}
-
- // When
- mock.ExpectQuery("SELECT \\* FROM test_users").
- WillReturnRows(sqlmock.NewRows([]string{"id", "name", "age"}))
-
- var rows entSql.Rows
- err = drv.Query(ctx, "SELECT * FROM test_users", []any{}, &rows)
-
- // Then
- require.NoError(t, err, "SELECT data should execute without err")
-
- counter := 0
- for rows.Next() {
- counter++
- }
- require.Equal(t, 0, counter, "Table should be empty")
- rows.Close()
-
- require.NoError(t, mock.ExpectationsWereMet())
-}
-
-func TestExecMultipleInserts(t *testing.T) {
- // Given
- db, mock, err := sqlmock.New()
- require.NoError(t, err)
- defer db.Close()
-
- ctx := context.Background()
- drv := &YDBDriver{Driver: entSql.OpenDB(dialect.YDB, db)}
-
- // When
- for i := 0; i < 10; i++ {
- insertQuery := fmt.Sprintf("INSERT INTO test_users (id, name, age) VALUES (%d, 'User%d', 20)", i, i)
- mock.ExpectExec("INSERT INTO test_users").
- WillReturnResult(sqlmock.NewResult(int64(i), 1))
-
- err := drv.Exec(ctx, insertQuery, []any{}, nil)
- require.NoError(t, err)
- }
-
- // Then
- mock.ExpectQuery("SELECT COUNT\\(\\*\\)").
- WillReturnRows(sqlmock.NewRows([]string{"count"}).AddRow(10))
-
- var rows entSql.Rows
- err = drv.Query(ctx, "SELECT COUNT(*) AS `count` FROM test_users", []any{}, &rows)
- require.NoError(t, err)
- require.True(t, rows.Next())
- var count uint64
- err = rows.Scan(&count)
- require.NoError(t, err)
- require.Equal(t, uint64(10), count, "Table should contain exactly 10 rows")
- rows.Close()
-
- require.NoError(t, mock.ExpectationsWereMet())
-}
-
-func TestQueryInvalidQuery(t *testing.T) {
- // Given
- db, mock, err := sqlmock.New()
- require.NoError(t, err)
- defer db.Close()
-
- ctx := context.Background()
- drv := &YDBDriver{Driver: entSql.OpenDB(dialect.YDB, db)}
-
- // When
- invalidQuery := "SELECT * FROM non_existent_table"
- mock.ExpectQuery("SELECT \\* FROM non_existent_table").
- WillReturnError(fmt.Errorf("table not found"))
-
- var rows entSql.Rows
- err = drv.Query(ctx, invalidQuery, []any{}, &rows)
-
- // Then
- require.Error(t, err, "should return error for invalid query")
- require.NoError(t, mock.ExpectationsWereMet())
-}
-
-func TestContextCancellation(t *testing.T) {
- // Given
- db, _, err := sqlmock.New()
- require.NoError(t, err)
- defer db.Close()
-
- ctx := context.Background()
- drv := &YDBDriver{Driver: entSql.OpenDB(dialect.YDB, db)}
-
- // When
- cancelCtx, cancel := context.WithCancel(ctx)
- cancel()
-
- // Then
- err = drv.Exec(cancelCtx, "SELECT 1", []any{}, nil)
- require.Error(t, err, "should return error when context is cancelled")
- require.Contains(t, err.Error(), "context canceled")
-}
diff --git a/entc/gen/storage.go b/entc/gen/storage.go
index 6fcde470fa..bbf89356ad 100644
--- a/entc/gen/storage.go
+++ b/entc/gen/storage.go
@@ -60,7 +60,6 @@ var drivers = []*Storage{
"entgo.io/ent/dialect/sql",
"entgo.io/ent/dialect/sql/sqlgraph",
"entgo.io/ent/dialect/sql/sqljson",
- "entgo.io/ent/dialect/ydb",
"entgo.io/ent/schema/field",
},
SchemaMode: Unique | Indexes | Cascade | Migrate,
diff --git a/entc/gen/template/dialect/sql/feature/retryoptions.tmpl b/entc/gen/template/dialect/sql/feature/retryoptions.tmpl
index fa066279da..e817cea5bf 100644
--- a/entc/gen/template/dialect/sql/feature/retryoptions.tmpl
+++ b/entc/gen/template/dialect/sql/feature/retryoptions.tmpl
@@ -12,35 +12,35 @@ in the LICENSE file in the root directory of this source tree.
{{/* Additional fields for the create builder. */}}
{{ define "dialect/sql/create/fields/additional/retryoptions" -}}
{{- if $.FeatureEnabled "sql/retryoptions" }}
- retryConfig sqlgraph.RetryConfig
+ 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 sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
{{- end }}
{{- end }}
{{/* Additional fields for the update builder. */}}
{{ define "dialect/sql/update/fields/additional/retryoptions" -}}
{{- if $.FeatureEnabled "sql/retryoptions" }}
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
{{- end }}
{{- end }}
{{/* Additional fields for the query builder. */}}
{{ define "dialect/sql/query/fields/additional/retryoptions" -}}
{{- if $.FeatureEnabled "sql/retryoptions" }}
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
{{- end }}
{{- end }}
{{/* Additional fields for the delete builder. */}}
{{ define "dialect/sql/delete/fields/additional/retryoptions" -}}
{{- if $.FeatureEnabled "sql/retryoptions" }}
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
{{- end }}
{{- end }}
diff --git a/entc/gen/template/dialect/sql/open.tmpl b/entc/gen/template/dialect/sql/open.tmpl
index 9be135d5b2..d64b2417be 100644
--- a/entc/gen/template/dialect/sql/open.tmpl
+++ b/entc/gen/template/dialect/sql/open.tmpl
@@ -7,15 +7,7 @@ in the LICENSE file in the root directory of this source tree.
{{/* gotype: entgo.io/ent/entc/gen.Graph */}}
{{ define "dialect/sql/client/open" }}
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ drv, err := sql.Open(driverName, dataSourceName)
if err != nil {
return nil, err
}
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 554ee80e20..2a7a6da62d 100644
--- a/entc/integration/cascadelete/ent/client.go
+++ b/entc/integration/cascadelete/ent/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/cascadelete/ent/comment"
"entgo.io/ent/entc/integration/cascadelete/ent/post"
"entgo.io/ent/entc/integration/cascadelete/ent/user"
@@ -114,15 +113,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 1b9dee98cb..9dee134e80 100644
--- a/entc/integration/config/ent/client.go
+++ b/entc/integration/config/ent/client.go
@@ -18,7 +18,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/config/ent/user"
)
@@ -105,15 +104,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 85427b4f00..1c0bbeceb2 100644
--- a/entc/integration/customid/ent/client.go
+++ b/entc/integration/customid/ent/client.go
@@ -23,7 +23,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/customid/ent/account"
"entgo.io/ent/entc/integration/customid/ent/blob"
"entgo.io/ent/entc/integration/customid/ent/bloblink"
@@ -174,15 +173,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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/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 eaf9bcb348..85ad70493c 100644
--- a/entc/integration/edgefield/ent/client.go
+++ b/entc/integration/edgefield/ent/client.go
@@ -20,7 +20,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/edgefield/ent/car"
"entgo.io/ent/entc/integration/edgefield/ent/card"
"entgo.io/ent/entc/integration/edgefield/ent/info"
@@ -139,15 +138,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 3a8ad32449..e7ef36af0f 100644
--- a/entc/integration/edgeschema/ent/client.go
+++ b/entc/integration/edgeschema/ent/client.go
@@ -20,7 +20,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/edgeschema/ent/attachedfile"
"entgo.io/ent/entc/integration/edgeschema/ent/file"
"entgo.io/ent/entc/integration/edgeschema/ent/friendship"
@@ -171,15 +170,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 11995cb813..40511ea5bf 100644
--- a/entc/integration/ent/api_create.go
+++ b/entc/integration/ent/api_create.go
@@ -22,7 +22,7 @@ type APICreate struct {
config
mutation *APIMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
@@ -219,7 +219,7 @@ type APICreateBulk struct {
config
err error
builders []*APICreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
diff --git a/entc/integration/ent/api_delete.go b/entc/integration/ent/api_delete.go
index ea896eca93..e4fee7c501 100644
--- a/entc/integration/ent/api_delete.go
+++ b/entc/integration/ent/api_delete.go
@@ -21,7 +21,7 @@ type APIDelete struct {
config
hooks []Hook
mutation *APIMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the APIDelete builder.
diff --git a/entc/integration/ent/api_query.go b/entc/integration/ent/api_query.go
index 256d3f8281..a8fa9ae8a5 100644
--- a/entc/integration/ent/api_query.go
+++ b/entc/integration/ent/api_query.go
@@ -28,7 +28,7 @@ type APIQuery struct {
inters []Interceptor
predicates []predicate.Api
modifiers []func(*sql.Selector)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/entc/integration/ent/api_update.go b/entc/integration/ent/api_update.go
index ad788a6f45..928383bf25 100644
--- a/entc/integration/ent/api_update.go
+++ b/entc/integration/ent/api_update.go
@@ -24,7 +24,7 @@ type APIUpdate struct {
hooks []Hook
mutation *APIMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the APIUpdate builder.
@@ -90,7 +90,7 @@ 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}
@@ -108,7 +108,7 @@ type APIUpdateOne struct {
hooks []Hook
mutation *APIMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Mutation returns the APIMutation object of the builder.
@@ -201,7 +201,7 @@ func (_u *APIUpdateOne) sqlSave(ctx context.Context) (_node *Api, 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{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 ce42a6c5c8..c926f3f72d 100644
--- a/entc/integration/ent/builder_create.go
+++ b/entc/integration/ent/builder_create.go
@@ -22,7 +22,7 @@ type BuilderCreate struct {
config
mutation *BuilderMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
@@ -219,7 +219,7 @@ type BuilderCreateBulk struct {
config
err error
builders []*BuilderCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
diff --git a/entc/integration/ent/builder_delete.go b/entc/integration/ent/builder_delete.go
index e2df610c9b..45427b58fc 100644
--- a/entc/integration/ent/builder_delete.go
+++ b/entc/integration/ent/builder_delete.go
@@ -21,7 +21,7 @@ type BuilderDelete struct {
config
hooks []Hook
mutation *BuilderMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the BuilderDelete builder.
diff --git a/entc/integration/ent/builder_query.go b/entc/integration/ent/builder_query.go
index 111b69a9d8..d6d02e3e1f 100644
--- a/entc/integration/ent/builder_query.go
+++ b/entc/integration/ent/builder_query.go
@@ -28,7 +28,7 @@ type BuilderQuery struct {
inters []Interceptor
predicates []predicate.Builder
modifiers []func(*sql.Selector)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/entc/integration/ent/builder_update.go b/entc/integration/ent/builder_update.go
index b543367ef3..d9502522bf 100644
--- a/entc/integration/ent/builder_update.go
+++ b/entc/integration/ent/builder_update.go
@@ -24,7 +24,7 @@ type BuilderUpdate struct {
hooks []Hook
mutation *BuilderMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the BuilderUpdate builder.
@@ -90,7 +90,7 @@ 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}
@@ -108,7 +108,7 @@ type BuilderUpdateOne struct {
hooks []Hook
mutation *BuilderMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Mutation returns the BuilderMutation object of the builder.
@@ -201,7 +201,7 @@ func (_u *BuilderUpdateOne) sqlSave(ctx context.Context) (_node *Builder, 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{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 eb559b8334..ae150a3579 100644
--- a/entc/integration/ent/card_create.go
+++ b/entc/integration/ent/card_create.go
@@ -25,7 +25,7 @@ type CardCreate struct {
config
mutation *CardMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
@@ -528,7 +528,7 @@ type CardCreateBulk struct {
config
err error
builders []*CardCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
diff --git a/entc/integration/ent/card_delete.go b/entc/integration/ent/card_delete.go
index d6479ec76d..8953497378 100644
--- a/entc/integration/ent/card_delete.go
+++ b/entc/integration/ent/card_delete.go
@@ -21,7 +21,7 @@ type CardDelete struct {
config
hooks []Hook
mutation *CardMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the CardDelete builder.
diff --git a/entc/integration/ent/card_query.go b/entc/integration/ent/card_query.go
index b15621ff4b..8af02449f6 100644
--- a/entc/integration/ent/card_query.go
+++ b/entc/integration/ent/card_query.go
@@ -35,7 +35,7 @@ type CardQuery struct {
withFKs bool
modifiers []func(*sql.Selector)
withNamedSpec map[string]*SpecQuery
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/entc/integration/ent/card_update.go b/entc/integration/ent/card_update.go
index 679c383abf..30df6c085a 100644
--- a/entc/integration/ent/card_update.go
+++ b/entc/integration/ent/card_update.go
@@ -27,7 +27,7 @@ type CardUpdate struct {
hooks []Hook
mutation *CardMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the CardUpdate builder.
@@ -312,7 +312,7 @@ func (_u *CardUpdate) 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{card.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
@@ -330,7 +330,7 @@ type CardUpdateOne struct {
hooks []Hook
mutation *CardMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// SetUpdateTime sets the "update_time" field.
@@ -642,7 +642,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/ent/client.go b/entc/integration/ent/client.go
index 199db87d67..9c603777ea 100644
--- a/entc/integration/ent/client.go
+++ b/entc/integration/ent/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/ent/api"
"entgo.io/ent/entc/integration/ent/builder"
"entgo.io/ent/entc/integration/ent/card"
@@ -181,15 +180,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 d06f067950..bd422a6d50 100644
--- a/entc/integration/ent/comment_create.go
+++ b/entc/integration/ent/comment_create.go
@@ -23,7 +23,7 @@ type CommentCreate struct {
config
mutation *CommentMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
@@ -571,7 +571,7 @@ type CommentCreateBulk struct {
config
err error
builders []*CommentCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
diff --git a/entc/integration/ent/comment_delete.go b/entc/integration/ent/comment_delete.go
index f4f2270eb2..93e119c963 100644
--- a/entc/integration/ent/comment_delete.go
+++ b/entc/integration/ent/comment_delete.go
@@ -21,7 +21,7 @@ type CommentDelete struct {
config
hooks []Hook
mutation *CommentMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the CommentDelete builder.
diff --git a/entc/integration/ent/comment_query.go b/entc/integration/ent/comment_query.go
index 166542f3a2..c3baf3ad40 100644
--- a/entc/integration/ent/comment_query.go
+++ b/entc/integration/ent/comment_query.go
@@ -28,7 +28,7 @@ type CommentQuery struct {
inters []Interceptor
predicates []predicate.Comment
modifiers []func(*sql.Selector)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/entc/integration/ent/comment_update.go b/entc/integration/ent/comment_update.go
index acc785dedc..6cb40439ad 100644
--- a/entc/integration/ent/comment_update.go
+++ b/entc/integration/ent/comment_update.go
@@ -25,7 +25,7 @@ type CommentUpdate struct {
hooks []Hook
mutation *CommentMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the CommentUpdate builder.
@@ -259,7 +259,7 @@ func (_u *CommentUpdate) 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{comment.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
@@ -277,7 +277,7 @@ type CommentUpdateOne struct {
hooks []Hook
mutation *CommentMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// SetUniqueInt sets the "unique_int" field.
@@ -538,7 +538,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/ent/exvaluescan_create.go b/entc/integration/ent/exvaluescan_create.go
index f3137aa574..ac8d39e056 100644
--- a/entc/integration/ent/exvaluescan_create.go
+++ b/entc/integration/ent/exvaluescan_create.go
@@ -24,7 +24,7 @@ type ExValueScanCreate struct {
config
mutation *ExValueScanMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
@@ -612,7 +612,7 @@ type ExValueScanCreateBulk struct {
config
err error
builders []*ExValueScanCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
diff --git a/entc/integration/ent/exvaluescan_delete.go b/entc/integration/ent/exvaluescan_delete.go
index 3a6556e16e..3c35359eb4 100644
--- a/entc/integration/ent/exvaluescan_delete.go
+++ b/entc/integration/ent/exvaluescan_delete.go
@@ -21,7 +21,7 @@ type ExValueScanDelete struct {
config
hooks []Hook
mutation *ExValueScanMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the ExValueScanDelete builder.
diff --git a/entc/integration/ent/exvaluescan_query.go b/entc/integration/ent/exvaluescan_query.go
index 65590152e2..a7f938c531 100644
--- a/entc/integration/ent/exvaluescan_query.go
+++ b/entc/integration/ent/exvaluescan_query.go
@@ -28,7 +28,7 @@ type ExValueScanQuery struct {
inters []Interceptor
predicates []predicate.ExValueScan
modifiers []func(*sql.Selector)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/entc/integration/ent/exvaluescan_update.go b/entc/integration/ent/exvaluescan_update.go
index 4e61748b2f..855ad39a59 100644
--- a/entc/integration/ent/exvaluescan_update.go
+++ b/entc/integration/ent/exvaluescan_update.go
@@ -26,7 +26,7 @@ type ExValueScanUpdate struct {
hooks []Hook
mutation *ExValueScanMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the ExValueScanUpdate builder.
@@ -247,7 +247,7 @@ func (_u *ExValueScanUpdate) 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{exvaluescan.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
@@ -265,7 +265,7 @@ type ExValueScanUpdateOne struct {
hooks []Hook
mutation *ExValueScanMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// SetBinary sets the "binary" field.
@@ -513,7 +513,7 @@ func (_u *ExValueScanUpdateOne) sqlSave(ctx context.Context) (_node *ExValueScan
_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 dcba23b626..9c84c807a4 100644
--- a/entc/integration/ent/fieldtype_create.go
+++ b/entc/integration/ent/fieldtype_create.go
@@ -28,7 +28,7 @@ type FieldTypeCreate struct {
config
mutation *FieldTypeMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
@@ -4181,7 +4181,7 @@ type FieldTypeCreateBulk struct {
config
err error
builders []*FieldTypeCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
diff --git a/entc/integration/ent/fieldtype_delete.go b/entc/integration/ent/fieldtype_delete.go
index 0dd3867853..c08698333c 100644
--- a/entc/integration/ent/fieldtype_delete.go
+++ b/entc/integration/ent/fieldtype_delete.go
@@ -21,7 +21,7 @@ type FieldTypeDelete struct {
config
hooks []Hook
mutation *FieldTypeMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the FieldTypeDelete builder.
diff --git a/entc/integration/ent/fieldtype_query.go b/entc/integration/ent/fieldtype_query.go
index ac8b169052..1ea3fa68f8 100644
--- a/entc/integration/ent/fieldtype_query.go
+++ b/entc/integration/ent/fieldtype_query.go
@@ -29,7 +29,7 @@ type FieldTypeQuery struct {
predicates []predicate.FieldType
withFKs bool
modifiers []func(*sql.Selector)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/entc/integration/ent/fieldtype_update.go b/entc/integration/ent/fieldtype_update.go
index 81890a7dd9..a26206cf23 100644
--- a/entc/integration/ent/fieldtype_update.go
+++ b/entc/integration/ent/fieldtype_update.go
@@ -31,7 +31,7 @@ type FieldTypeUpdate struct {
hooks []Hook
mutation *FieldTypeMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the FieldTypeUpdate builder.
@@ -1928,7 +1928,7 @@ func (_u *FieldTypeUpdate) 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{fieldtype.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
@@ -1946,7 +1946,7 @@ type FieldTypeUpdateOne struct {
hooks []Hook
mutation *FieldTypeMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// SetInt sets the "int" field.
@@ -3870,7 +3870,7 @@ func (_u *FieldTypeUpdateOne) sqlSave(ctx context.Context) (_node *FieldType, 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{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 6b7c44fcc8..b989f0ae66 100644
--- a/entc/integration/ent/file_create.go
+++ b/entc/integration/ent/file_create.go
@@ -26,7 +26,7 @@ type FileCreate struct {
config
mutation *FileMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
@@ -818,7 +818,7 @@ type FileCreateBulk struct {
config
err error
builders []*FileCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
diff --git a/entc/integration/ent/file_delete.go b/entc/integration/ent/file_delete.go
index 7af494bf69..e3b570ae33 100644
--- a/entc/integration/ent/file_delete.go
+++ b/entc/integration/ent/file_delete.go
@@ -21,7 +21,7 @@ type FileDelete struct {
config
hooks []Hook
mutation *FileMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the FileDelete builder.
diff --git a/entc/integration/ent/file_query.go b/entc/integration/ent/file_query.go
index ac61788e95..0cfa86a0f1 100644
--- a/entc/integration/ent/file_query.go
+++ b/entc/integration/ent/file_query.go
@@ -37,7 +37,7 @@ type FileQuery struct {
withFKs bool
modifiers []func(*sql.Selector)
withNamedField map[string]*FieldTypeQuery
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/entc/integration/ent/file_update.go b/entc/integration/ent/file_update.go
index da45d1c6b5..90b25b9939 100644
--- a/entc/integration/ent/file_update.go
+++ b/entc/integration/ent/file_update.go
@@ -28,7 +28,7 @@ type FileUpdate struct {
hooks []Hook
mutation *FileMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the FileUpdate builder.
@@ -521,7 +521,7 @@ func (_u *FileUpdate) 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{file.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
@@ -539,7 +539,7 @@ type FileUpdateOne struct {
hooks []Hook
mutation *FileMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// SetSetID sets the "set_id" field.
@@ -1059,7 +1059,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/ent/filetype_create.go b/entc/integration/ent/filetype_create.go
index 04bc53ab60..7acd4c3bce 100644
--- a/entc/integration/ent/filetype_create.go
+++ b/entc/integration/ent/filetype_create.go
@@ -23,7 +23,7 @@ type FileTypeCreate struct {
config
mutation *FileTypeMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
@@ -413,7 +413,7 @@ type FileTypeCreateBulk struct {
config
err error
builders []*FileTypeCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
diff --git a/entc/integration/ent/filetype_delete.go b/entc/integration/ent/filetype_delete.go
index a95d2f4df1..aed5948604 100644
--- a/entc/integration/ent/filetype_delete.go
+++ b/entc/integration/ent/filetype_delete.go
@@ -21,7 +21,7 @@ type FileTypeDelete struct {
config
hooks []Hook
mutation *FileTypeMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the FileTypeDelete builder.
diff --git a/entc/integration/ent/filetype_query.go b/entc/integration/ent/filetype_query.go
index 3823927bd2..720c82a824 100644
--- a/entc/integration/ent/filetype_query.go
+++ b/entc/integration/ent/filetype_query.go
@@ -32,7 +32,7 @@ type FileTypeQuery struct {
withFiles *FileQuery
modifiers []func(*sql.Selector)
withNamedFiles map[string]*FileQuery
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/entc/integration/ent/filetype_update.go b/entc/integration/ent/filetype_update.go
index 10cf3c1996..7a9d983507 100644
--- a/entc/integration/ent/filetype_update.go
+++ b/entc/integration/ent/filetype_update.go
@@ -25,7 +25,7 @@ type FileTypeUpdate struct {
hooks []Hook
mutation *FileTypeMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the FileTypeUpdate builder.
@@ -241,7 +241,7 @@ func (_u *FileTypeUpdate) 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{filetype.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
@@ -259,7 +259,7 @@ type FileTypeUpdateOne struct {
hooks []Hook
mutation *FileTypeMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// SetName sets the "name" field.
@@ -502,7 +502,7 @@ func (_u *FileTypeUpdateOne) sqlSave(ctx context.Context) (_node *FileType, 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{filetype.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
diff --git a/entc/integration/ent/goods_create.go b/entc/integration/ent/goods_create.go
index ce57d59b77..dbe0c88b5e 100644
--- a/entc/integration/ent/goods_create.go
+++ b/entc/integration/ent/goods_create.go
@@ -22,7 +22,7 @@ type GoodsCreate struct {
config
mutation *GoodsMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
@@ -219,7 +219,7 @@ type GoodsCreateBulk struct {
config
err error
builders []*GoodsCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
diff --git a/entc/integration/ent/goods_delete.go b/entc/integration/ent/goods_delete.go
index f9e49134df..95d1cefec2 100644
--- a/entc/integration/ent/goods_delete.go
+++ b/entc/integration/ent/goods_delete.go
@@ -21,7 +21,7 @@ type GoodsDelete struct {
config
hooks []Hook
mutation *GoodsMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the GoodsDelete builder.
diff --git a/entc/integration/ent/goods_query.go b/entc/integration/ent/goods_query.go
index c28b06688d..467114a544 100644
--- a/entc/integration/ent/goods_query.go
+++ b/entc/integration/ent/goods_query.go
@@ -28,7 +28,7 @@ type GoodsQuery struct {
inters []Interceptor
predicates []predicate.Goods
modifiers []func(*sql.Selector)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/entc/integration/ent/goods_update.go b/entc/integration/ent/goods_update.go
index 37732b6254..70c2a2f242 100644
--- a/entc/integration/ent/goods_update.go
+++ b/entc/integration/ent/goods_update.go
@@ -24,7 +24,7 @@ type GoodsUpdate struct {
hooks []Hook
mutation *GoodsMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the GoodsUpdate builder.
@@ -90,7 +90,7 @@ 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}
@@ -108,7 +108,7 @@ type GoodsUpdateOne struct {
hooks []Hook
mutation *GoodsMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Mutation returns the GoodsMutation object of the builder.
@@ -201,7 +201,7 @@ func (_u *GoodsUpdateOne) sqlSave(ctx context.Context) (_node *Goods, 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{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 8d2be28c49..e8d46a90ad 100644
--- a/entc/integration/ent/group_create.go
+++ b/entc/integration/ent/group_create.go
@@ -26,7 +26,7 @@ type GroupCreate struct {
config
mutation *GroupMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
@@ -633,7 +633,7 @@ type GroupCreateBulk struct {
config
err error
builders []*GroupCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
diff --git a/entc/integration/ent/group_delete.go b/entc/integration/ent/group_delete.go
index 353ed4e359..c1cbe6a2ff 100644
--- a/entc/integration/ent/group_delete.go
+++ b/entc/integration/ent/group_delete.go
@@ -21,7 +21,7 @@ type GroupDelete struct {
config
hooks []Hook
mutation *GroupMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the GroupDelete builder.
diff --git a/entc/integration/ent/group_query.go b/entc/integration/ent/group_query.go
index 99c333cd9c..233675c2c8 100644
--- a/entc/integration/ent/group_query.go
+++ b/entc/integration/ent/group_query.go
@@ -40,7 +40,7 @@ type GroupQuery struct {
withNamedFiles map[string]*FileQuery
withNamedBlocked map[string]*UserQuery
withNamedUsers map[string]*UserQuery
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/entc/integration/ent/group_update.go b/entc/integration/ent/group_update.go
index 1fb546a0c2..d7919dd516 100644
--- a/entc/integration/ent/group_update.go
+++ b/entc/integration/ent/group_update.go
@@ -28,7 +28,7 @@ type GroupUpdate struct {
hooks []Hook
mutation *GroupMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the GroupUpdate builder.
@@ -522,7 +522,7 @@ func (_u *GroupUpdate) 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{group.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
@@ -540,7 +540,7 @@ type GroupUpdateOne struct {
hooks []Hook
mutation *GroupMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// SetActive sets the "active" field.
@@ -1061,7 +1061,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/ent/groupinfo_create.go b/entc/integration/ent/groupinfo_create.go
index 8162668e19..10fb463642 100644
--- a/entc/integration/ent/groupinfo_create.go
+++ b/entc/integration/ent/groupinfo_create.go
@@ -23,7 +23,7 @@ type GroupInfoCreate struct {
config
mutation *GroupInfoMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
@@ -365,7 +365,7 @@ type GroupInfoCreateBulk struct {
config
err error
builders []*GroupInfoCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
diff --git a/entc/integration/ent/groupinfo_delete.go b/entc/integration/ent/groupinfo_delete.go
index 9be9235d12..4beaaa1dc0 100644
--- a/entc/integration/ent/groupinfo_delete.go
+++ b/entc/integration/ent/groupinfo_delete.go
@@ -21,7 +21,7 @@ type GroupInfoDelete struct {
config
hooks []Hook
mutation *GroupInfoMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the GroupInfoDelete builder.
diff --git a/entc/integration/ent/groupinfo_query.go b/entc/integration/ent/groupinfo_query.go
index 16bc6bc9b3..534fdec199 100644
--- a/entc/integration/ent/groupinfo_query.go
+++ b/entc/integration/ent/groupinfo_query.go
@@ -32,7 +32,7 @@ type GroupInfoQuery struct {
withGroups *GroupQuery
modifiers []func(*sql.Selector)
withNamedGroups map[string]*GroupQuery
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/entc/integration/ent/groupinfo_update.go b/entc/integration/ent/groupinfo_update.go
index d464deded5..84804c05c3 100644
--- a/entc/integration/ent/groupinfo_update.go
+++ b/entc/integration/ent/groupinfo_update.go
@@ -25,7 +25,7 @@ type GroupInfoUpdate struct {
hooks []Hook
mutation *GroupInfoMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the GroupInfoUpdate builder.
@@ -216,7 +216,7 @@ func (_u *GroupInfoUpdate) 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{groupinfo.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
@@ -234,7 +234,7 @@ type GroupInfoUpdateOne struct {
hooks []Hook
mutation *GroupInfoMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// SetDesc sets the "desc" field.
@@ -452,7 +452,7 @@ func (_u *GroupInfoUpdateOne) sqlSave(ctx context.Context) (_node *GroupInfo, 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{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 b5a7dcd441..25fcbbab0a 100644
--- a/entc/integration/ent/item_create.go
+++ b/entc/integration/ent/item_create.go
@@ -23,7 +23,7 @@ type ItemCreate struct {
config
mutation *ItemMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
@@ -338,7 +338,7 @@ type ItemCreateBulk struct {
config
err error
builders []*ItemCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
diff --git a/entc/integration/ent/item_delete.go b/entc/integration/ent/item_delete.go
index 2fc36cc402..0589a45b60 100644
--- a/entc/integration/ent/item_delete.go
+++ b/entc/integration/ent/item_delete.go
@@ -21,7 +21,7 @@ type ItemDelete struct {
config
hooks []Hook
mutation *ItemMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the ItemDelete builder.
diff --git a/entc/integration/ent/item_query.go b/entc/integration/ent/item_query.go
index 55761a6193..b0f0a503b9 100644
--- a/entc/integration/ent/item_query.go
+++ b/entc/integration/ent/item_query.go
@@ -28,7 +28,7 @@ type ItemQuery struct {
inters []Interceptor
predicates []predicate.Item
modifiers []func(*sql.Selector)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/entc/integration/ent/item_update.go b/entc/integration/ent/item_update.go
index 80c3fcafb0..e38cbf0762 100644
--- a/entc/integration/ent/item_update.go
+++ b/entc/integration/ent/item_update.go
@@ -24,7 +24,7 @@ type ItemUpdate struct {
hooks []Hook
mutation *ItemMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the ItemUpdate builder.
@@ -129,7 +129,7 @@ func (_u *ItemUpdate) 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{item.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
@@ -147,7 +147,7 @@ type ItemUpdateOne struct {
hooks []Hook
mutation *ItemMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// SetText sets the "text" field.
@@ -279,7 +279,7 @@ func (_u *ItemUpdateOne) sqlSave(ctx context.Context) (_node *Item, 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{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 82a8a5f50b..dcf6b262ff 100644
--- a/entc/integration/ent/license_create.go
+++ b/entc/integration/ent/license_create.go
@@ -23,7 +23,7 @@ type LicenseCreate struct {
config
mutation *LicenseMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
@@ -330,7 +330,7 @@ type LicenseCreateBulk struct {
config
err error
builders []*LicenseCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
diff --git a/entc/integration/ent/license_delete.go b/entc/integration/ent/license_delete.go
index deb737343e..a5eb96cf39 100644
--- a/entc/integration/ent/license_delete.go
+++ b/entc/integration/ent/license_delete.go
@@ -21,7 +21,7 @@ type LicenseDelete struct {
config
hooks []Hook
mutation *LicenseMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the LicenseDelete builder.
diff --git a/entc/integration/ent/license_query.go b/entc/integration/ent/license_query.go
index b6488048e7..6c44d53753 100644
--- a/entc/integration/ent/license_query.go
+++ b/entc/integration/ent/license_query.go
@@ -28,7 +28,7 @@ type LicenseQuery struct {
inters []Interceptor
predicates []predicate.License
modifiers []func(*sql.Selector)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/entc/integration/ent/license_update.go b/entc/integration/ent/license_update.go
index 85551abd7b..7000b4b0b9 100644
--- a/entc/integration/ent/license_update.go
+++ b/entc/integration/ent/license_update.go
@@ -25,7 +25,7 @@ type LicenseUpdate struct {
hooks []Hook
mutation *LicenseMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the LicenseUpdate builder.
@@ -109,7 +109,7 @@ func (_u *LicenseUpdate) 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{license.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
@@ -127,7 +127,7 @@ type LicenseUpdateOne struct {
hooks []Hook
mutation *LicenseMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// SetUpdateTime sets the "update_time" field.
@@ -238,7 +238,7 @@ func (_u *LicenseUpdateOne) sqlSave(ctx context.Context) (_node *License, 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{license.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
diff --git a/entc/integration/ent/node_create.go b/entc/integration/ent/node_create.go
index cd1d4f23b4..413d951bd7 100644
--- a/entc/integration/ent/node_create.go
+++ b/entc/integration/ent/node_create.go
@@ -23,7 +23,7 @@ type NodeCreate struct {
config
mutation *NodeMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
@@ -424,7 +424,7 @@ type NodeCreateBulk struct {
config
err error
builders []*NodeCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
diff --git a/entc/integration/ent/node_delete.go b/entc/integration/ent/node_delete.go
index dee9b0ba35..d92900c1a3 100644
--- a/entc/integration/ent/node_delete.go
+++ b/entc/integration/ent/node_delete.go
@@ -21,7 +21,7 @@ type NodeDelete struct {
config
hooks []Hook
mutation *NodeMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the NodeDelete builder.
diff --git a/entc/integration/ent/node_query.go b/entc/integration/ent/node_query.go
index c39f0b82a2..e8ef5e909a 100644
--- a/entc/integration/ent/node_query.go
+++ b/entc/integration/ent/node_query.go
@@ -32,7 +32,7 @@ type NodeQuery struct {
withNext *NodeQuery
withFKs bool
modifiers []func(*sql.Selector)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/entc/integration/ent/node_update.go b/entc/integration/ent/node_update.go
index 0f22c31517..9abd19022d 100644
--- a/entc/integration/ent/node_update.go
+++ b/entc/integration/ent/node_update.go
@@ -25,7 +25,7 @@ type NodeUpdate struct {
hooks []Hook
mutation *NodeMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the NodeUpdate builder.
@@ -262,7 +262,7 @@ func (_u *NodeUpdate) 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{node.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
@@ -280,7 +280,7 @@ type NodeUpdateOne struct {
hooks []Hook
mutation *NodeMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// SetValue sets the "value" field.
@@ -544,7 +544,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/ent/pc_create.go b/entc/integration/ent/pc_create.go
index 6285b1e040..d79c7b453a 100644
--- a/entc/integration/ent/pc_create.go
+++ b/entc/integration/ent/pc_create.go
@@ -22,7 +22,7 @@ type PCCreate struct {
config
mutation *PCMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
@@ -219,7 +219,7 @@ type PCCreateBulk struct {
config
err error
builders []*PCCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
diff --git a/entc/integration/ent/pc_delete.go b/entc/integration/ent/pc_delete.go
index 6b90014579..a96dee3753 100644
--- a/entc/integration/ent/pc_delete.go
+++ b/entc/integration/ent/pc_delete.go
@@ -21,7 +21,7 @@ type PCDelete struct {
config
hooks []Hook
mutation *PCMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the PCDelete builder.
diff --git a/entc/integration/ent/pc_query.go b/entc/integration/ent/pc_query.go
index 3ab0ef4610..c5a0449843 100644
--- a/entc/integration/ent/pc_query.go
+++ b/entc/integration/ent/pc_query.go
@@ -28,7 +28,7 @@ type PCQuery struct {
inters []Interceptor
predicates []predicate.PC
modifiers []func(*sql.Selector)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/entc/integration/ent/pc_update.go b/entc/integration/ent/pc_update.go
index 728a59a72d..4a28a9b895 100644
--- a/entc/integration/ent/pc_update.go
+++ b/entc/integration/ent/pc_update.go
@@ -24,7 +24,7 @@ type PCUpdate struct {
hooks []Hook
mutation *PCMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the PCUpdate builder.
@@ -90,7 +90,7 @@ 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}
@@ -108,7 +108,7 @@ type PCUpdateOne struct {
hooks []Hook
mutation *PCMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Mutation returns the PCMutation object of the builder.
@@ -201,7 +201,7 @@ func (_u *PCUpdateOne) sqlSave(ctx context.Context) (_node *PC, 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{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 208c2e4a75..802090e351 100644
--- a/entc/integration/ent/pet_create.go
+++ b/entc/integration/ent/pet_create.go
@@ -25,7 +25,7 @@ type PetCreate struct {
config
mutation *PetMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
@@ -630,7 +630,7 @@ type PetCreateBulk struct {
config
err error
builders []*PetCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
diff --git a/entc/integration/ent/pet_delete.go b/entc/integration/ent/pet_delete.go
index 8cf51235a2..5980b6b33f 100644
--- a/entc/integration/ent/pet_delete.go
+++ b/entc/integration/ent/pet_delete.go
@@ -21,7 +21,7 @@ type PetDelete struct {
config
hooks []Hook
mutation *PetMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the PetDelete builder.
diff --git a/entc/integration/ent/pet_query.go b/entc/integration/ent/pet_query.go
index b751e89919..079c842357 100644
--- a/entc/integration/ent/pet_query.go
+++ b/entc/integration/ent/pet_query.go
@@ -32,7 +32,7 @@ type PetQuery struct {
withOwner *UserQuery
withFKs bool
modifiers []func(*sql.Selector)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/entc/integration/ent/pet_update.go b/entc/integration/ent/pet_update.go
index 86d42e92e2..2e25572f65 100644
--- a/entc/integration/ent/pet_update.go
+++ b/entc/integration/ent/pet_update.go
@@ -27,7 +27,7 @@ type PetUpdate struct {
hooks []Hook
mutation *PetMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the PetUpdate builder.
@@ -340,7 +340,7 @@ func (_u *PetUpdate) 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{pet.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
@@ -358,7 +358,7 @@ type PetUpdateOne struct {
hooks []Hook
mutation *PetMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// SetAge sets the "age" field.
@@ -698,7 +698,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/ent/spec_create.go b/entc/integration/ent/spec_create.go
index 354231971f..912f417eab 100644
--- a/entc/integration/ent/spec_create.go
+++ b/entc/integration/ent/spec_create.go
@@ -23,7 +23,7 @@ type SpecCreate struct {
config
mutation *SpecMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
@@ -251,7 +251,7 @@ type SpecCreateBulk struct {
config
err error
builders []*SpecCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
diff --git a/entc/integration/ent/spec_delete.go b/entc/integration/ent/spec_delete.go
index 4fd2627533..9d82b2738a 100644
--- a/entc/integration/ent/spec_delete.go
+++ b/entc/integration/ent/spec_delete.go
@@ -21,7 +21,7 @@ type SpecDelete struct {
config
hooks []Hook
mutation *SpecMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the SpecDelete builder.
diff --git a/entc/integration/ent/spec_query.go b/entc/integration/ent/spec_query.go
index 50b972e1cf..e9a30d2e32 100644
--- a/entc/integration/ent/spec_query.go
+++ b/entc/integration/ent/spec_query.go
@@ -32,7 +32,7 @@ type SpecQuery struct {
withCard *CardQuery
modifiers []func(*sql.Selector)
withNamedCard map[string]*CardQuery
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/entc/integration/ent/spec_update.go b/entc/integration/ent/spec_update.go
index d0ce335f44..4273961e5e 100644
--- a/entc/integration/ent/spec_update.go
+++ b/entc/integration/ent/spec_update.go
@@ -25,7 +25,7 @@ type SpecUpdate struct {
hooks []Hook
mutation *SpecMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the SpecUpdate builder.
@@ -172,7 +172,7 @@ func (_u *SpecUpdate) 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{spec.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
@@ -190,7 +190,7 @@ type SpecUpdateOne struct {
hooks []Hook
mutation *SpecMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// AddCardIDs adds the "card" edge to the Card entity by IDs.
@@ -364,7 +364,7 @@ func (_u *SpecUpdateOne) sqlSave(ctx context.Context) (_node *Spec, 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{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 d06d1ac267..2477a0d4ff 100644
--- a/entc/integration/ent/task_create.go
+++ b/entc/integration/ent/task_create.go
@@ -24,7 +24,7 @@ type TaskCreate struct {
config
mutation *TaskMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
@@ -690,7 +690,7 @@ type TaskCreateBulk struct {
config
err error
builders []*TaskCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
diff --git a/entc/integration/ent/task_delete.go b/entc/integration/ent/task_delete.go
index ce2900fac8..f5e4556c00 100644
--- a/entc/integration/ent/task_delete.go
+++ b/entc/integration/ent/task_delete.go
@@ -22,7 +22,7 @@ type TaskDelete struct {
config
hooks []Hook
mutation *TaskMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the TaskDelete builder.
diff --git a/entc/integration/ent/task_query.go b/entc/integration/ent/task_query.go
index bdd6ec5540..275f112f6a 100644
--- a/entc/integration/ent/task_query.go
+++ b/entc/integration/ent/task_query.go
@@ -28,7 +28,7 @@ type TaskQuery struct {
inters []Interceptor
predicates []predicate.Task
modifiers []func(*sql.Selector)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/entc/integration/ent/task_update.go b/entc/integration/ent/task_update.go
index 88d8a2b4e2..408311b561 100644
--- a/entc/integration/ent/task_update.go
+++ b/entc/integration/ent/task_update.go
@@ -25,7 +25,7 @@ type TaskUpdate struct {
hooks []Hook
mutation *TaskMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the TaskUpdate builder.
@@ -295,7 +295,7 @@ func (_u *TaskUpdate) 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{enttask.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
@@ -313,7 +313,7 @@ type TaskUpdateOne struct {
hooks []Hook
mutation *TaskMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// SetPriority sets the "priority" field.
@@ -610,7 +610,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{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 e9dcb84db3..8daaae3572 100644
--- a/entc/integration/ent/user_create.go
+++ b/entc/integration/ent/user_create.go
@@ -26,7 +26,7 @@ type UserCreate struct {
config
mutation *UserMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
@@ -1281,7 +1281,7 @@ type UserCreateBulk struct {
config
err error
builders []*UserCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
conflict []sql.ConflictOption
}
diff --git a/entc/integration/ent/user_delete.go b/entc/integration/ent/user_delete.go
index f995536f25..51f59cf9f4 100644
--- a/entc/integration/ent/user_delete.go
+++ b/entc/integration/ent/user_delete.go
@@ -21,7 +21,7 @@ type UserDelete struct {
config
hooks []Hook
mutation *UserMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the UserDelete builder.
diff --git a/entc/integration/ent/user_query.go b/entc/integration/ent/user_query.go
index 0927a941b3..5bb10ff36d 100644
--- a/entc/integration/ent/user_query.go
+++ b/entc/integration/ent/user_query.go
@@ -52,7 +52,7 @@ type UserQuery struct {
withNamedFollowers map[string]*UserQuery
withNamedFollowing map[string]*UserQuery
withNamedChildren map[string]*UserQuery
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/entc/integration/ent/user_update.go b/entc/integration/ent/user_update.go
index 6620c6344b..d6020c711d 100644
--- a/entc/integration/ent/user_update.go
+++ b/entc/integration/ent/user_update.go
@@ -28,7 +28,7 @@ type UserUpdate struct {
hooks []Hook
mutation *UserMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the UserUpdate builder.
@@ -1197,7 +1197,7 @@ func (_u *UserUpdate) 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{user.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
@@ -1215,7 +1215,7 @@ type UserUpdateOne struct {
hooks []Hook
mutation *UserMutation
modifiers []func(*sql.UpdateBuilder)
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// SetOptionalInt sets the "optional_int" field.
@@ -2411,7 +2411,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/go.mod b/entc/integration/go.mod
index 7b1caee556..b3bb11c531 100644
--- a/entc/integration/go.mod
+++ b/entc/integration/go.mod
@@ -50,4 +50,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
-replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.33
+replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.34
diff --git a/entc/integration/go.sum b/entc/integration/go.sum
index 48b6a96115..680a4f10dd 100644
--- a/entc/integration/go.sum
+++ b/entc/integration/go.sum
@@ -5,8 +5,8 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
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/LostImagin4tion/atlas v0.0.33 h1:RgcQhGG0MZDwheuFRiZu47ihFRDhtcYmbAT6KU3J3v0=
-github.com/LostImagin4tion/atlas v0.0.33/go.mod h1:FtOd0Ry45l3FeDVGVm8tf2SFWg3vHDztylE0eE3EWQ8=
+github.com/LostImagin4tion/atlas v0.0.34 h1:xCEZMtvTWwbuSU0TVQTsc60sKffIJxqjh/VIvRKcN5c=
+github.com/LostImagin4tion/atlas v0.0.34/go.mod h1:FtOd0Ry45l3FeDVGVm8tf2SFWg3vHDztylE0eE3EWQ8=
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=
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 d963edd315..4b4c2dd21a 100644
--- a/entc/integration/hooks/ent/client.go
+++ b/entc/integration/hooks/ent/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/hooks/ent/card"
"entgo.io/ent/entc/integration/hooks/ent/pet"
"entgo.io/ent/entc/integration/hooks/ent/user"
@@ -114,15 +113,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 93a3e0181e..54927ecec6 100644
--- a/entc/integration/idtype/ent/client.go
+++ b/entc/integration/idtype/ent/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/idtype/ent/user"
)
@@ -106,15 +105,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 6bdf330b34..2044e9fc03 100644
--- a/entc/integration/integration_test.go
+++ b/entc/integration/integration_test.go
@@ -361,7 +361,7 @@ func Upsert(t *testing.T, client *ent.Client) {
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").
@@ -1299,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)
@@ -1310,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)
diff --git a/entc/integration/json/ent/client.go b/entc/integration/json/ent/client.go
index a9e54fe3c7..2bf861dbb5 100644
--- a/entc/integration/json/ent/client.go
+++ b/entc/integration/json/ent/client.go
@@ -18,7 +18,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/json/ent/user"
)
@@ -105,15 +104,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 7e75175637..f8ca5ecbc1 100644
--- a/entc/integration/migrate/entv1/client.go
+++ b/entc/integration/migrate/entv1/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/migrate/entv1/car"
"entgo.io/ent/entc/integration/migrate/entv1/conversion"
"entgo.io/ent/entc/integration/migrate/entv1/customtype"
@@ -118,15 +117,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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_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 2c1b3777c9..24e0f7b29c 100644
--- a/entc/integration/migrate/entv2/client.go
+++ b/entc/integration/migrate/entv2/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/migrate/entv2/blog"
"entgo.io/ent/entc/integration/migrate/entv2/car"
"entgo.io/ent/entc/integration/migrate/entv2/conversion"
@@ -138,15 +137,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 d5afb29b91..5583848196 100644
--- a/entc/integration/migrate/versioned/client.go
+++ b/entc/integration/migrate/versioned/client.go
@@ -18,7 +18,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/migrate/versioned/group"
"entgo.io/ent/entc/integration/migrate/versioned/user"
)
@@ -109,15 +108,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 8e1bcbc8ab..dc40291cbf 100644
--- a/entc/integration/multischema/ent/client.go
+++ b/entc/integration/multischema/ent/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/multischema/ent/friendship"
"entgo.io/ent/entc/integration/multischema/ent/group"
"entgo.io/ent/entc/integration/multischema/ent/parent"
@@ -130,15 +129,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 4fc86d49ae..5c487bf289 100644
--- a/entc/integration/multischema/versioned/client.go
+++ b/entc/integration/multischema/versioned/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/multischema/versioned/friendship"
"entgo.io/ent/entc/integration/multischema/versioned/group"
"entgo.io/ent/entc/integration/multischema/versioned/pet"
@@ -123,15 +122,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 cac43ddb40..1b04e73291 100644
--- a/entc/integration/privacy/ent/client.go
+++ b/entc/integration/privacy/ent/client.go
@@ -21,7 +21,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/privacy/ent/task"
"entgo.io/ent/entc/integration/privacy/ent/team"
"entgo.io/ent/entc/integration/privacy/ent/user"
@@ -124,15 +123,7 @@ func HTTPClient(v *http.Client) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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/template/ent/client.go b/entc/integration/template/ent/client.go
index 306c44f2cd..53b649d131 100644
--- a/entc/integration/template/ent/client.go
+++ b/entc/integration/template/ent/client.go
@@ -20,7 +20,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/entc/integration/template/ent/group"
"entgo.io/ent/entc/integration/template/ent/pet"
"entgo.io/ent/entc/integration/template/ent/user"
@@ -128,15 +127,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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/examples/compositetypes/ent/client.go b/examples/compositetypes/ent/client.go
index 6efaac3f20..111ea08388 100644
--- a/examples/compositetypes/ent/client.go
+++ b/examples/compositetypes/ent/client.go
@@ -14,7 +14,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/compositetypes/ent/user"
)
@@ -101,15 +100,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 5f9a38bb02..2cdd5ab688 100644
--- a/examples/domaintypes/ent/client.go
+++ b/examples/domaintypes/ent/client.go
@@ -14,7 +14,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/domaintypes/ent/user"
)
@@ -101,15 +100,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 14decdaa89..e29d298e53 100644
--- a/examples/edgeindex/ent/client.go
+++ b/examples/edgeindex/ent/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/edgeindex/ent/city"
"entgo.io/ent/examples/edgeindex/ent/street"
)
@@ -110,15 +109,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 858ec80a64..d6b576a4a4 100644
--- a/examples/encryptfield/ent/client.go
+++ b/examples/encryptfield/ent/client.go
@@ -18,7 +18,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/encryptfield/ent/user"
"gocloud.dev/secrets"
)
@@ -114,15 +113,7 @@ func SecretsKeeper(v *secrets.Keeper) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 166e4a68e8..b7b79e5e99 100644
--- a/examples/entcpkg/ent/client.go
+++ b/examples/entcpkg/ent/client.go
@@ -21,7 +21,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/entcpkg/ent/user"
)
@@ -124,15 +123,7 @@ func Writer(v io.Writer) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 ffdd2ec8c0..49481310f8 100644
--- a/examples/enumtypes/ent/client.go
+++ b/examples/enumtypes/ent/client.go
@@ -14,7 +14,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/enumtypes/ent/user"
)
@@ -101,15 +100,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 698414bc64..7779fa3a25 100644
--- a/examples/extensions/ent/client.go
+++ b/examples/extensions/ent/client.go
@@ -14,7 +14,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/extensions/ent/user"
)
@@ -101,15 +100,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 9dd4076549..e4e3ccc00a 100644
--- a/examples/fs/ent/client.go
+++ b/examples/fs/ent/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/fs/ent/file"
)
@@ -106,15 +105,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 a09fe0c34b..4252d58b29 100644
--- a/examples/functionalidx/ent/client.go
+++ b/examples/functionalidx/ent/client.go
@@ -14,7 +14,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/functionalidx/ent/user"
)
@@ -101,15 +100,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 13d183ff1c..56ecf157a6 100644
--- a/examples/go.mod
+++ b/examples/go.mod
@@ -50,4 +50,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
-replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.33
+replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.34
diff --git a/examples/go.sum b/examples/go.sum
index e84eec833f..355d0d85e7 100644
--- a/examples/go.sum
+++ b/examples/go.sum
@@ -449,8 +449,8 @@ github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/GoogleCloudPlatform/cloudsql-proxy v1.33.1/go.mod h1:n3KDPrdaY2p9Nr0B1allAdjYArwIpXQcitNbsS/Qiok=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
-github.com/LostImagin4tion/atlas v0.0.33 h1:RgcQhGG0MZDwheuFRiZu47ihFRDhtcYmbAT6KU3J3v0=
-github.com/LostImagin4tion/atlas v0.0.33/go.mod h1:FtOd0Ry45l3FeDVGVm8tf2SFWg3vHDztylE0eE3EWQ8=
+github.com/LostImagin4tion/atlas v0.0.34 h1:xCEZMtvTWwbuSU0TVQTsc60sKffIJxqjh/VIvRKcN5c=
+github.com/LostImagin4tion/atlas v0.0.34/go.mod h1:FtOd0Ry45l3FeDVGVm8tf2SFWg3vHDztylE0eE3EWQ8=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
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 2414de9cf1..22d485921d 100644
--- a/examples/jsonencode/ent/client.go
+++ b/examples/jsonencode/ent/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/jsonencode/ent/card"
"entgo.io/ent/examples/jsonencode/ent/pet"
"entgo.io/ent/examples/jsonencode/ent/user"
@@ -114,15 +113,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 6622a651ee..006739841f 100644
--- a/examples/m2m2types/ent/client.go
+++ b/examples/m2m2types/ent/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/m2m2types/ent/group"
"entgo.io/ent/examples/m2m2types/ent/user"
)
@@ -110,15 +109,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 844fa092af..33bd37734d 100644
--- a/examples/m2mbidi/ent/client.go
+++ b/examples/m2mbidi/ent/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/m2mbidi/ent/user"
)
@@ -106,15 +105,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 a091524684..cfe203599c 100644
--- a/examples/m2mrecur/ent/client.go
+++ b/examples/m2mrecur/ent/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/m2mrecur/ent/user"
)
@@ -106,15 +105,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 4e9a791272..1c9e618d05 100644
--- a/examples/migration/ent/client.go
+++ b/examples/migration/ent/client.go
@@ -20,7 +20,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/migration/ent/card"
"entgo.io/ent/examples/migration/ent/payment"
"entgo.io/ent/examples/migration/ent/pet"
@@ -127,15 +126,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 ba285138f6..b40c9d15af 100644
--- a/examples/o2m2types/ent/client.go
+++ b/examples/o2m2types/ent/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/o2m2types/ent/pet"
"entgo.io/ent/examples/o2m2types/ent/user"
)
@@ -110,15 +109,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 61e5ee76b8..d9af9f9fe0 100644
--- a/examples/o2mrecur/ent/client.go
+++ b/examples/o2mrecur/ent/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/o2mrecur/ent/node"
)
@@ -106,15 +105,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 1a229c421f..47eeb4ff79 100644
--- a/examples/o2o2types/ent/client.go
+++ b/examples/o2o2types/ent/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/o2o2types/ent/card"
"entgo.io/ent/examples/o2o2types/ent/user"
)
@@ -110,15 +109,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 6481b24719..7bf54a7b49 100644
--- a/examples/o2obidi/ent/client.go
+++ b/examples/o2obidi/ent/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/o2obidi/ent/user"
)
@@ -106,15 +105,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 e3bfd1e0a0..d59c8fb164 100644
--- a/examples/o2orecur/ent/client.go
+++ b/examples/o2orecur/ent/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/o2orecur/ent/node"
)
@@ -106,15 +105,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 ddf6e09ea9..56563164ba 100644
--- a/examples/privacyadmin/ent/client.go
+++ b/examples/privacyadmin/ent/client.go
@@ -18,7 +18,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/privacyadmin/ent/user"
)
@@ -105,15 +104,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 3049f613d8..7cfa81c1e6 100644
--- a/examples/privacytenant/ent/client.go
+++ b/examples/privacytenant/ent/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/privacytenant/ent/group"
"entgo.io/ent/examples/privacytenant/ent/tenant"
"entgo.io/ent/examples/privacytenant/ent/user"
@@ -114,15 +113,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 844735ece7..9b9f04b01d 100644
--- a/examples/rls/ent/client.go
+++ b/examples/rls/ent/client.go
@@ -14,7 +14,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/rls/ent/tenant"
"entgo.io/ent/examples/rls/ent/user"
)
@@ -105,15 +104,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 07c0d8ded0..87fe18a838 100644
--- a/examples/start/ent/client.go
+++ b/examples/start/ent/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/start/ent/car"
"entgo.io/ent/examples/start/ent/group"
"entgo.io/ent/examples/start/ent/user"
@@ -114,15 +113,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 61d53840eb..8cdf6e4df4 100644
--- a/examples/traversal/ent/client.go
+++ b/examples/traversal/ent/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/traversal/ent/group"
"entgo.io/ent/examples/traversal/ent/pet"
"entgo.io/ent/examples/traversal/ent/user"
@@ -114,15 +113,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 441a83a35a..d746d4c277 100644
--- a/examples/triggers/ent/client.go
+++ b/examples/triggers/ent/client.go
@@ -14,7 +14,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/triggers/ent/user"
"entgo.io/ent/examples/triggers/ent/userauditlog"
)
@@ -105,15 +104,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 09d70f04f1..36254a4059 100644
--- a/examples/version/ent/client.go
+++ b/examples/version/ent/client.go
@@ -18,7 +18,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/version/ent/user"
)
@@ -105,15 +104,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 ff92994b59..6506dc312c 100644
--- a/examples/viewcomposite/ent/client.go
+++ b/examples/viewcomposite/ent/client.go
@@ -14,7 +14,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/viewcomposite/ent/pet"
"entgo.io/ent/examples/viewcomposite/ent/user"
)
@@ -111,15 +110,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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 e0f2bde1d8..4f90deb307 100644
--- a/examples/viewschema/ent/client.go
+++ b/examples/viewschema/ent/client.go
@@ -14,7 +14,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/viewschema/ent/pet"
"entgo.io/ent/examples/viewschema/ent/user"
)
@@ -111,15 +110,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ 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/ent/client.go b/examples/ydb/ent/client.go
index d378e901b7..a261dc8fb0 100644
--- a/examples/ydb/ent/client.go
+++ b/examples/ydb/ent/client.go
@@ -19,7 +19,6 @@ import (
"entgo.io/ent/dialect"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
- "entgo.io/ent/dialect/ydb"
"entgo.io/ent/examples/ydb/ent/episode"
"entgo.io/ent/examples/ydb/ent/season"
"entgo.io/ent/examples/ydb/ent/series"
@@ -114,15 +113,7 @@ func Driver(driver dialect.Driver) Option {
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
switch driverName {
case dialect.MySQL, dialect.Postgres, dialect.SQLite, dialect.YDB:
- var (
- drv dialect.Driver
- err error
- )
- if driverName == dialect.YDB {
- drv, err = ydb.Open(context.Background(), dataSourceName)
- } else {
- drv, err = sql.Open(driverName, dataSourceName)
- }
+ drv, err := sql.Open(driverName, dataSourceName)
if err != nil {
return nil, err
}
diff --git a/examples/ydb/ent/episode_create.go b/examples/ydb/ent/episode_create.go
index 0cb9c190c2..8f2f4b2e7a 100644
--- a/examples/ydb/ent/episode_create.go
+++ b/examples/ydb/ent/episode_create.go
@@ -12,6 +12,7 @@ import (
"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"
@@ -23,7 +24,7 @@ type EpisodeCreate struct {
config
mutation *EpisodeMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// SetSeasonID sets the "season_id" field.
@@ -179,7 +180,7 @@ type EpisodeCreateBulk struct {
config
err error
builders []*EpisodeCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Save creates the Episode entities in the database.
diff --git a/examples/ydb/ent/episode_delete.go b/examples/ydb/ent/episode_delete.go
index 2720770e34..240aac844f 100644
--- a/examples/ydb/ent/episode_delete.go
+++ b/examples/ydb/ent/episode_delete.go
@@ -21,7 +21,7 @@ type EpisodeDelete struct {
config
hooks []Hook
mutation *EpisodeMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the EpisodeDelete builder.
diff --git a/examples/ydb/ent/episode_query.go b/examples/ydb/ent/episode_query.go
index 7c7a3d5830..162f0abf45 100644
--- a/examples/ydb/ent/episode_query.go
+++ b/examples/ydb/ent/episode_query.go
@@ -28,7 +28,7 @@ type EpisodeQuery struct {
inters []Interceptor
predicates []predicate.Episode
withSeason *SeasonQuery
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/examples/ydb/ent/episode_update.go b/examples/ydb/ent/episode_update.go
index 16cd9f1359..0b844a353a 100644
--- a/examples/ydb/ent/episode_update.go
+++ b/examples/ydb/ent/episode_update.go
@@ -25,7 +25,7 @@ type EpisodeUpdate struct {
config
hooks []Hook
mutation *EpisodeMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the EpisodeUpdate builder.
@@ -188,7 +188,7 @@ func (_u *EpisodeUpdate) sqlSave(ctx context.Context) (_node int, err error) {
}
_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{episode.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
@@ -205,7 +205,7 @@ type EpisodeUpdateOne struct {
fields []string
hooks []Hook
mutation *EpisodeMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// SetSeasonID sets the "season_id" field.
@@ -395,7 +395,7 @@ func (_u *EpisodeUpdateOne) sqlSave(ctx context.Context) (_node *Episode, 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{episode.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
diff --git a/examples/ydb/ent/season_create.go b/examples/ydb/ent/season_create.go
index bb49606788..07270e036f 100644
--- a/examples/ydb/ent/season_create.go
+++ b/examples/ydb/ent/season_create.go
@@ -12,6 +12,7 @@ import (
"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"
@@ -24,7 +25,7 @@ type SeasonCreate struct {
config
mutation *SeasonMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// SetSeriesID sets the "series_id" field.
@@ -224,7 +225,7 @@ type SeasonCreateBulk struct {
config
err error
builders []*SeasonCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Save creates the Season entities in the database.
diff --git a/examples/ydb/ent/season_delete.go b/examples/ydb/ent/season_delete.go
index 89a1d5ee9c..8817be5b13 100644
--- a/examples/ydb/ent/season_delete.go
+++ b/examples/ydb/ent/season_delete.go
@@ -21,7 +21,7 @@ type SeasonDelete struct {
config
hooks []Hook
mutation *SeasonMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the SeasonDelete builder.
diff --git a/examples/ydb/ent/season_query.go b/examples/ydb/ent/season_query.go
index 34a45ed74b..67900aa04b 100644
--- a/examples/ydb/ent/season_query.go
+++ b/examples/ydb/ent/season_query.go
@@ -31,7 +31,7 @@ type SeasonQuery struct {
predicates []predicate.Season
withSeries *SeriesQuery
withEpisodes *EpisodeQuery
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/examples/ydb/ent/season_update.go b/examples/ydb/ent/season_update.go
index b9f44283dd..81b6b402cd 100644
--- a/examples/ydb/ent/season_update.go
+++ b/examples/ydb/ent/season_update.go
@@ -26,7 +26,7 @@ type SeasonUpdate struct {
config
hooks []Hook
mutation *SeasonMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the SeasonUpdate builder.
@@ -287,7 +287,7 @@ func (_u *SeasonUpdate) sqlSave(ctx context.Context) (_node int, err error) {
}
_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{season.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
@@ -304,7 +304,7 @@ type SeasonUpdateOne struct {
fields []string
hooks []Hook
mutation *SeasonMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// SetSeriesID sets the "series_id" field.
@@ -592,7 +592,7 @@ func (_u *SeasonUpdateOne) sqlSave(ctx context.Context) (_node *Season, 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{season.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
diff --git a/examples/ydb/ent/series_create.go b/examples/ydb/ent/series_create.go
index 6d4352e662..5d56ef3b6d 100644
--- a/examples/ydb/ent/series_create.go
+++ b/examples/ydb/ent/series_create.go
@@ -12,6 +12,7 @@ import (
"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"
@@ -23,7 +24,7 @@ type SeriesCreate struct {
config
mutation *SeriesMutation
hooks []Hook
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// SetTitle sets the "title" field.
@@ -194,7 +195,7 @@ type SeriesCreateBulk struct {
config
err error
builders []*SeriesCreate
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Save creates the Series entities in the database.
diff --git a/examples/ydb/ent/series_delete.go b/examples/ydb/ent/series_delete.go
index a66adf80f7..45b6bd9ffb 100644
--- a/examples/ydb/ent/series_delete.go
+++ b/examples/ydb/ent/series_delete.go
@@ -21,7 +21,7 @@ type SeriesDelete struct {
config
hooks []Hook
mutation *SeriesMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the SeriesDelete builder.
diff --git a/examples/ydb/ent/series_query.go b/examples/ydb/ent/series_query.go
index c3c484ba5b..76a915fada 100644
--- a/examples/ydb/ent/series_query.go
+++ b/examples/ydb/ent/series_query.go
@@ -29,7 +29,7 @@ type SeriesQuery struct {
inters []Interceptor
predicates []predicate.Series
withSeasons *SeasonQuery
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
diff --git a/examples/ydb/ent/series_update.go b/examples/ydb/ent/series_update.go
index 9c53f19fc0..e7cae45802 100644
--- a/examples/ydb/ent/series_update.go
+++ b/examples/ydb/ent/series_update.go
@@ -25,7 +25,7 @@ type SeriesUpdate struct {
config
hooks []Hook
mutation *SeriesMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// Where appends a list predicates to the SeriesUpdate builder.
@@ -238,7 +238,7 @@ func (_u *SeriesUpdate) sqlSave(ctx context.Context) (_node int, err error) {
}
_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{series.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
@@ -255,7 +255,7 @@ type SeriesUpdateOne struct {
fields []string
hooks []Hook
mutation *SeriesMutation
- retryConfig sqlgraph.RetryConfig
+ retryConfig sql.RetryConfig
}
// SetTitle sets the "title" field.
@@ -495,7 +495,7 @@ func (_u *SeriesUpdateOne) sqlSave(ctx context.Context) (_node *Series, 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{series.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
diff --git a/go.mod b/go.mod
index c3d32e35ae..a41b9692b7 100644
--- a/go.mod
+++ b/go.mod
@@ -64,4 +64,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
-replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.33
+replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.34
diff --git a/go.sum b/go.sum
index 5f73949be5..cc10301608 100644
--- a/go.sum
+++ b/go.sum
@@ -3,8 +3,8 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
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/LostImagin4tion/atlas v0.0.33 h1:RgcQhGG0MZDwheuFRiZu47ihFRDhtcYmbAT6KU3J3v0=
-github.com/LostImagin4tion/atlas v0.0.33/go.mod h1:FtOd0Ry45l3FeDVGVm8tf2SFWg3vHDztylE0eE3EWQ8=
+github.com/LostImagin4tion/atlas v0.0.34 h1:xCEZMtvTWwbuSU0TVQTsc60sKffIJxqjh/VIvRKcN5c=
+github.com/LostImagin4tion/atlas v0.0.34/go.mod h1:FtOd0Ry45l3FeDVGVm8tf2SFWg3vHDztylE0eE3EWQ8=
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=
From 90296b698139f8534a8528e4b2c8b994b1e53006 Mon Sep 17 00:00:00 2001
From: Egor Danilov <63148392+LostImagin4tion@users.noreply.github.com>
Date: Tue, 17 Feb 2026 14:35:26 +0300
Subject: [PATCH 11/14] dialect/sql: removed redundant yql statements (#14)
---
dialect/sql/builder.go | 348 ++++--------------------------
dialect/sql/builder_test.go | 412 ------------------------------------
2 files changed, 44 insertions(+), 716 deletions(-)
diff --git a/dialect/sql/builder.go b/dialect/sql/builder.go
index 0a3264e468..29b514e310 100644
--- a/dialect/sql/builder.go
+++ b/dialect/sql/builder.go
@@ -157,8 +157,7 @@ type InsertBuilder struct {
conflict *conflict
// YDB-specific:
- isUpsert bool // use UPSERT instead of INSERT
- isReplace bool // use REPLACE instead of INSERT
+ isUpsert bool // use UPSERT instead of INSERT
}
// Insert creates a builder for the `INSERT INTO` statement.
@@ -186,21 +185,6 @@ func Upsert(table string) *InsertBuilder {
return &InsertBuilder{table: table, isUpsert: true}
}
-// Replace creates a builder for the `REPLACE INTO` statement.
-// REPLACE overwrites entire rows based on primary key comparison.
-// For existing rows, the entire row is replaced (unspecified columns get default values).
-// For missing rows, new rows are inserted.
-//
-// Replace("users").
-// Columns("id", "name", "age").
-// Values(1, "a8m", 10).
-// Values(2, "foo", 20)
-//
-// Note: REPLACE is only supported in YDB dialect.
-func Replace(table string) *InsertBuilder {
- return &InsertBuilder{table: table, isReplace: true}
-}
-
// Schema sets the database name for the insert table.
func (i *InsertBuilder) Schema(name string) *InsertBuilder {
i.schema = name
@@ -494,20 +478,13 @@ func (i *InsertBuilder) Query() (string, []any) {
func (i *InsertBuilder) QueryErr() (string, []any, error) {
b := i.Builder.clone()
- switch {
- case i.isUpsert:
+ 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 ")
- case i.isReplace:
- if !b.ydb() {
- b.AddError(fmt.Errorf("REPLACE INTO is not supported by %q", b.dialect))
- return "", nil, b.Err()
- }
- b.WriteString("REPLACE INTO ")
- default:
+ } else {
b.WriteString("INSERT INTO ")
}
@@ -597,10 +574,6 @@ type UpdateBuilder struct {
order []any
limit *int
prefix Queries
-
- // YDB-specific:
- onSelect *Selector // UPDATE ON subquery
- isBatch bool // use BATCH UPDATE instead of UPDATE
}
// Update creates a builder for the `UPDATE` statement.
@@ -608,17 +581,6 @@ type UpdateBuilder struct {
// Update("users").Set("name", "foo").Set("age", 10)
func Update(table string) *UpdateBuilder { return &UpdateBuilder{table: table} }
-// BatchUpdate creates a builder for the `BATCH UPDATE` statement (YDB-specific).
-// BATCH UPDATE processes large tables in batches, minimizing lock invalidation risk.
-//
-// Note: BATCH UPDATE is only supported in YDB dialect.
-// Note: YDB uses path notation for tables, e.g. "/database/path/to/table"
-//
-// BatchUpdate("/local/my_table").Set("status", "active").Where(GT("id", 100))
-func BatchUpdate(table string) *UpdateBuilder {
- return &UpdateBuilder{table: table, isBatch: true}
-}
-
// Schema sets the database name for the updated table.
func (u *UpdateBuilder) Schema(name string) *UpdateBuilder {
u.schema = name
@@ -721,25 +683,6 @@ func (u *UpdateBuilder) Returning(columns ...string) *UpdateBuilder {
return u
}
-// On sets a subquery for the UPDATE ON statement (YDB-specific).
-// The subquery must return columns that include all primary key columns.
-// For each row in the subquery result, the corresponding row in the table is updated.
-//
-// Update("users").
-// On(
-// Select("key", "name")
-// .From(Table("temp_updates"))
-// .Where(EQ("status", "pending"))
-// )
-func (u *UpdateBuilder) On(s *Selector) *UpdateBuilder {
- if u.ydb() {
- u.onSelect = s
- } else {
- u.AddError(fmt.Errorf("UPDATE ON is not supported by %q", u.dialect))
- }
- return u
-}
-
// Query returns query representation of an `UPDATE` statement.
func (u *UpdateBuilder) Query() (string, []any) {
query, args, _ := u.QueryErr()
@@ -753,36 +696,10 @@ func (u *UpdateBuilder) QueryErr() (string, []any, error) {
b.Pad()
}
- // BATCH UPDATE (YDB-specific)
- if u.isBatch {
- if !b.ydb() {
- b.AddError(fmt.Errorf("BATCH UPDATE is not supported by %q", b.dialect))
- return "", nil, b.Err()
- }
- if len(u.returning) > 0 {
- b.AddError(fmt.Errorf("BATCH UPDATE: RETURNING clause is not supported"))
- return "", nil, b.Err()
- }
- if u.onSelect != nil {
- b.AddError(fmt.Errorf("BATCH UPDATE: UPDATE ON pattern is not supported"))
- return "", nil, b.Err()
- }
- b.WriteString("BATCH UPDATE ")
- } else {
- b.WriteString("UPDATE ")
- }
-
+ b.WriteString("UPDATE ")
b.writeSchema(u.schema)
b.Ident(u.table)
- // UPDATE ON pattern (YDB-specific)
- if u.onSelect != nil {
- b.WriteString(" ON ")
- b.Join(u.onSelect)
- joinReturning(u.returning, &b)
- return b.String(), b.args, nil
- }
-
// Standard UPDATE SET pattern
b.WriteString(" SET ")
u.writeSetter(&b)
@@ -827,14 +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
-
- // YDB-specific:
- onSelect *Selector // DELETE FROM ... ON SELECT pattern
- returning []string
- isBatch bool // use BATCH DELETE instead of DELETE
+ table string
+ schema string
+ where *Predicate
+ returning []string // YDB-specific
}
// Delete creates a builder for the `DELETE` statement.
@@ -852,16 +765,6 @@ type DeleteBuilder struct {
// )
func Delete(table string) *DeleteBuilder { return &DeleteBuilder{table: table} }
-// BatchDelete creates a builder for the `BATCH DELETE FROM` statement (YDB-specific).
-// BATCH DELETE processes large tables in batches, minimizing lock invalidation risk.
-//
-// Note: BATCH DELETE is only supported in YDB dialect.
-//
-// BatchDelete("/local/my_table").Where(GT("Key1", 1))
-func BatchDelete(table string) *DeleteBuilder {
- return &DeleteBuilder{table: table, isBatch: true}
-}
-
// Schema sets the database name for the table whose row will be deleted.
func (d *DeleteBuilder) Schema(name string) *DeleteBuilder {
d.schema = name
@@ -887,20 +790,6 @@ func (d *DeleteBuilder) FromSelect(s *Selector) *DeleteBuilder {
return d
}
-// On sets the subquery for DELETE FROM ... ON SELECT pattern (YDB-specific).
-// This allows deleting rows based on a subquery that returns primary key columns.
-//
-// Delete("users").
-// On(Select("id").From(Table("users")).Where(EQ("status", "inactive")))
-func (d *DeleteBuilder) On(s *Selector) *DeleteBuilder {
- if d.ydb() {
- d.onSelect = s
- } else {
- d.AddError(fmt.Errorf("DELETE ON is not supported by %q", d.dialect))
- }
- return d
-}
-
// Returning adds the `RETURNING` clause to the delete statement.
// Supported by YDB.
func (d *DeleteBuilder) Returning(columns ...string) *DeleteBuilder {
@@ -921,34 +810,11 @@ func (d *DeleteBuilder) Query() (string, []any) {
func (d *DeleteBuilder) QueryErr() (string, []any, error) {
b := d.Builder.clone()
- // BATCH DELETE (YDB-specific)
- if d.isBatch {
- if !b.ydb() {
- b.AddError(fmt.Errorf("BATCH DELETE is not supported by %q", b.dialect))
- return "", nil, b.Err()
- }
- if len(d.returning) > 0 {
- b.AddError(fmt.Errorf("BATCH DELETE: RETURNING clause is not supported"))
- return "", nil, b.Err()
- }
- if d.onSelect != nil {
- b.AddError(fmt.Errorf("BATCH DELETE: DELETE ON pattern is not supported"))
- return "", nil, b.Err()
- }
- b.WriteString("BATCH DELETE FROM ")
- } else {
- b.WriteString("DELETE FROM ")
- }
-
+ b.WriteString("DELETE FROM ")
b.writeSchema(d.schema)
b.Ident(d.table)
- // YDB-specific DELETE ON SELECT pattern
- if d.onSelect != nil {
- d.onSelect.SetDialect(b.dialect)
- b.WriteString(" ON ")
- b.Join(d.onSelect)
- } else if d.where != nil {
+ if d.where != nil {
b.WriteString(" WHERE ")
b.Join(d.where)
}
@@ -1887,8 +1753,7 @@ type SelectTable struct {
quote bool
// YDB-specific:
- index string // secondary index name for VIEW clause
- isCte bool // YDB-specific: marks this as a CTE reference
+ isCte bool // YDB-specific: marks this as a CTE reference
}
// Table returns a new table selector.
@@ -1911,20 +1776,6 @@ func (s *SelectTable) As(alias string) *SelectTable {
return s
}
-// View sets the secondary index name for the VIEW clause (YDB-specific).
-// This allows explicit use of secondary indexes in SELECT and JOIN operations.
-//
-// t := Table("users").View("idx_email").As("u")
-// Select().From(Table("orders")).Join(t).On(...)
-func (s *SelectTable) View(index string) *SelectTable {
- if s.ydb() {
- s.index = index
- } else {
- s.AddError(fmt.Errorf("VIEW is not supported by %q", s.dialect))
- }
- return s
-}
-
// C returns a formatted string for the table column.
func (s *SelectTable) C(column string) string {
name := s.name
@@ -1982,12 +1833,6 @@ func (s *SelectTable) ref() string {
b.Ident(s.name)
- // YDB-specific: VIEW clause for secondary indexes
- if s.index != "" {
- b.WriteString(" VIEW ")
- b.Ident(s.index)
- }
-
if s.as != "" {
b.WriteString(" AS ")
b.Ident(s.as)
@@ -2019,25 +1864,24 @@ type Selector struct {
Builder
// ctx stores contextual data typically from
// generated code such as alternate table schemas.
- ctx context.Context
- as string
- selection []*selection
- from []TableView
- joins []join
- collected [][]*Predicate
- where *Predicate
- or bool
- not bool
- order []any
- assumeOrder []string // YDB-specific: ASSUME ORDER BY columns
- group []string
- having *Predicate
- limit *int
- offset *int
- distinct bool
- setOps []setOp
- prefix Queries
- lock *LockOptions
+ ctx context.Context
+ as string
+ selection []*selection
+ from []TableView
+ joins []join
+ collected [][]*Predicate
+ where *Predicate
+ or bool
+ not bool
+ order []any
+ group []string
+ having *Predicate
+ limit *int
+ offset *int
+ distinct bool
+ setOps []setOp
+ prefix Queries
+ lock *LockOptions
}
// New returns a new Selector with the same dialect and context.
@@ -2456,36 +2300,11 @@ func (s *Selector) FullJoin(t TableView) *Selector {
return s.join("FULL JOIN", t)
}
-// LeftSemiJoin appends a `LEFT SEMI JOIN` clause to the statement (YDB-specific).
-func (s *Selector) LeftSemiJoin(t TableView) *Selector {
- return s.join("LEFT SEMI JOIN", t)
-}
-
-// RightSemiJoin appends a `RIGHT SEMI JOIN` clause to the statement (YDB-specific).
-func (s *Selector) RightSemiJoin(t TableView) *Selector {
- return s.join("RIGHT SEMI JOIN", t)
-}
-
-// LeftOnlyJoin appends a `LEFT ONLY JOIN` clause to the statement (YDB-specific).
-func (s *Selector) LeftOnlyJoin(t TableView) *Selector {
- return s.join("LEFT ONLY JOIN", t)
-}
-
-// RightOnlyJoin appends a `RIGHT ONLY JOIN` clause to the statement (YDB-specific).
-func (s *Selector) RightOnlyJoin(t TableView) *Selector {
- return s.join("RIGHT ONLY JOIN", t)
-}
-
// CrossJoin appends a `CROSS JOIN` clause to the statement.
func (s *Selector) CrossJoin(t TableView) *Selector {
return s.join("CROSS JOIN", t)
}
-// ExclusionJoin appends an `EXCLUSION JOIN` clause to the statement (YDB-specific).
-func (s *Selector) ExclusionJoin(t TableView) *Selector {
- return s.join("EXCLUSION 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{
@@ -2784,22 +2603,21 @@ func (s *Selector) Clone() *Selector {
joins[i] = s.joins[i].clone()
}
return &Selector{
- Builder: s.Builder.clone(),
- ctx: s.ctx,
- as: s.as,
- or: s.or,
- not: s.not,
- from: s.from,
- limit: s.limit,
- offset: s.offset,
- distinct: s.distinct,
- where: s.where.clone(),
- having: s.having.clone(),
- joins: append([]join{}, joins...),
- group: append([]string{}, s.group...),
- order: append([]any{}, s.order...),
- assumeOrder: append([]string{}, s.assumeOrder...),
- selection: append([]*selection{}, s.selection...),
+ Builder: s.Builder.clone(),
+ ctx: s.ctx,
+ as: s.as,
+ or: s.or,
+ not: s.not,
+ from: s.from,
+ limit: s.limit,
+ offset: s.offset,
+ distinct: s.distinct,
+ where: s.where.clone(),
+ having: s.having.clone(),
+ joins: append([]join{}, joins...),
+ group: append([]string{}, s.group...),
+ order: append([]any{}, s.order...),
+ selection: append([]*selection{}, s.selection...),
}
}
@@ -2827,11 +2645,6 @@ func DescExpr(x Querier) Querier {
// OrderBy appends the `ORDER BY` clause to the `SELECT` statement.
func (s *Selector) OrderBy(columns ...string) *Selector {
- if s.ydb() && len(s.assumeOrder) != 0 {
- s.AddError(fmt.Errorf("ORDER BY: can't be used with ASSUME ORDER BY simultaneously"))
- return s
- }
-
for i := range columns {
s.order = append(s.order, columns[i])
}
@@ -2873,27 +2686,6 @@ func (s *Selector) ClearOrder() *Selector {
return s
}
-// AssumeOrderBy appends the `ASSUME ORDER BY` clause to the `SELECT` statement (YDB-specific).
-// This tells YDB to assume the data is already sorted without actually sorting it.
-// This is an optimization hint and only works with column names (not expressions).
-//
-// Select("*").
-// From(Table("users")).
-// AssumeOrderBy("first-key", Desc("second-key"))
-func (s *Selector) AssumeOrderBy(columns ...string) *Selector {
- if s.ydb() {
- if len(s.order) != 0 {
- s.AddError(fmt.Errorf("ASSUME ORDER BY: can't be used with ORDER BY simultaneously"))
- return s
- }
-
- s.assumeOrder = append(s.assumeOrder, columns...)
- } else {
- s.AddError(fmt.Errorf("ASSUME ORDER BY is not supported by %q", s.dialect))
- }
- return s
-}
-
// GroupBy appends the `GROUP BY` clause to the `SELECT` statement.
func (s *Selector) GroupBy(columns ...string) *Selector {
s.group = append(s.group, columns...)
@@ -2991,7 +2783,6 @@ func (s *Selector) Query() (string, []any) {
s.applyAliasesToOrder()
}
joinOrder(s.order, &b)
- s.joinAssumeOrder(&b)
if s.limit != nil {
b.WriteString(" LIMIT ")
b.WriteString(strconv.Itoa(*s.limit))
@@ -3109,19 +2900,6 @@ func joinOrder(order []any, b *Builder) {
}
}
-func (s *Selector) joinAssumeOrder(b *Builder) {
- if !b.ydb() || len(s.assumeOrder) == 0 {
- return
- }
- b.WriteString(" ASSUME ORDER BY ")
- for i := range s.assumeOrder {
- if i > 0 {
- b.Comma()
- }
- b.Ident(s.assumeOrder[i])
- }
-}
-
func joinReturning(columns []string, b *Builder) {
supportedByDialect := b.postgres() || b.sqlite() || b.ydb()
if len(columns) == 0 || !supportedByDialect {
@@ -4185,19 +3963,6 @@ func (d *DialectBuilder) Upsert(table string) *InsertBuilder {
return b
}
-// Replace creates an InsertBuilder for the REPLACE statement with the configured dialect.
-// REPLACE is only supported in YDB dialect.
-//
-// Dialect(dialect.YDB).
-// Replace("users").
-// Columns("id", "name", "age").
-// Values(1, "a8m", 10)
-func (d *DialectBuilder) Replace(table string) *InsertBuilder {
- b := Replace(table)
- b.SetDialect(d.dialect)
- return b
-}
-
// Update creates a UpdateBuilder for the configured dialect.
//
// Dialect(dialect.Postgres).
@@ -4208,19 +3973,6 @@ func (d *DialectBuilder) Update(table string) *UpdateBuilder {
return b
}
-// BatchUpdate creates an UpdateBuilder for the BATCH UPDATE statement with the configured dialect.
-// BATCH UPDATE is only supported in YDB dialect.
-//
-// Dialect(dialect.YDB).
-// BatchUpdate("users").
-// Set("status", "active").
-// Where(GT("created_at", time.Now()))
-func (d *DialectBuilder) BatchUpdate(table string) *UpdateBuilder {
- b := BatchUpdate(table)
- b.SetDialect(d.dialect)
- return b
-}
-
// Delete creates a DeleteBuilder for the configured dialect.
//
// Dialect(dialect.Postgres).
@@ -4231,18 +3983,6 @@ func (d *DialectBuilder) Delete(table string) *DeleteBuilder {
return b
}
-// BatchDelete creates a DeleteBuilder for the BATCH DELETE statement with the configured dialect.
-// BATCH DELETE is only supported in YDB dialect.
-//
-// Dialect(dialect.YDB).
-// BatchDelete("users").
-// Where(GT("Key1", 1))
-func (d *DialectBuilder) BatchDelete(table string) *DeleteBuilder {
- b := BatchDelete(table)
- b.SetDialect(d.dialect)
- return b
-}
-
// Select creates a Selector for the configured dialect.
//
// Dialect(dialect.Postgres).
diff --git a/dialect/sql/builder_test.go b/dialect/sql/builder_test.go
index a3ff15fc98..839f471a1d 100644
--- a/dialect/sql/builder_test.go
+++ b/dialect/sql/builder_test.go
@@ -1575,26 +1575,6 @@ AND "users"."id1" < "users"."id2") AND "users"."id1" <= "users"."id2"`, "\n", ""
driver.NamedValue{Name: "p1", Value: "expired"},
},
},
- {
- input: func() Querier {
- d := Dialect(dialect.YDB)
- subquery := d.Select("id", "email").
- From(Table("users")).
- Where(EQ("status", "ToDelete"))
- return d.Delete("users").On(subquery)
- }(),
- wantQuery: "DELETE FROM `users` ON SELECT `id`, `email` FROM `users` WHERE `status` = $p0",
- wantArgs: []any{driver.NamedValue{Name: "p0", Value: "ToDelete"}},
- },
- {
- input: func() Querier {
- d := Dialect(dialect.YDB)
- subquery := d.Select("*").
- From(Table("temp_delete_list"))
- return d.Delete("users").On(subquery)
- }(),
- wantQuery: "DELETE FROM `users` ON SELECT * FROM `temp_delete_list`",
- },
{
input: Dialect(dialect.YDB).
Delete("orders").
@@ -1611,17 +1591,6 @@ AND "users"."id1" < "users"."id2") AND "users"."id1" <= "users"."id2"`, "\n", ""
wantQuery: "DELETE FROM `orders` WHERE `status` = $p0 RETURNING `order_id`, `order_date`",
wantArgs: []any{driver.NamedValue{Name: "p0", Value: "cancelled"}},
},
- {
- input: func() Querier {
- d := Dialect(dialect.YDB)
- subquery := d.Select("id").
- From(Table("temp_ids"))
- return d.Delete("users").
- On(subquery).
- Returning("id", "name")
- }(),
- wantQuery: "DELETE FROM `users` ON SELECT `id` FROM `temp_ids` RETURNING `id`, `name`",
- },
{
input: Dialect(dialect.YDB).Delete("users"),
wantQuery: "DELETE FROM `users`",
@@ -1734,47 +1703,6 @@ AND "users"."id1" < "users"."id2") AND "users"."id1" <= "users"."id2"`, "\n", ""
driver.NamedValue{Name: "p2", Value: "john@example.com"},
},
},
- {
- input: Dialect(dialect.YDB).
- Replace("users").
- Columns("id", "name", "age").
- Values(1, "a8m", 10),
- wantQuery: "REPLACE 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).
- Replace("users").
- Columns("id", "name", "age").
- Values(1, "a8m", 10).
- Values(2, "foo", 20),
- wantQuery: "REPLACE 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).
- Replace("orders").
- Columns("order_id", "status", "amount").
- Values(1001, "shipped", 500).
- Returning("*"),
- wantQuery: "REPLACE 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).
Update("users").
@@ -1799,126 +1727,6 @@ AND "users"."id1" < "users"."id2") AND "users"."id1" <= "users"."id2"`, "\n", ""
driver.NamedValue{Name: "p1", Value: "2023-01-01"},
},
},
- {
- input: func() Querier {
- d := Dialect(dialect.YDB)
- subquery := d.Select("key", "value").
- From(Table("temp_updates")).
- Where(EQ("status", "pending"))
- return d.Update("users").On(subquery)
- }(),
- wantQuery: "UPDATE `users` ON SELECT `key`, `value` FROM `temp_updates` WHERE `status` = $p0",
- wantArgs: []any{driver.NamedValue{Name: "p0", Value: "pending"}},
- },
- {
- input: func() Querier {
- d := Dialect(dialect.YDB)
- subquery := d.Select("*").
- From(Table("staged_data"))
- return d.Update("users").
- On(subquery).
- Returning("id", "name")
- }(),
- wantQuery: "UPDATE `users` ON SELECT * FROM `staged_data` RETURNING `id`, `name`",
- },
- {
- input: func() Querier {
- d := Dialect(dialect.YDB)
- t1 := d.Table("orders")
- t2 := d.Table("users").View("idx_email").As("u")
- return d.Select(t1.C("id"), t2.C("name")).
- From(t1).
- Join(t2).
- On(t1.C("user_id"), t2.C("id"))
- }(),
- wantQuery: "SELECT `orders`.`id` AS `id`, `u`.`name` AS `name` FROM `orders` JOIN `users` VIEW `idx_email` AS `u` ON `orders`.`user_id` = `u`.`id`",
- },
- {
- input: func() Querier {
- d := Dialect(dialect.YDB)
- t1 := d.Table("a_table").As("a")
- t2 := d.Table("b_table").View("b_index_ref").As("b")
- return d.Select(t1.C("value"), t2.C("value")).
- From(t1).
- Join(t2).
- On(t1.C("ref"), t2.C("ref"))
- }(),
- wantQuery: "SELECT `a`.`value` AS `value`, `b`.`value` AS `value` FROM `a_table` AS `a` JOIN `b_table` VIEW `b_index_ref` AS `b` ON `a`.`ref` = `b`.`ref`",
- },
- {
- input: func() Querier {
- d := Dialect(dialect.YDB)
- t1 := d.Table("orders")
- t2 := d.Table("products").View("idx_category")
- return d.Select("*").
- From(t1).
- LeftJoin(t2).
- On(t1.C("product_id"), t2.C("id")).
- Where(EQ(t2.C("category"), "Electronics"))
- }(),
- wantQuery: "SELECT * FROM `orders` LEFT JOIN `products` VIEW `idx_category` AS `t1` ON `orders`.`product_id` = `t1`.`id` WHERE `t1`.`category` = $p0",
- wantArgs: []any{driver.NamedValue{Name: "p0", Value: "Electronics"}},
- },
- {
- input: func() Querier {
- d := Dialect(dialect.YDB)
- t1 := d.Table("users")
- t2 := d.Table("blacklist")
- return d.Select(t1.C("id"), t1.C("name")).
- From(t1).
- LeftSemiJoin(t2).
- On(t1.C("id"), t2.C("user_id"))
- }(),
- wantQuery: "SELECT `users`.`id` AS `id`, `users`.`name` AS `name` FROM `users` LEFT SEMI JOIN `blacklist` AS `t1` ON `users`.`id` = `t1`.`user_id`",
- },
- {
- input: func() Querier {
- d := Dialect(dialect.YDB)
- t1 := d.Table("orders")
- t2 := d.Table("active_users").As("t1")
- return d.Select(t2.C("id"), t2.C("email")).
- From(t1).
- RightSemiJoin(t2).
- On(t1.C("user_id"), t2.C("id"))
- }(),
- wantQuery: "SELECT `t1`.`id` AS `id`, `t1`.`email` AS `email` FROM `orders` RIGHT SEMI JOIN `active_users` AS `t1` ON `orders`.`user_id` = `t1`.`id`",
- },
- {
- input: func() Querier {
- d := Dialect(dialect.YDB)
- t1 := d.Table("users")
- t2 := d.Table("deleted_users")
- return d.Select(t1.C("id"), t1.C("name")).
- From(t1).
- LeftOnlyJoin(t2).
- On(t1.C("id"), t2.C("id"))
- }(),
- wantQuery: "SELECT `users`.`id` AS `id`, `users`.`name` AS `name` FROM `users` LEFT ONLY JOIN `deleted_users` AS `t1` ON `users`.`id` = `t1`.`id`",
- },
- {
- input: func() Querier {
- d := Dialect(dialect.YDB)
- t1 := d.Table("archived")
- t2 := d.Table("users").As("t1")
- return d.Select(t2.C("id"), t2.C("status")).
- From(t1).
- RightOnlyJoin(t2).
- On(t1.C("user_id"), t2.C("id"))
- }(),
- wantQuery: "SELECT `t1`.`id` AS `id`, `t1`.`status` AS `status` FROM `archived` RIGHT ONLY JOIN `users` AS `t1` ON `archived`.`user_id` = `t1`.`id`",
- },
- {
- input: func() Querier {
- d := Dialect(dialect.YDB)
- t1 := d.Table("table_a").As("a")
- t2 := d.Table("table_b").As("b")
- return d.Select(t1.C("key"), t2.C("key")).
- From(t1).
- ExclusionJoin(t2).
- On(t1.C("key"), t2.C("key"))
- }(),
- wantQuery: "SELECT `a`.`key` AS `key`, `b`.`key` AS `key` FROM `table_a` AS `a` EXCLUSION JOIN `table_b` AS `b` ON `a`.`key` = `b`.`key`",
- },
{
input: func() Querier {
t1 := Table("users").As("u")
@@ -2231,226 +2039,6 @@ func TestSelector_Intersect(t *testing.T) {
require.Equal(t, []any{20, "true", 18}, args)
}
-func TestSelector_AssumeOrderBy_YDB(t *testing.T) {
- query, args := Dialect(dialect.YDB).
- Select("*").
- From(Table("my_table")).
- AssumeOrderBy("key").
- Query()
- require.Equal(t, "SELECT * FROM `my_table` ASSUME ORDER BY `key`", query)
- require.Empty(t, args)
-
- query, args = Dialect(dialect.YDB).
- Select("key", "subkey").
- From(Table("my_table")).
- AssumeOrderBy("key", Desc("subkey")).
- Query()
- require.Equal(t, "SELECT `key`, `subkey` FROM `my_table` ASSUME ORDER BY `key`, `subkey` DESC", query)
- require.Empty(t, args)
-
- query, args = Dialect(dialect.YDB).
- Select("*").
- From(Table("orders")).
- Where(EQ("status", "active")).
- AssumeOrderBy("created_at").
- Query()
- require.Equal(t, "SELECT * FROM `orders` WHERE `status` = $p0 ASSUME ORDER BY `created_at`", query)
- require.Equal(t, []any{driver.NamedValue{Name: "p0", Value: "active"}}, args)
-
- query, args = Dialect(dialect.YDB).
- Select("id", "name").
- From(Table("users")).
- AssumeOrderBy("id").
- Limit(10).
- Query()
- require.Equal(t, "SELECT `id`, `name` FROM `users` ASSUME ORDER BY `id` LIMIT 10", query)
- require.Empty(t, args)
-
- t.Run("OrderBy then AssumeOrderBy should error", func(t *testing.T) {
- selector := Dialect(dialect.YDB).
- Select("*").
- From(Table("users")).
- OrderBy("id").
- AssumeOrderBy("id")
-
- err := selector.Err()
- require.Error(t, err)
- })
-
- t.Run("AssumeOrderBy then OrderBy should error", func(t *testing.T) {
- selector := Dialect(dialect.YDB).
- Select("*").
- From(Table("users")).
- AssumeOrderBy("id").
- OrderBy("id")
-
- err := selector.Err()
- require.Error(t, err)
- })
-
- t.Run("Non-YDB dialect with AssumeOrderBy should error", func(t *testing.T) {
- selector := Dialect(dialect.Postgres).
- Select("*").
- From(Table("users")).
- AssumeOrderBy("name")
-
- err := selector.Err()
- require.Error(t, err)
- })
-}
-
-func TestSelector_VIEW_SecondaryIndex_YDB(t *testing.T) {
- t.Run("Simple SELECT with VIEW in FROM clause", func(t *testing.T) {
- d := Dialect(dialect.YDB)
- query, args := d.Select("series_id", "title", "info", "release_date", "views", "uploaded_user_id").
- From(d.Table("series").View("views_index")).
- Where(GTE("views", 1000)).
- Query()
-
- require.Equal(t, "SELECT `series_id`, `title`, `info`, `release_date`, `views`, `uploaded_user_id` FROM `series` VIEW `views_index` WHERE `views` >= $p0", query)
- require.Equal(t, []any{driver.NamedValue{Name: "p0", Value: 1000}}, args)
- })
-
- t.Run("JOIN with VIEW on both tables", func(t *testing.T) {
- d := Dialect(dialect.YDB)
- series := d.Table("series").View("users_index").As("t1")
- users := d.Table("users").View("name_index").As("t2")
-
- query, args := d.Select(series.C("series_id"), series.C("title")).
- From(series).
- Join(users).
- On(series.C("uploaded_user_id"), users.C("user_id")).
- Where(EQ(users.C("name"), "John Doe")).
- Query()
-
- require.Equal(t, "SELECT `t1`.`series_id` AS `series_id`, `t1`.`title` AS `title` FROM `series` VIEW `users_index` AS `t1` JOIN `users` VIEW `name_index` AS `t2` ON `t1`.`uploaded_user_id` = `t2`.`user_id` WHERE `t2`.`name` = $p0", query)
- require.Equal(t, []any{driver.NamedValue{Name: "p0", Value: "John Doe"}}, args)
- })
-
- t.Run("VIEW on non-YDB dialect should error", func(t *testing.T) {
- d := Dialect(dialect.Postgres)
- table := d.Table("users").View("idx_name")
-
- err := table.Err()
- require.Error(t, err)
- })
-}
-
-func TestBatchUpdate_YDB(t *testing.T) {
- t.Run("Basic BATCH UPDATE with SET and WHERE", func(t *testing.T) {
- d := Dialect(dialect.YDB)
- query, args := d.BatchUpdate("my_table").
- Set("Value1", "foo").
- Set("Value2", 0).
- Where(GT("Key1", 1)).
- Query()
-
- require.Equal(t, "BATCH UPDATE `my_table` SET `Value1` = $p0, `Value2` = $p1 WHERE `Key1` > $p2", query)
- require.Equal(t, []any{
- driver.NamedValue{Name: "p0", Value: "foo"},
- driver.NamedValue{Name: "p1", Value: 0},
- driver.NamedValue{Name: "p2", Value: 1},
- }, args)
- })
-
- t.Run("BATCH UPDATE on non-YDB dialect should error", func(t *testing.T) {
- builder := Dialect(dialect.MySQL).
- BatchUpdate("users").
- Set("status", "active").
- Where(GT("created_at", "2024-01-01"))
-
- query, args, err := builder.QueryErr()
-
- require.Empty(t, query)
- require.Empty(t, args)
- require.Error(t, err)
- })
-
- t.Run("BATCH UPDATE with RETURNING should error", func(t *testing.T) {
- builder := Dialect(dialect.YDB).
- BatchUpdate("users").
- Set("status", "active").
- Returning("id", "status")
-
- query, args, err := builder.QueryErr()
-
- require.Empty(t, query)
- require.Empty(t, args)
- require.Error(t, err)
- })
-
- t.Run("BATCH UPDATE with UPDATE ON pattern should error", func(t *testing.T) {
- d := Dialect(dialect.YDB)
- subquery := d.Select("id").From(Table("orders")).Where(EQ("status", "pending"))
-
- builder := d.BatchUpdate("users").
- Set("status", "active").
- On(subquery)
-
- query, args, err := builder.QueryErr()
-
- require.Empty(t, query)
- require.Empty(t, args)
- require.Error(t, err)
- require.Contains(t, err.Error(), "BATCH UPDATE: UPDATE ON pattern is not supported")
- })
-}
-
-func TestBatchDelete_YDB(t *testing.T) {
- t.Run("Basic BATCH DELETE", func(t *testing.T) {
- d := Dialect(dialect.YDB)
- query, args := d.BatchDelete("my_table").
- Where(And(GT("Key1", 1), GTE("Key2", "One"))).
- Query()
-
- require.Equal(t, "BATCH DELETE FROM `my_table` WHERE `Key1` > $p0 AND `Key2` >= $p1", query)
- require.Equal(t, []any{
- driver.NamedValue{Name: "p0", Value: 1},
- driver.NamedValue{Name: "p1", Value: "One"},
- }, args)
- })
-
- t.Run("BATCH DELETE on non-YDB dialect should error", func(t *testing.T) {
- builder := Dialect(dialect.MySQL).
- BatchDelete("users").
- Where(GT("id", 100))
-
- query, args, err := builder.QueryErr()
-
- require.Empty(t, query)
- require.Empty(t, args)
- require.Error(t, err)
- })
-
- t.Run("BATCH DELETE with RETURNING should error", func(t *testing.T) {
- builder := Dialect(dialect.YDB).
- BatchDelete("users").
- Where(GT("id", 100)).
- Returning("id")
-
- query, args, err := builder.QueryErr()
-
- require.Empty(t, query)
- require.Empty(t, args)
- require.Error(t, err)
- })
-
- t.Run("BATCH DELETE with DELETE ON pattern should error", func(t *testing.T) {
- d := Dialect(dialect.YDB)
- subquery := d.Select("id").From(Table("users")).Where(EQ("status", "deleted"))
-
- builder := d.BatchDelete("users").
- On(subquery)
-
- query, args, err := builder.QueryErr()
-
- require.Empty(t, query)
- require.Empty(t, args)
- require.Error(t, err)
- require.Contains(t, err.Error(), "BATCH DELETE: DELETE ON pattern is not supported")
- })
-}
-
func TestCreateView_YDB(t *testing.T) {
t.Run("Basic view with security_invoker", func(t *testing.T) {
d := Dialect(dialect.YDB)
From df0c934fba85b0db06ea5a7a7e88f095326ee3b9 Mon Sep 17 00:00:00 2001
From: Egor Danilov <63148392+LostImagin4tion@users.noreply.github.com>
Date: Wed, 18 Feb 2026 19:27:01 +0300
Subject: [PATCH 12/14] doc/md: updated ydb docs (#16)
---
doc/md/ydb.md | 97 +++++++++++++++++++++++++--------------------------
1 file changed, 48 insertions(+), 49 deletions(-)
diff --git a/doc/md/ydb.md b/doc/md/ydb.md
index 53b7529b8e..3dcb237dfe 100644
--- a/doc/md/ydb.md
+++ b/doc/md/ydb.md
@@ -45,12 +45,48 @@ func main() {
}
```
+## 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
-YDB requires special handling for transient errors (network issues, temporary unavailability, etc.).
+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:
@@ -95,61 +131,29 @@ Common retry options from `ydb-go-sdk`:
| `retry.WithLabel(string)` | Add a label for debugging/tracing |
| `retry.WithTrace(trace.Retry)` | Enable retry tracing |
-## YDB-Specific SQL Features
-
-The ent SQL builder supports several YDB-specific SQL constructs that are used internally
-or can be leveraged for advanced use cases.
-
-### UPSERT and REPLACE
-
-YDB doesn't support the standard `ON CONFLICT` clause. Instead, it uses `UPSERT` and `REPLACE` statements:
-
-- **UPSERT**: Inserts a new row or updates an existing row if a conflict occurs
-- **REPLACE**: Replaces the entire row if a conflict occurs
-
-Ent automatically uses `UPSERT` when you configure `OnConflict` options in your create operations.
-
-### BATCH Operations
-
-For large tables, YDB provides `BATCH UPDATE` and `BATCH DELETE` statements that process data
-in batches, minimizing lock invalidation risk. These are used internally by ent when appropriate.
-
-### Special JOIN Types
-
-YDB supports additional JOIN types beyond the standard SQL joins:
-
-| Join Type | Description |
-|-----------|-------------|
-| `LEFT SEMI JOIN` | Returns rows from left table that have matches in right table |
-| `RIGHT SEMI JOIN` | Returns rows from right table that have matches in left table |
-| `LEFT ONLY JOIN` | Returns rows from left table that have no matches in right table |
-| `RIGHT ONLY JOIN` | Returns rows from right table that have no matches in left table |
-| `EXCLUSION JOIN` | Returns rows that don't have matches in either table |
+## Known Limitations
-### VIEW Clause for Secondary Indexes
+When using ent with YDB, be aware of the following limitations:
-YDB allows explicit use of secondary indexes via the `VIEW` clause. This is an optimization
-hint that tells YDB to use a specific index for the query.
+### No automatic retries when using Client.BeginTx
-### Named Parameters
+`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.
-YDB uses named parameters with the `$paramName` syntax (e.g., `$p1`, `$p2`) instead of
-positional placeholders. Ent handles this automatically.
+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).
-## Known Limitations
+### No Nested Transactions
-When using ent with YDB, be aware of the following limitations:
+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.
-### 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.
-
### Float/Double Index Restriction
YDB doesn't allow `Float` or `Double` types as index keys. If you define an index on a
@@ -160,11 +164,6 @@ float field, it will be skipped during migration.
YDB doesn't support enum types in DDL statements. Ent maps enum fields to `Utf8` (string)
type, with validation handled at the application level.
-### RowsAffected Behavior
-
-YDB's `RowsAffected()` doesn't return accurate counts. The ent driver uses the `RETURNING`
-clause internally to count affected rows when needed.
-
### Primary Key Requirements
YDB requires explicit primary keys for all tables. Make sure your ent schemas define
From c1c7eaf9376dd7c589b4b4707c0ea38d52b73016 Mon Sep 17 00:00:00 2001
From: Egor Danilov <63148392+LostImagin4tion@users.noreply.github.com>
Date: Tue, 24 Feb 2026 12:58:16 +0300
Subject: [PATCH 13/14] doc/md: fixed code snippet in ydb docs (#17)
---
doc/md/ydb.md | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/doc/md/ydb.md b/doc/md/ydb.md
index 3dcb237dfe..7848648872 100644
--- a/doc/md/ydb.md
+++ b/doc/md/ydb.md
@@ -15,7 +15,7 @@ YDB support is currently in **preview** and requires the [Atlas migration engine
## Opening a Connection
-To connect to YDB, use the `ydb.Open()` function from the `entgo.io/ent/dialect/ydb` package:
+To connect to YDB, use the standard `ent.Open()` function with the `"ydb"` dialect:
```go
package main
@@ -25,8 +25,6 @@ import (
"log"
"entdemo/ent"
-
- "entgo.io/ent/dialect/ydb"
)
func main() {
From 49e7554dac837958621264208866c9d72e2c46cc Mon Sep 17 00:00:00 2001
From: Egor Danilov <63148392+LostImagin4tion@users.noreply.github.com>
Date: Wed, 4 Mar 2026 00:03:12 +0300
Subject: [PATCH 14/14] all: replaced atlas dependency with ydb-platform source
(#18)
---
entc/integration/go.mod | 6 ++----
entc/integration/go.sum | 4 ++--
examples/go.mod | 6 ++----
examples/go.sum | 4 ++--
go.mod | 6 ++----
go.sum | 4 ++--
6 files changed, 12 insertions(+), 18 deletions(-)
diff --git a/entc/integration/go.mod b/entc/integration/go.mod
index b3bb11c531..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.9
-
-toolchain go1.24.11
+go 1.24.13
replace entgo.io/ent => ../../
@@ -50,4 +48,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
-replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.34
+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 680a4f10dd..a18cb0780d 100644
--- a/entc/integration/go.sum
+++ b/entc/integration/go.sum
@@ -5,8 +5,6 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
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/LostImagin4tion/atlas v0.0.34 h1:xCEZMtvTWwbuSU0TVQTsc60sKffIJxqjh/VIvRKcN5c=
-github.com/LostImagin4tion/atlas v0.0.34/go.mod h1:FtOd0Ry45l3FeDVGVm8tf2SFWg3vHDztylE0eE3EWQ8=
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=
@@ -121,6 +119,8 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
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=
diff --git a/examples/go.mod b/examples/go.mod
index 56ecf157a6..c4d345a263 100644
--- a/examples/go.mod
+++ b/examples/go.mod
@@ -1,8 +1,6 @@
module entgo.io/ent/examples
-go 1.24.9
-
-toolchain go1.24.11
+go 1.24.13
replace entgo.io/ent => ../
@@ -50,4 +48,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
-replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.34
+replace ariga.io/atlas => github.com/ydb-platform/ariga-atlas v0.0.1
diff --git a/examples/go.sum b/examples/go.sum
index 355d0d85e7..0d320bb6ae 100644
--- a/examples/go.sum
+++ b/examples/go.sum
@@ -449,8 +449,6 @@ github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/GoogleCloudPlatform/cloudsql-proxy v1.33.1/go.mod h1:n3KDPrdaY2p9Nr0B1allAdjYArwIpXQcitNbsS/Qiok=
github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
-github.com/LostImagin4tion/atlas v0.0.34 h1:xCEZMtvTWwbuSU0TVQTsc60sKffIJxqjh/VIvRKcN5c=
-github.com/LostImagin4tion/atlas v0.0.34/go.mod h1:FtOd0Ry45l3FeDVGVm8tf2SFWg3vHDztylE0eE3EWQ8=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
@@ -1697,6 +1695,8 @@ 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=
diff --git a/go.mod b/go.mod
index a41b9692b7..bedb5df1ba 100644
--- a/go.mod
+++ b/go.mod
@@ -1,8 +1,6 @@
module entgo.io/ent
-go 1.24.9
-
-toolchain go1.24.11
+go 1.24.13
require (
ariga.io/atlas v0.36.2-0.20250730182955-2c6300d0a3e1
@@ -64,4 +62,4 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
)
-replace ariga.io/atlas => github.com/LostImagin4tion/atlas v0.0.34
+replace ariga.io/atlas => github.com/ydb-platform/ariga-atlas v0.0.1
diff --git a/go.sum b/go.sum
index cc10301608..da8b2d1d85 100644
--- a/go.sum
+++ b/go.sum
@@ -3,8 +3,6 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
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/LostImagin4tion/atlas v0.0.34 h1:xCEZMtvTWwbuSU0TVQTsc60sKffIJxqjh/VIvRKcN5c=
-github.com/LostImagin4tion/atlas v0.0.34/go.mod h1:FtOd0Ry45l3FeDVGVm8tf2SFWg3vHDztylE0eE3EWQ8=
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=
@@ -156,6 +154,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
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=