From bd54486fb36ce72200f9fda133e84b94a68cb3c7 Mon Sep 17 00:00:00 2001 From: Tony Grosinger Date: Thu, 11 Jul 2024 21:09:15 -0700 Subject: [PATCH] Migrate from ent to sqlc --- .gitignore | 4 +- Makefile | 20 +- README.md | 58 +- config/config.yaml => config.yaml | 7 +- config/config.go | 40 +- db/migrations/001_init.up.sql | 23 + db/queries/password_tokens.sql | 30 + db/queries/users.sql | 27 + ent/client.go | 517 ----------- ent/ent.go | 611 ------------- ent/enttest/enttest.go | 84 -- ent/generate.go | 3 - ent/hook/hook.go | 211 ----- ent/migrate/migrate.go | 64 -- ent/migrate/schema.go | 56 -- ent/mutation.go | 1113 ------------------------ ent/passwordtoken.go | 158 ---- ent/passwordtoken/passwordtoken.go | 99 --- ent/passwordtoken/where.go | 210 ----- ent/passwordtoken_create.go | 253 ------ ent/passwordtoken_delete.go | 89 -- ent/passwordtoken_query.go | 614 ------------- ent/passwordtoken_update.go | 370 -------- ent/predicate/predicate.go | 13 - ent/runtime.go | 5 - ent/runtime/runtime.go | 56 -- ent/schema/passwordtoken.go | 34 - ent/schema/user.go | 64 -- ent/tx.go | 213 ----- ent/user.go | 178 ---- ent/user/user.go | 133 --- ent/user/where.go | 365 -------- ent/user_create.go | 320 ------- ent/user_delete.go | 89 -- ent/user_query.go | 607 ------------- ent/user_update.go | 521 ----------- go.mod | 8 + go.sum | 21 + pkg/db/time.go | 37 + pkg/handlers/auth.go | 117 +-- pkg/middleware/auth.go | 16 +- pkg/middleware/auth_test.go | 12 +- pkg/middleware/entity.go | 33 +- pkg/middleware/entity_test.go | 6 +- pkg/middleware/middleware_test.go | 6 +- pkg/models/db.go | 119 +++ pkg/models/sqlc/db.go | 31 + pkg/models/sqlc/models.go | 25 + pkg/models/sqlc/password_tokens.sql.go | 126 +++ pkg/models/sqlc/users.sql.go | 105 +++ pkg/models/users.go | 9 + pkg/page/page.go | 6 +- pkg/page/page_test.go | 4 +- pkg/services/auth.go | 78 +- pkg/services/auth_test.go | 22 +- pkg/services/container.go | 68 +- pkg/services/container_test.go | 3 +- pkg/services/services_test.go | 6 +- pkg/tests/tests.go | 22 +- sqlc.yaml | 29 + 60 files changed, 785 insertions(+), 7383 deletions(-) rename config/config.yaml => config.yaml (80%) create mode 100644 db/migrations/001_init.up.sql create mode 100644 db/queries/password_tokens.sql create mode 100644 db/queries/users.sql delete mode 100644 ent/client.go delete mode 100644 ent/ent.go delete mode 100644 ent/enttest/enttest.go delete mode 100644 ent/generate.go delete mode 100644 ent/hook/hook.go delete mode 100644 ent/migrate/migrate.go delete mode 100644 ent/migrate/schema.go delete mode 100644 ent/mutation.go delete mode 100644 ent/passwordtoken.go delete mode 100644 ent/passwordtoken/passwordtoken.go delete mode 100644 ent/passwordtoken/where.go delete mode 100644 ent/passwordtoken_create.go delete mode 100644 ent/passwordtoken_delete.go delete mode 100644 ent/passwordtoken_query.go delete mode 100644 ent/passwordtoken_update.go delete mode 100644 ent/predicate/predicate.go delete mode 100644 ent/runtime.go delete mode 100644 ent/runtime/runtime.go delete mode 100644 ent/schema/passwordtoken.go delete mode 100644 ent/schema/user.go delete mode 100644 ent/tx.go delete mode 100644 ent/user.go delete mode 100644 ent/user/user.go delete mode 100644 ent/user/where.go delete mode 100644 ent/user_create.go delete mode 100644 ent/user_delete.go delete mode 100644 ent/user_query.go delete mode 100644 ent/user_update.go create mode 100644 pkg/db/time.go create mode 100644 pkg/models/db.go create mode 100644 pkg/models/sqlc/db.go create mode 100644 pkg/models/sqlc/models.go create mode 100644 pkg/models/sqlc/password_tokens.sql.go create mode 100644 pkg/models/sqlc/users.sql.go create mode 100644 pkg/models/users.go create mode 100644 sqlc.yaml diff --git a/.gitignore b/.gitignore index cd5d60f..73b8fc0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ -.idea -dbs \ No newline at end of file +data.db* + diff --git a/Makefile b/Makefile index 57fad5d..815cad9 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,3 @@ -# Install Ent code-generation module -.PHONY: ent-install -ent-install: - go get -d entgo.io/ent/cmd/ent - -# Generate Ent code -.PHONY: ent-gen -ent-gen: - go generate ./ent - -# Create a new Ent entity -.PHONY: ent-new -ent-new: - go run entgo.io/ent/cmd/ent new $(name) - # Run the application .PHONY: run run: @@ -24,6 +9,11 @@ run: test: go test -count=1 -p 1 ./... +.PHONY: sqlc +sqlc: + rm -f pkg/models/sqlc/* + sqlc generate + # Check for direct dependency updates .PHONY: check-updates check-updates: diff --git a/README.md b/README.md index 1cebda5..00da19d 100644 --- a/README.md +++ b/README.md @@ -31,9 +31,7 @@ * [Database](#database) * [Auto-migrations](#auto-migrations) * [Separate test database](#separate-test-database) -* [ORM](#orm) - * [Entity types](#entity-types) - * [New entity type](#new-entity-type) + * [SQLC](#sqlc) * [Sessions](#sessions) * [Encryption](#encryption) * [Authentication](#authentication) @@ -173,7 +171,6 @@ The container is located at `pkg/services/container.go` and is meant to house al - Configuration - Cache - Database -- ORM - Web - Validator - Authentication @@ -238,13 +235,13 @@ func TestMain(m *testing.M) { ## Database -The database currently used is [SQLite](https://sqlite.org/) but you are free to use whatever you prefer. If you plan to continue using [Ent](https://entgo.io/), the incredible ORM, you can check their supported databases [here](https://entgo.io/docs/dialects). The database driver is provided by [go-sqlite3](https://github.com/mattn/go-sqlite3). A reference to the database is included in the `Container` if direct access is required. +The database currently used is [SQLite](https://sqlite.org/) but you are free to use whatever you prefer. The database driver is provided by [go-sqlite3](https://github.com/mattn/go-sqlite3). A reference to the database is included in the `Container` if direct access is required. Database configuration can be found and managed within the `config` package. ### Auto-migrations -[Ent](https://entgo.io/) provides automatic migrations which are executed on the database whenever the `Container` is created, which means they will run when the application starts. +[Golang Migrate](github.com/golang-migrate/migrate) provides automati migrat-ns on the database whenever the application starts. Migrations are written in the `db/migrations` directory, which must be present at runtime in the container. ### Separate test database @@ -254,41 +251,12 @@ When a `Container` is created, if the [environment](#environments) is set to `co When this project was using Postgres, it would automatically drop and recreate the test database. Since the current default is in-memory, that is no longer needed. If you decide to use a test database not in-memory, you can alter the `Container` initialization code to do this for you. -## ORM +## SQLC -As previously mentioned, [Ent](https://entgo.io/) is the supplied ORM. It can swapped out, but I highly recommend it. I don't think there is anything comparable for Go, at the current time. If you're not familiar with Ent, take a look through their top-notch [documentation](https://entgo.io/docs/getting-started). +Database interactions are handled using [sqlc](https://sqlc.dev) by writing raw SQL queries in the `database/queries` directory and then generating the necessary boilerplate code with `make sqlc`. This creates functions available on the `DBClient.C` object for each written query. -An Ent client is included in the `Container` to provide easy access to the ORM throughout the application. +If you want to group business logic for the database into functions beyond what can be performed in a single SQL query, you can create a sub-client, such as the example`DBUserClient` and attach methods which have access to the database. -Ent relies on code-generation for the entities you create to provide robust, type-safe data operations. Everything within the `ent` package in this repository is generated code for the two entity types listed below with the exception of the schema declaration. - -### Entity types - -The two included entity types are: -- User -- PasswordToken - -### New entity type - -While you should refer to their [documentation](https://entgo.io/docs/getting-started) for detailed usage, it's helpful to understand how to create an entity type and generate code. To make this easier, the `Makefile` contains some helpers. - -1. Ensure all Ent code is downloaded by executing `make ent-install`. -2. Create the new entity type by executing `make ent-new name=User` where `User` is the name of the entity type. This will generate a file like you can see in `ent/schema/user.go` though the `Fields()` and `Edges()` will be left empty. -3. Populate the `Fields()` and optionally the `Edges()` (which are the relationships to other entity types). -4. When done, generate all code by executing `make ent-gen`. - -The generated code is extremely flexible and impressive. An example to highlight this is one used within this application: - -```go -entity, err := c.ORM.PasswordToken. - Query(). - Where(passwordtoken.ID(tokenID)). - Where(passwordtoken.HasUserWith(user.ID(userID))). - Where(passwordtoken.CreatedAtGTE(expiration)). - Only(ctx.Request().Context()) -``` - -This executes a database query to return the _password token_ entity with a given ID that belong to a user with a given ID and has a _created at_ timestamp field that is greater than or equal to a given time. ## Sessions @@ -386,13 +354,13 @@ A `Handler` is a simple type that handles one or more of your routes and allows The provided patterns are not required, but were designed to make development as easy as possible. -For this example, we'll create a new handler which includes a GET and POST route and uses the ORM. Start by creating a file at `pkg/handlers/example.go`. +For this example, we'll create a new handler which includes a GET and POST route and uses the database. Start by creating a file at `pkg/handlers/example.go`. 1) Define the handler type: ```go type Example struct { - orm *ent.Client + db *services.DBClient *services.TemplateRenderer } ``` @@ -410,7 +378,7 @@ func init() { ```go func (e *Example) Init(c *services.Container) error { e.TemplateRenderer = c.TemplateRenderer - e.orm = c.ORM + e.db = c.DB return nil } ``` @@ -1054,7 +1022,7 @@ Tasks can be created and queued with various chained options: err := c.Tasks. New(task). Wait(30 * time.Second). // Wait 30 seconds before passing the task to the subscriber - At(time.Date(...)). // Wait until a given date before passing the task to the subscriber + At(time.Date(...)). // Wait until a given date before passing the task to the subscriber Tx(tx). // Include the queueing of this task in a database transaction Save() ``` @@ -1156,7 +1124,7 @@ The provided implementation uses the relatively new [log/slog](https://go.dev/bl ### Context -The simple `pkg/log` package provides the ability to set and get a logger from the Echo context. This is especially useful when you use the provided logger middleware (see below). If you intend to use a different logger, modify these methods to receive and return the logger of your choice. +The simple `pkg/log` package provides the ability to set and get a logger from the Echo context. This is especially useful when you use the provided logger middleware (see below). If you intend to use a different logger, modify these methods to receive and return the logger of your choice. ### Usage @@ -1205,7 +1173,7 @@ Thank you to all of the following amazing projects for making this possible. - [alpinejs](https://github.com/alpinejs/alpine) - [bulma](https://github.com/jgthms/bulma) - [echo](https://github.com/labstack/echo) -- [ent](https://github.com/ent/ent) +- [golang-migrate](https://github.com/golang-migrate/migrate) - [go](https://go.dev/) - [go-sqlite3](https://github.com/mattn/go-sqlite3) - [goqite](https://github.com/maragudk/goqite) @@ -1218,4 +1186,4 @@ Thank you to all of the following amazing projects for making this possible. - [sqlite](https://sqlite.org/) - [testify](https://github.com/stretchr/testify) - [validator](https://github.com/go-playground/validator) -- [viper](https://github.com/spf13/viper) \ No newline at end of file +- [viper](https://github.com/spf13/viper) diff --git a/config/config.yaml b/config.yaml similarity index 80% rename from config/config.yaml rename to config.yaml index 8d6c305..1892d07 100644 --- a/config/config.yaml +++ b/config.yaml @@ -26,10 +26,9 @@ cache: staticFile: "4380h" page: "24h" -database: - driver: "sqlite3" - connection: "dbs/main.db?_journal=WAL&_timeout=5000&_fk=true" - testConnection: ":memory:?_journal=WAL&_timeout=5000&_fk=true" +storage: + databaseFile: "data.db" + migrationsDir: db/migrations tasks: pollInterval: "1s" diff --git a/config/config.go b/config/config.go index b868259..3b7a6c2 100644 --- a/config/config.go +++ b/config/config.go @@ -2,6 +2,7 @@ package config import ( "os" + "path/filepath" "strings" "time" @@ -53,12 +54,12 @@ func SwitchEnvironment(env environment) { type ( // Config stores complete configuration Config struct { - HTTP HTTPConfig - App AppConfig - Cache CacheConfig - Database DatabaseConfig - Tasks TasksConfig - Mail MailConfig + HTTP HTTPConfig + App AppConfig + Cache CacheConfig + Storage StorageConfig + Tasks TasksConfig + Mail MailConfig } // HTTPConfig stores HTTP configuration @@ -97,11 +98,15 @@ type ( } } - // DatabaseConfig stores the database configuration - DatabaseConfig struct { - Driver string - Connection string - TestConnection string + // StorageConfig stores the storage configuration + StorageConfig struct { + // DatabaseFile is the path used to find the database file. + // It can be an absolute path, or a path relative to the config file location. + DatabaseFile string + + // MigrationsDir is the path used to find the migration files. + // It can be an absolute path, or a path relative to the config file location. + MigrationsDir string } // TasksConfig stores the tasks configuration @@ -130,8 +135,8 @@ func GetConfig() (Config, error) { viper.SetConfigType("yaml") viper.AddConfigPath(".") viper.AddConfigPath("config") - viper.AddConfigPath("../config") - viper.AddConfigPath("../../config") + viper.AddConfigPath("../") + viper.AddConfigPath("../../") // Load env variables viper.SetEnvPrefix("pagoda") @@ -146,5 +151,14 @@ func GetConfig() (Config, error) { return c, err } + usedConfigFilePath := viper.GetViper().ConfigFileUsed() + configFileDir := filepath.Dir(usedConfigFilePath) + if !filepath.IsAbs(c.Storage.DatabaseFile) { + c.Storage.DatabaseFile = filepath.Join(configFileDir, c.Storage.DatabaseFile) + } + if !filepath.IsAbs(c.Storage.MigrationsDir) { + c.Storage.MigrationsDir = filepath.Join(configFileDir, c.Storage.MigrationsDir) + } + return c, nil } diff --git a/db/migrations/001_init.up.sql b/db/migrations/001_init.up.sql new file mode 100644 index 0000000..752cdaa --- /dev/null +++ b/db/migrations/001_init.up.sql @@ -0,0 +1,23 @@ +CREATE TABLE password_tokens ( + id integer NOT NULL PRIMARY KEY AUTOINCREMENT, + hash text NOT NULL, + created_at text NOT NULL DEFAULT CURRENT_TIMESTAMP, + password_token_user integer NOT NULL, + + CONSTRAINT `password_tokens_users_user` + FOREIGN KEY (`password_token_user`) + REFERENCES `users` (`id`) + ON DELETE NO ACTION +) STRICT; + +CREATE TABLE users ( + id integer NOT NULL PRIMARY KEY AUTOINCREMENT, + name text NOT NULL, + email text NOT NULL, + password text NOT NULL, + verified integer NOT NULL DEFAULT 0, + created_at text NOT NULL DEFAULT CURRENT_TIMESTAMP +) STRICT; + +CREATE UNIQUE INDEX `users_email_key` ON `users` (`email`); + diff --git a/db/queries/password_tokens.sql b/db/queries/password_tokens.sql new file mode 100644 index 0000000..cd936fe --- /dev/null +++ b/db/queries/password_tokens.sql @@ -0,0 +1,30 @@ +-- name: GetAllPasswordTokensForUser :many +-- GetAllPasswordTokensForUser retrieves all password tokens without checking expiration. +SELECT * FROM password_tokens +WHERE password_token_user = ?; + +-- name: GetValidPasswordToken :one +-- GetValidPasswordToken returns only valid password tokens for the provided +-- user, and only if the created_at time is greater than the provided time. +SELECT * FROM password_tokens +WHERE + id = ? + AND password_token_user = ? + AND datetime(created_at) > datetime(?) +LIMIT 1; + +-- name: CreatePasswordToken :one +INSERT INTO password_tokens ( + hash, password_token_user +) VALUES ( + ?, ? +) RETURNING *; + +-- name: UpdatePasswordTokenCreatedAt :exec +UPDATE password_tokens +SET created_at = ? +WHERE id = ?; + +-- name: DeletePasswordTokens :exec +DELETE FROM password_tokens +WHERE password_token_user = ?; diff --git a/db/queries/users.sql b/db/queries/users.sql new file mode 100644 index 0000000..cf5e124 --- /dev/null +++ b/db/queries/users.sql @@ -0,0 +1,27 @@ +-- name: GetUserByEmail :one +SELECT * FROM users +WHERE email = lower(?) +LIMIT 1; + +-- name: GetUserByID :one +SELECT * FROM users +WHERE id = ? +LIMIT 1; + +-- name: CreateUser :one +INSERT INTO users ( + name, email, password +) VALUES ( + ?, ?, ? +) RETURNING *; + +-- name: UpdateUserPassword :exec +UPDATE users +SET password = ? +WHERE id = ?; + +-- name: UpdateUserSetVerified :exec +UPDATE users +SET verified = 1 +WHERE email = ?; + diff --git a/ent/client.go b/ent/client.go deleted file mode 100644 index 9560139..0000000 --- a/ent/client.go +++ /dev/null @@ -1,517 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package ent - -import ( - "context" - "errors" - "fmt" - "log" - "reflect" - - "entgo.io/ent" - "entgo.io/ent/dialect" - "entgo.io/ent/dialect/sql" - "entgo.io/ent/dialect/sql/sqlgraph" - - "git.grosinger.net/tgrosinger/saasitone/ent/migrate" - "git.grosinger.net/tgrosinger/saasitone/ent/passwordtoken" - "git.grosinger.net/tgrosinger/saasitone/ent/user" -) - -// 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 - // PasswordToken is the client for interacting with the PasswordToken builders. - PasswordToken *PasswordTokenClient - // User is the client for interacting with the User builders. - User *UserClient -} - -// 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.PasswordToken = NewPasswordTokenClient(c.config) - c.User = NewUserClient(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: - 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, - PasswordToken: NewPasswordTokenClient(cfg), - User: NewUserClient(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, - PasswordToken: NewPasswordTokenClient(cfg), - User: NewUserClient(cfg), - }, nil -} - -// Debug returns a new debug-client. It's used to get verbose logging on specific operations. -// -// client.Debug(). -// PasswordToken. -// 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.PasswordToken.Use(hooks...) - c.User.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.PasswordToken.Intercept(interceptors...) - c.User.Intercept(interceptors...) -} - -// Mutate implements the ent.Mutator interface. -func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) { - switch m := m.(type) { - case *PasswordTokenMutation: - return c.PasswordToken.mutate(ctx, m) - case *UserMutation: - return c.User.mutate(ctx, m) - default: - return nil, fmt.Errorf("ent: unknown mutation type %T", m) - } -} - -// PasswordTokenClient is a client for the PasswordToken schema. -type PasswordTokenClient struct { - config -} - -// NewPasswordTokenClient returns a client for the PasswordToken from the given config. -func NewPasswordTokenClient(c config) *PasswordTokenClient { - return &PasswordTokenClient{config: c} -} - -// Use adds a list of mutation hooks to the hooks stack. -// A call to `Use(f, g, h)` equals to `passwordtoken.Hooks(f(g(h())))`. -func (c *PasswordTokenClient) Use(hooks ...Hook) { - c.hooks.PasswordToken = append(c.hooks.PasswordToken, hooks...) -} - -// Intercept adds a list of query interceptors to the interceptors stack. -// A call to `Intercept(f, g, h)` equals to `passwordtoken.Intercept(f(g(h())))`. -func (c *PasswordTokenClient) Intercept(interceptors ...Interceptor) { - c.inters.PasswordToken = append(c.inters.PasswordToken, interceptors...) -} - -// Create returns a builder for creating a PasswordToken entity. -func (c *PasswordTokenClient) Create() *PasswordTokenCreate { - mutation := newPasswordTokenMutation(c.config, OpCreate) - return &PasswordTokenCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// CreateBulk returns a builder for creating a bulk of PasswordToken entities. -func (c *PasswordTokenClient) CreateBulk(builders ...*PasswordTokenCreate) *PasswordTokenCreateBulk { - return &PasswordTokenCreateBulk{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 *PasswordTokenClient) MapCreateBulk(slice any, setFunc func(*PasswordTokenCreate, int)) *PasswordTokenCreateBulk { - rv := reflect.ValueOf(slice) - if rv.Kind() != reflect.Slice { - return &PasswordTokenCreateBulk{err: fmt.Errorf("calling to PasswordTokenClient.MapCreateBulk with wrong type %T, need slice", slice)} - } - builders := make([]*PasswordTokenCreate, rv.Len()) - for i := 0; i < rv.Len(); i++ { - builders[i] = c.Create() - setFunc(builders[i], i) - } - return &PasswordTokenCreateBulk{config: c.config, builders: builders} -} - -// Update returns an update builder for PasswordToken. -func (c *PasswordTokenClient) Update() *PasswordTokenUpdate { - mutation := newPasswordTokenMutation(c.config, OpUpdate) - return &PasswordTokenUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// UpdateOne returns an update builder for the given entity. -func (c *PasswordTokenClient) UpdateOne(pt *PasswordToken) *PasswordTokenUpdateOne { - mutation := newPasswordTokenMutation(c.config, OpUpdateOne, withPasswordToken(pt)) - return &PasswordTokenUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// UpdateOneID returns an update builder for the given id. -func (c *PasswordTokenClient) UpdateOneID(id int) *PasswordTokenUpdateOne { - mutation := newPasswordTokenMutation(c.config, OpUpdateOne, withPasswordTokenID(id)) - return &PasswordTokenUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// Delete returns a delete builder for PasswordToken. -func (c *PasswordTokenClient) Delete() *PasswordTokenDelete { - mutation := newPasswordTokenMutation(c.config, OpDelete) - return &PasswordTokenDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// DeleteOne returns a builder for deleting the given entity. -func (c *PasswordTokenClient) DeleteOne(pt *PasswordToken) *PasswordTokenDeleteOne { - return c.DeleteOneID(pt.ID) -} - -// DeleteOneID returns a builder for deleting the given entity by its id. -func (c *PasswordTokenClient) DeleteOneID(id int) *PasswordTokenDeleteOne { - builder := c.Delete().Where(passwordtoken.ID(id)) - builder.mutation.id = &id - builder.mutation.op = OpDeleteOne - return &PasswordTokenDeleteOne{builder} -} - -// Query returns a query builder for PasswordToken. -func (c *PasswordTokenClient) Query() *PasswordTokenQuery { - return &PasswordTokenQuery{ - config: c.config, - ctx: &QueryContext{Type: TypePasswordToken}, - inters: c.Interceptors(), - } -} - -// Get returns a PasswordToken entity by its id. -func (c *PasswordTokenClient) Get(ctx context.Context, id int) (*PasswordToken, error) { - return c.Query().Where(passwordtoken.ID(id)).Only(ctx) -} - -// GetX is like Get, but panics if an error occurs. -func (c *PasswordTokenClient) GetX(ctx context.Context, id int) *PasswordToken { - obj, err := c.Get(ctx, id) - if err != nil { - panic(err) - } - return obj -} - -// QueryUser queries the user edge of a PasswordToken. -func (c *PasswordTokenClient) QueryUser(pt *PasswordToken) *UserQuery { - query := (&UserClient{config: c.config}).Query() - query.path = func(context.Context) (fromV *sql.Selector, _ error) { - id := pt.ID - step := sqlgraph.NewStep( - sqlgraph.From(passwordtoken.Table, passwordtoken.FieldID, id), - sqlgraph.To(user.Table, user.FieldID), - sqlgraph.Edge(sqlgraph.M2O, false, passwordtoken.UserTable, passwordtoken.UserColumn), - ) - fromV = sqlgraph.Neighbors(pt.driver.Dialect(), step) - return fromV, nil - } - return query -} - -// Hooks returns the client hooks. -func (c *PasswordTokenClient) Hooks() []Hook { - return c.hooks.PasswordToken -} - -// Interceptors returns the client interceptors. -func (c *PasswordTokenClient) Interceptors() []Interceptor { - return c.inters.PasswordToken -} - -func (c *PasswordTokenClient) mutate(ctx context.Context, m *PasswordTokenMutation) (Value, error) { - switch m.Op() { - case OpCreate: - return (&PasswordTokenCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) - case OpUpdate: - return (&PasswordTokenUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) - case OpUpdateOne: - return (&PasswordTokenUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) - case OpDelete, OpDeleteOne: - return (&PasswordTokenDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) - default: - return nil, fmt.Errorf("ent: unknown PasswordToken mutation op: %q", m.Op()) - } -} - -// UserClient is a client for the User schema. -type UserClient struct { - config -} - -// NewUserClient returns a client for the User from the given config. -func NewUserClient(c config) *UserClient { - return &UserClient{config: c} -} - -// Use adds a list of mutation hooks to the hooks stack. -// A call to `Use(f, g, h)` equals to `user.Hooks(f(g(h())))`. -func (c *UserClient) Use(hooks ...Hook) { - c.hooks.User = append(c.hooks.User, hooks...) -} - -// Intercept adds a list of query interceptors to the interceptors stack. -// A call to `Intercept(f, g, h)` equals to `user.Intercept(f(g(h())))`. -func (c *UserClient) Intercept(interceptors ...Interceptor) { - c.inters.User = append(c.inters.User, interceptors...) -} - -// Create returns a builder for creating a User entity. -func (c *UserClient) Create() *UserCreate { - mutation := newUserMutation(c.config, OpCreate) - return &UserCreate{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// CreateBulk returns a builder for creating a bulk of User entities. -func (c *UserClient) CreateBulk(builders ...*UserCreate) *UserCreateBulk { - return &UserCreateBulk{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 *UserClient) MapCreateBulk(slice any, setFunc func(*UserCreate, int)) *UserCreateBulk { - rv := reflect.ValueOf(slice) - if rv.Kind() != reflect.Slice { - return &UserCreateBulk{err: fmt.Errorf("calling to UserClient.MapCreateBulk with wrong type %T, need slice", slice)} - } - builders := make([]*UserCreate, rv.Len()) - for i := 0; i < rv.Len(); i++ { - builders[i] = c.Create() - setFunc(builders[i], i) - } - return &UserCreateBulk{config: c.config, builders: builders} -} - -// Update returns an update builder for User. -func (c *UserClient) Update() *UserUpdate { - mutation := newUserMutation(c.config, OpUpdate) - return &UserUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// UpdateOne returns an update builder for the given entity. -func (c *UserClient) UpdateOne(u *User) *UserUpdateOne { - mutation := newUserMutation(c.config, OpUpdateOne, withUser(u)) - return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// UpdateOneID returns an update builder for the given id. -func (c *UserClient) UpdateOneID(id int) *UserUpdateOne { - mutation := newUserMutation(c.config, OpUpdateOne, withUserID(id)) - return &UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// Delete returns a delete builder for User. -func (c *UserClient) Delete() *UserDelete { - mutation := newUserMutation(c.config, OpDelete) - return &UserDelete{config: c.config, hooks: c.Hooks(), mutation: mutation} -} - -// DeleteOne returns a builder for deleting the given entity. -func (c *UserClient) DeleteOne(u *User) *UserDeleteOne { - return c.DeleteOneID(u.ID) -} - -// DeleteOneID returns a builder for deleting the given entity by its id. -func (c *UserClient) DeleteOneID(id int) *UserDeleteOne { - builder := c.Delete().Where(user.ID(id)) - builder.mutation.id = &id - builder.mutation.op = OpDeleteOne - return &UserDeleteOne{builder} -} - -// Query returns a query builder for User. -func (c *UserClient) Query() *UserQuery { - return &UserQuery{ - config: c.config, - ctx: &QueryContext{Type: TypeUser}, - inters: c.Interceptors(), - } -} - -// Get returns a User entity by its id. -func (c *UserClient) Get(ctx context.Context, id int) (*User, error) { - return c.Query().Where(user.ID(id)).Only(ctx) -} - -// GetX is like Get, but panics if an error occurs. -func (c *UserClient) GetX(ctx context.Context, id int) *User { - obj, err := c.Get(ctx, id) - if err != nil { - panic(err) - } - return obj -} - -// QueryOwner queries the owner edge of a User. -func (c *UserClient) QueryOwner(u *User) *PasswordTokenQuery { - query := (&PasswordTokenClient{config: c.config}).Query() - query.path = func(context.Context) (fromV *sql.Selector, _ error) { - id := u.ID - step := sqlgraph.NewStep( - sqlgraph.From(user.Table, user.FieldID, id), - sqlgraph.To(passwordtoken.Table, passwordtoken.FieldID), - sqlgraph.Edge(sqlgraph.O2M, true, user.OwnerTable, user.OwnerColumn), - ) - fromV = sqlgraph.Neighbors(u.driver.Dialect(), step) - return fromV, nil - } - return query -} - -// Hooks returns the client hooks. -func (c *UserClient) Hooks() []Hook { - hooks := c.hooks.User - return append(hooks[:len(hooks):len(hooks)], user.Hooks[:]...) -} - -// Interceptors returns the client interceptors. -func (c *UserClient) Interceptors() []Interceptor { - return c.inters.User -} - -func (c *UserClient) mutate(ctx context.Context, m *UserMutation) (Value, error) { - switch m.Op() { - case OpCreate: - return (&UserCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) - case OpUpdate: - return (&UserUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) - case OpUpdateOne: - return (&UserUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx) - case OpDelete, OpDeleteOne: - return (&UserDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx) - default: - return nil, fmt.Errorf("ent: unknown User mutation op: %q", m.Op()) - } -} - -// hooks and interceptors per client, for fast access. -type ( - hooks struct { - PasswordToken, User []ent.Hook - } - inters struct { - PasswordToken, User []ent.Interceptor - } -) diff --git a/ent/ent.go b/ent/ent.go deleted file mode 100644 index 5d44ec4..0000000 --- a/ent/ent.go +++ /dev/null @@ -1,611 +0,0 @@ -// 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" - - "git.grosinger.net/tgrosinger/saasitone/ent/passwordtoken" - "git.grosinger.net/tgrosinger/saasitone/ent/user" -) - -// 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 -) - -// columnChecker checks if the column exists in the given table. -func checkColumn(table, column string) error { - initCheck.Do(func() { - columnCheck = sql.NewColumnCheck(map[string]func(string) bool{ - passwordtoken.Table: passwordtoken.ValidColumn, - user.Table: user.ValidColumn, - }) - }) - return columnCheck(table, column) -} - -// 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/ent/enttest/enttest.go b/ent/enttest/enttest.go deleted file mode 100644 index 9020d70..0000000 --- a/ent/enttest/enttest.go +++ /dev/null @@ -1,84 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package enttest - -import ( - "context" - - "entgo.io/ent/dialect/sql/schema" - - "git.grosinger.net/tgrosinger/saasitone/ent" - "git.grosinger.net/tgrosinger/saasitone/ent/migrate" - _ "git.grosinger.net/tgrosinger/saasitone/ent/runtime" // required by schema hooks. -) - -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/ent/generate.go b/ent/generate.go deleted file mode 100644 index 8d3fdfd..0000000 --- a/ent/generate.go +++ /dev/null @@ -1,3 +0,0 @@ -package ent - -//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate ./schema diff --git a/ent/hook/hook.go b/ent/hook/hook.go deleted file mode 100644 index 8826e4a..0000000 --- a/ent/hook/hook.go +++ /dev/null @@ -1,211 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package hook - -import ( - "context" - "fmt" - - "git.grosinger.net/tgrosinger/saasitone/ent" -) - -// The PasswordTokenFunc type is an adapter to allow the use of ordinary -// function as PasswordToken mutator. -type PasswordTokenFunc func(context.Context, *ent.PasswordTokenMutation) (ent.Value, error) - -// Mutate calls f(ctx, m). -func (f PasswordTokenFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { - if mv, ok := m.(*ent.PasswordTokenMutation); ok { - return f(ctx, mv) - } - return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.PasswordTokenMutation", m) -} - -// The UserFunc type is an adapter to allow the use of ordinary -// function as User mutator. -type UserFunc func(context.Context, *ent.UserMutation) (ent.Value, error) - -// Mutate calls f(ctx, m). -func (f UserFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) { - if mv, ok := m.(*ent.UserMutation); ok { - return f(ctx, mv) - } - return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserMutation", 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/ent/migrate/migrate.go b/ent/migrate/migrate.go deleted file mode 100644 index 1956a6b..0000000 --- a/ent/migrate/migrate.go +++ /dev/null @@ -1,64 +0,0 @@ -// 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/ent/migrate/schema.go b/ent/migrate/schema.go deleted file mode 100644 index ae043a4..0000000 --- a/ent/migrate/schema.go +++ /dev/null @@ -1,56 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package migrate - -import ( - "entgo.io/ent/dialect/sql/schema" - "entgo.io/ent/schema/field" -) - -var ( - // PasswordTokensColumns holds the columns for the "password_tokens" table. - PasswordTokensColumns = []*schema.Column{ - {Name: "id", Type: field.TypeInt, Increment: true}, - {Name: "hash", Type: field.TypeString}, - {Name: "created_at", Type: field.TypeTime}, - {Name: "password_token_user", Type: field.TypeInt}, - } - // PasswordTokensTable holds the schema information for the "password_tokens" table. - PasswordTokensTable = &schema.Table{ - Name: "password_tokens", - Columns: PasswordTokensColumns, - PrimaryKey: []*schema.Column{PasswordTokensColumns[0]}, - ForeignKeys: []*schema.ForeignKey{ - { - Symbol: "password_tokens_users_user", - Columns: []*schema.Column{PasswordTokensColumns[3]}, - RefColumns: []*schema.Column{UsersColumns[0]}, - OnDelete: schema.NoAction, - }, - }, - } - // UsersColumns holds the columns for the "users" table. - UsersColumns = []*schema.Column{ - {Name: "id", Type: field.TypeInt, Increment: true}, - {Name: "name", Type: field.TypeString}, - {Name: "email", Type: field.TypeString, Unique: true}, - {Name: "password", Type: field.TypeString}, - {Name: "verified", Type: field.TypeBool, Default: false}, - {Name: "created_at", Type: field.TypeTime}, - } - // UsersTable holds the schema information for the "users" table. - UsersTable = &schema.Table{ - Name: "users", - Columns: UsersColumns, - PrimaryKey: []*schema.Column{UsersColumns[0]}, - } - // Tables holds all the tables in the schema. - Tables = []*schema.Table{ - PasswordTokensTable, - UsersTable, - } -) - -func init() { - PasswordTokensTable.ForeignKeys[0].RefTable = UsersTable -} diff --git a/ent/mutation.go b/ent/mutation.go deleted file mode 100644 index fc61aac..0000000 --- a/ent/mutation.go +++ /dev/null @@ -1,1113 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package ent - -import ( - "context" - "errors" - "fmt" - "sync" - "time" - - "entgo.io/ent" - "entgo.io/ent/dialect/sql" - - "git.grosinger.net/tgrosinger/saasitone/ent/passwordtoken" - "git.grosinger.net/tgrosinger/saasitone/ent/predicate" - "git.grosinger.net/tgrosinger/saasitone/ent/user" -) - -const ( - // Operation types. - OpCreate = ent.OpCreate - OpDelete = ent.OpDelete - OpDeleteOne = ent.OpDeleteOne - OpUpdate = ent.OpUpdate - OpUpdateOne = ent.OpUpdateOne - - // Node types. - TypePasswordToken = "PasswordToken" - TypeUser = "User" -) - -// PasswordTokenMutation represents an operation that mutates the PasswordToken nodes in the graph. -type PasswordTokenMutation struct { - config - op Op - typ string - id *int - hash *string - created_at *time.Time - clearedFields map[string]struct{} - user *int - cleareduser bool - done bool - oldValue func(context.Context) (*PasswordToken, error) - predicates []predicate.PasswordToken -} - -var _ ent.Mutation = (*PasswordTokenMutation)(nil) - -// passwordtokenOption allows management of the mutation configuration using functional options. -type passwordtokenOption func(*PasswordTokenMutation) - -// newPasswordTokenMutation creates new mutation for the PasswordToken entity. -func newPasswordTokenMutation(c config, op Op, opts ...passwordtokenOption) *PasswordTokenMutation { - m := &PasswordTokenMutation{ - config: c, - op: op, - typ: TypePasswordToken, - clearedFields: make(map[string]struct{}), - } - for _, opt := range opts { - opt(m) - } - return m -} - -// withPasswordTokenID sets the ID field of the mutation. -func withPasswordTokenID(id int) passwordtokenOption { - return func(m *PasswordTokenMutation) { - var ( - err error - once sync.Once - value *PasswordToken - ) - m.oldValue = func(ctx context.Context) (*PasswordToken, error) { - once.Do(func() { - if m.done { - err = errors.New("querying old values post mutation is not allowed") - } else { - value, err = m.Client().PasswordToken.Get(ctx, id) - } - }) - return value, err - } - m.id = &id - } -} - -// withPasswordToken sets the old PasswordToken of the mutation. -func withPasswordToken(node *PasswordToken) passwordtokenOption { - return func(m *PasswordTokenMutation) { - m.oldValue = func(context.Context) (*PasswordToken, 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 PasswordTokenMutation) 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 PasswordTokenMutation) 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 -} - -// 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 *PasswordTokenMutation) ID() (id int, 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 *PasswordTokenMutation) IDs(ctx context.Context) ([]int, error) { - switch { - case m.op.Is(OpUpdateOne | OpDeleteOne): - id, exists := m.ID() - if exists { - return []int{id}, nil - } - fallthrough - case m.op.Is(OpUpdate | OpDelete): - return m.Client().PasswordToken.Query().Where(m.predicates...).IDs(ctx) - default: - return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) - } -} - -// SetHash sets the "hash" field. -func (m *PasswordTokenMutation) SetHash(s string) { - m.hash = &s -} - -// Hash returns the value of the "hash" field in the mutation. -func (m *PasswordTokenMutation) Hash() (r string, exists bool) { - v := m.hash - if v == nil { - return - } - return *v, true -} - -// OldHash returns the old "hash" field's value of the PasswordToken entity. -// If the PasswordToken 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 *PasswordTokenMutation) OldHash(ctx context.Context) (v string, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldHash is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldHash requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldHash: %w", err) - } - return oldValue.Hash, nil -} - -// ResetHash resets all changes to the "hash" field. -func (m *PasswordTokenMutation) ResetHash() { - m.hash = nil -} - -// SetCreatedAt sets the "created_at" field. -func (m *PasswordTokenMutation) SetCreatedAt(t time.Time) { - m.created_at = &t -} - -// CreatedAt returns the value of the "created_at" field in the mutation. -func (m *PasswordTokenMutation) CreatedAt() (r time.Time, exists bool) { - v := m.created_at - if v == nil { - return - } - return *v, true -} - -// OldCreatedAt returns the old "created_at" field's value of the PasswordToken entity. -// If the PasswordToken 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 *PasswordTokenMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldCreatedAt requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err) - } - return oldValue.CreatedAt, nil -} - -// ResetCreatedAt resets all changes to the "created_at" field. -func (m *PasswordTokenMutation) ResetCreatedAt() { - m.created_at = nil -} - -// SetUserID sets the "user" edge to the User entity by id. -func (m *PasswordTokenMutation) SetUserID(id int) { - m.user = &id -} - -// ClearUser clears the "user" edge to the User entity. -func (m *PasswordTokenMutation) ClearUser() { - m.cleareduser = true -} - -// UserCleared reports if the "user" edge to the User entity was cleared. -func (m *PasswordTokenMutation) UserCleared() bool { - return m.cleareduser -} - -// UserID returns the "user" edge ID in the mutation. -func (m *PasswordTokenMutation) UserID() (id int, exists bool) { - if m.user != nil { - return *m.user, true - } - return -} - -// UserIDs returns the "user" edge IDs in the mutation. -// Note that IDs always returns len(IDs) <= 1 for unique edges, and you should use -// UserID instead. It exists only for internal usage by the builders. -func (m *PasswordTokenMutation) UserIDs() (ids []int) { - if id := m.user; id != nil { - ids = append(ids, *id) - } - return -} - -// ResetUser resets all changes to the "user" edge. -func (m *PasswordTokenMutation) ResetUser() { - m.user = nil - m.cleareduser = false -} - -// Where appends a list predicates to the PasswordTokenMutation builder. -func (m *PasswordTokenMutation) Where(ps ...predicate.PasswordToken) { - m.predicates = append(m.predicates, ps...) -} - -// WhereP appends storage-level predicates to the PasswordTokenMutation builder. Using this method, -// users can use type-assertion to append predicates that do not depend on any generated package. -func (m *PasswordTokenMutation) WhereP(ps ...func(*sql.Selector)) { - p := make([]predicate.PasswordToken, len(ps)) - for i := range ps { - p[i] = ps[i] - } - m.Where(p...) -} - -// Op returns the operation name. -func (m *PasswordTokenMutation) Op() Op { - return m.op -} - -// SetOp allows setting the mutation operation. -func (m *PasswordTokenMutation) SetOp(op Op) { - m.op = op -} - -// Type returns the node type of this mutation (PasswordToken). -func (m *PasswordTokenMutation) 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 *PasswordTokenMutation) Fields() []string { - fields := make([]string, 0, 2) - if m.hash != nil { - fields = append(fields, passwordtoken.FieldHash) - } - if m.created_at != nil { - fields = append(fields, passwordtoken.FieldCreatedAt) - } - 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 *PasswordTokenMutation) Field(name string) (ent.Value, bool) { - switch name { - case passwordtoken.FieldHash: - return m.Hash() - case passwordtoken.FieldCreatedAt: - return m.CreatedAt() - } - 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 *PasswordTokenMutation) OldField(ctx context.Context, name string) (ent.Value, error) { - switch name { - case passwordtoken.FieldHash: - return m.OldHash(ctx) - case passwordtoken.FieldCreatedAt: - return m.OldCreatedAt(ctx) - } - return nil, fmt.Errorf("unknown PasswordToken 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 *PasswordTokenMutation) SetField(name string, value ent.Value) error { - switch name { - case passwordtoken.FieldHash: - v, ok := value.(string) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetHash(v) - return nil - case passwordtoken.FieldCreatedAt: - v, ok := value.(time.Time) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetCreatedAt(v) - return nil - } - return fmt.Errorf("unknown PasswordToken field %s", name) -} - -// AddedFields returns all numeric fields that were incremented/decremented during -// this mutation. -func (m *PasswordTokenMutation) 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 *PasswordTokenMutation) 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 *PasswordTokenMutation) AddField(name string, value ent.Value) error { - switch name { - } - return fmt.Errorf("unknown PasswordToken numeric field %s", name) -} - -// ClearedFields returns all nullable fields that were cleared during this -// mutation. -func (m *PasswordTokenMutation) ClearedFields() []string { - return nil -} - -// FieldCleared returns a boolean indicating if a field with the given name was -// cleared in this mutation. -func (m *PasswordTokenMutation) 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 *PasswordTokenMutation) ClearField(name string) error { - return fmt.Errorf("unknown PasswordToken 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 *PasswordTokenMutation) ResetField(name string) error { - switch name { - case passwordtoken.FieldHash: - m.ResetHash() - return nil - case passwordtoken.FieldCreatedAt: - m.ResetCreatedAt() - return nil - } - return fmt.Errorf("unknown PasswordToken field %s", name) -} - -// AddedEdges returns all edge names that were set/added in this mutation. -func (m *PasswordTokenMutation) AddedEdges() []string { - edges := make([]string, 0, 1) - if m.user != nil { - edges = append(edges, passwordtoken.EdgeUser) - } - return edges -} - -// AddedIDs returns all IDs (to other nodes) that were added for the given edge -// name in this mutation. -func (m *PasswordTokenMutation) AddedIDs(name string) []ent.Value { - switch name { - case passwordtoken.EdgeUser: - if id := m.user; id != nil { - return []ent.Value{*id} - } - } - return nil -} - -// RemovedEdges returns all edge names that were removed in this mutation. -func (m *PasswordTokenMutation) 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 *PasswordTokenMutation) RemovedIDs(name string) []ent.Value { - return nil -} - -// ClearedEdges returns all edge names that were cleared in this mutation. -func (m *PasswordTokenMutation) ClearedEdges() []string { - edges := make([]string, 0, 1) - if m.cleareduser { - edges = append(edges, passwordtoken.EdgeUser) - } - return edges -} - -// EdgeCleared returns a boolean which indicates if the edge with the given name -// was cleared in this mutation. -func (m *PasswordTokenMutation) EdgeCleared(name string) bool { - switch name { - case passwordtoken.EdgeUser: - return m.cleareduser - } - 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 *PasswordTokenMutation) ClearEdge(name string) error { - switch name { - case passwordtoken.EdgeUser: - m.ClearUser() - return nil - } - return fmt.Errorf("unknown PasswordToken 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 *PasswordTokenMutation) ResetEdge(name string) error { - switch name { - case passwordtoken.EdgeUser: - m.ResetUser() - return nil - } - return fmt.Errorf("unknown PasswordToken edge %s", name) -} - -// UserMutation represents an operation that mutates the User nodes in the graph. -type UserMutation struct { - config - op Op - typ string - id *int - name *string - email *string - password *string - verified *bool - created_at *time.Time - clearedFields map[string]struct{} - owner map[int]struct{} - removedowner map[int]struct{} - clearedowner bool - done bool - oldValue func(context.Context) (*User, error) - predicates []predicate.User -} - -var _ ent.Mutation = (*UserMutation)(nil) - -// userOption allows management of the mutation configuration using functional options. -type userOption func(*UserMutation) - -// newUserMutation creates new mutation for the User entity. -func newUserMutation(c config, op Op, opts ...userOption) *UserMutation { - m := &UserMutation{ - config: c, - op: op, - typ: TypeUser, - clearedFields: make(map[string]struct{}), - } - for _, opt := range opts { - opt(m) - } - return m -} - -// withUserID sets the ID field of the mutation. -func withUserID(id int) userOption { - return func(m *UserMutation) { - var ( - err error - once sync.Once - value *User - ) - m.oldValue = func(ctx context.Context) (*User, error) { - once.Do(func() { - if m.done { - err = errors.New("querying old values post mutation is not allowed") - } else { - value, err = m.Client().User.Get(ctx, id) - } - }) - return value, err - } - m.id = &id - } -} - -// withUser sets the old User of the mutation. -func withUser(node *User) userOption { - return func(m *UserMutation) { - m.oldValue = func(context.Context) (*User, 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 UserMutation) 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 UserMutation) 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 -} - -// 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 *UserMutation) ID() (id int, 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 *UserMutation) IDs(ctx context.Context) ([]int, error) { - switch { - case m.op.Is(OpUpdateOne | OpDeleteOne): - id, exists := m.ID() - if exists { - return []int{id}, nil - } - fallthrough - case m.op.Is(OpUpdate | OpDelete): - return m.Client().User.Query().Where(m.predicates...).IDs(ctx) - default: - return nil, fmt.Errorf("IDs is not allowed on %s operations", m.op) - } -} - -// SetName sets the "name" field. -func (m *UserMutation) SetName(s string) { - m.name = &s -} - -// Name returns the value of the "name" field in the mutation. -func (m *UserMutation) Name() (r string, exists bool) { - v := m.name - if v == nil { - return - } - return *v, true -} - -// OldName returns the old "name" field's value of the User entity. -// If the User 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 *UserMutation) OldName(ctx context.Context) (v string, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldName is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldName requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldName: %w", err) - } - return oldValue.Name, nil -} - -// ResetName resets all changes to the "name" field. -func (m *UserMutation) ResetName() { - m.name = nil -} - -// SetEmail sets the "email" field. -func (m *UserMutation) SetEmail(s string) { - m.email = &s -} - -// Email returns the value of the "email" field in the mutation. -func (m *UserMutation) Email() (r string, exists bool) { - v := m.email - if v == nil { - return - } - return *v, true -} - -// OldEmail returns the old "email" field's value of the User entity. -// If the User 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 *UserMutation) OldEmail(ctx context.Context) (v string, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldEmail is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldEmail requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldEmail: %w", err) - } - return oldValue.Email, nil -} - -// ResetEmail resets all changes to the "email" field. -func (m *UserMutation) ResetEmail() { - m.email = nil -} - -// SetPassword sets the "password" field. -func (m *UserMutation) SetPassword(s string) { - m.password = &s -} - -// Password returns the value of the "password" field in the mutation. -func (m *UserMutation) Password() (r string, exists bool) { - v := m.password - if v == nil { - return - } - return *v, true -} - -// OldPassword returns the old "password" field's value of the User entity. -// If the User 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 *UserMutation) OldPassword(ctx context.Context) (v string, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldPassword is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldPassword requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldPassword: %w", err) - } - return oldValue.Password, nil -} - -// ResetPassword resets all changes to the "password" field. -func (m *UserMutation) ResetPassword() { - m.password = nil -} - -// SetVerified sets the "verified" field. -func (m *UserMutation) SetVerified(b bool) { - m.verified = &b -} - -// Verified returns the value of the "verified" field in the mutation. -func (m *UserMutation) Verified() (r bool, exists bool) { - v := m.verified - if v == nil { - return - } - return *v, true -} - -// OldVerified returns the old "verified" field's value of the User entity. -// If the User 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 *UserMutation) OldVerified(ctx context.Context) (v bool, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldVerified is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldVerified requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldVerified: %w", err) - } - return oldValue.Verified, nil -} - -// ResetVerified resets all changes to the "verified" field. -func (m *UserMutation) ResetVerified() { - m.verified = nil -} - -// SetCreatedAt sets the "created_at" field. -func (m *UserMutation) SetCreatedAt(t time.Time) { - m.created_at = &t -} - -// CreatedAt returns the value of the "created_at" field in the mutation. -func (m *UserMutation) CreatedAt() (r time.Time, exists bool) { - v := m.created_at - if v == nil { - return - } - return *v, true -} - -// OldCreatedAt returns the old "created_at" field's value of the User entity. -// If the User 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 *UserMutation) OldCreatedAt(ctx context.Context) (v time.Time, err error) { - if !m.op.Is(OpUpdateOne) { - return v, errors.New("OldCreatedAt is only allowed on UpdateOne operations") - } - if m.id == nil || m.oldValue == nil { - return v, errors.New("OldCreatedAt requires an ID field in the mutation") - } - oldValue, err := m.oldValue(ctx) - if err != nil { - return v, fmt.Errorf("querying old value for OldCreatedAt: %w", err) - } - return oldValue.CreatedAt, nil -} - -// ResetCreatedAt resets all changes to the "created_at" field. -func (m *UserMutation) ResetCreatedAt() { - m.created_at = nil -} - -// AddOwnerIDs adds the "owner" edge to the PasswordToken entity by ids. -func (m *UserMutation) AddOwnerIDs(ids ...int) { - if m.owner == nil { - m.owner = make(map[int]struct{}) - } - for i := range ids { - m.owner[ids[i]] = struct{}{} - } -} - -// ClearOwner clears the "owner" edge to the PasswordToken entity. -func (m *UserMutation) ClearOwner() { - m.clearedowner = true -} - -// OwnerCleared reports if the "owner" edge to the PasswordToken entity was cleared. -func (m *UserMutation) OwnerCleared() bool { - return m.clearedowner -} - -// RemoveOwnerIDs removes the "owner" edge to the PasswordToken entity by IDs. -func (m *UserMutation) RemoveOwnerIDs(ids ...int) { - if m.removedowner == nil { - m.removedowner = make(map[int]struct{}) - } - for i := range ids { - delete(m.owner, ids[i]) - m.removedowner[ids[i]] = struct{}{} - } -} - -// RemovedOwner returns the removed IDs of the "owner" edge to the PasswordToken entity. -func (m *UserMutation) RemovedOwnerIDs() (ids []int) { - for id := range m.removedowner { - ids = append(ids, id) - } - return -} - -// OwnerIDs returns the "owner" edge IDs in the mutation. -func (m *UserMutation) OwnerIDs() (ids []int) { - for id := range m.owner { - ids = append(ids, id) - } - return -} - -// ResetOwner resets all changes to the "owner" edge. -func (m *UserMutation) ResetOwner() { - m.owner = nil - m.clearedowner = false - m.removedowner = nil -} - -// Where appends a list predicates to the UserMutation builder. -func (m *UserMutation) Where(ps ...predicate.User) { - m.predicates = append(m.predicates, ps...) -} - -// WhereP appends storage-level predicates to the UserMutation builder. Using this method, -// users can use type-assertion to append predicates that do not depend on any generated package. -func (m *UserMutation) WhereP(ps ...func(*sql.Selector)) { - p := make([]predicate.User, len(ps)) - for i := range ps { - p[i] = ps[i] - } - m.Where(p...) -} - -// Op returns the operation name. -func (m *UserMutation) Op() Op { - return m.op -} - -// SetOp allows setting the mutation operation. -func (m *UserMutation) SetOp(op Op) { - m.op = op -} - -// Type returns the node type of this mutation (User). -func (m *UserMutation) 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 *UserMutation) Fields() []string { - fields := make([]string, 0, 5) - if m.name != nil { - fields = append(fields, user.FieldName) - } - if m.email != nil { - fields = append(fields, user.FieldEmail) - } - if m.password != nil { - fields = append(fields, user.FieldPassword) - } - if m.verified != nil { - fields = append(fields, user.FieldVerified) - } - if m.created_at != nil { - fields = append(fields, user.FieldCreatedAt) - } - 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 *UserMutation) Field(name string) (ent.Value, bool) { - switch name { - case user.FieldName: - return m.Name() - case user.FieldEmail: - return m.Email() - case user.FieldPassword: - return m.Password() - case user.FieldVerified: - return m.Verified() - case user.FieldCreatedAt: - return m.CreatedAt() - } - 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 *UserMutation) OldField(ctx context.Context, name string) (ent.Value, error) { - switch name { - case user.FieldName: - return m.OldName(ctx) - case user.FieldEmail: - return m.OldEmail(ctx) - case user.FieldPassword: - return m.OldPassword(ctx) - case user.FieldVerified: - return m.OldVerified(ctx) - case user.FieldCreatedAt: - return m.OldCreatedAt(ctx) - } - return nil, fmt.Errorf("unknown User 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 *UserMutation) SetField(name string, value ent.Value) error { - switch name { - case user.FieldName: - v, ok := value.(string) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetName(v) - return nil - case user.FieldEmail: - v, ok := value.(string) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetEmail(v) - return nil - case user.FieldPassword: - v, ok := value.(string) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetPassword(v) - return nil - case user.FieldVerified: - v, ok := value.(bool) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetVerified(v) - return nil - case user.FieldCreatedAt: - v, ok := value.(time.Time) - if !ok { - return fmt.Errorf("unexpected type %T for field %s", value, name) - } - m.SetCreatedAt(v) - return nil - } - return fmt.Errorf("unknown User field %s", name) -} - -// AddedFields returns all numeric fields that were incremented/decremented during -// this mutation. -func (m *UserMutation) 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 *UserMutation) 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 *UserMutation) AddField(name string, value ent.Value) error { - switch name { - } - return fmt.Errorf("unknown User numeric field %s", name) -} - -// ClearedFields returns all nullable fields that were cleared during this -// mutation. -func (m *UserMutation) ClearedFields() []string { - return nil -} - -// FieldCleared returns a boolean indicating if a field with the given name was -// cleared in this mutation. -func (m *UserMutation) 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 *UserMutation) ClearField(name string) error { - return fmt.Errorf("unknown User 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 *UserMutation) ResetField(name string) error { - switch name { - case user.FieldName: - m.ResetName() - return nil - case user.FieldEmail: - m.ResetEmail() - return nil - case user.FieldPassword: - m.ResetPassword() - return nil - case user.FieldVerified: - m.ResetVerified() - return nil - case user.FieldCreatedAt: - m.ResetCreatedAt() - return nil - } - return fmt.Errorf("unknown User field %s", name) -} - -// AddedEdges returns all edge names that were set/added in this mutation. -func (m *UserMutation) AddedEdges() []string { - edges := make([]string, 0, 1) - if m.owner != nil { - edges = append(edges, user.EdgeOwner) - } - return edges -} - -// AddedIDs returns all IDs (to other nodes) that were added for the given edge -// name in this mutation. -func (m *UserMutation) AddedIDs(name string) []ent.Value { - switch name { - case user.EdgeOwner: - ids := make([]ent.Value, 0, len(m.owner)) - for id := range m.owner { - ids = append(ids, id) - } - return ids - } - return nil -} - -// RemovedEdges returns all edge names that were removed in this mutation. -func (m *UserMutation) RemovedEdges() []string { - edges := make([]string, 0, 1) - if m.removedowner != nil { - edges = append(edges, user.EdgeOwner) - } - return edges -} - -// RemovedIDs returns all IDs (to other nodes) that were removed for the edge with -// the given name in this mutation. -func (m *UserMutation) RemovedIDs(name string) []ent.Value { - switch name { - case user.EdgeOwner: - ids := make([]ent.Value, 0, len(m.removedowner)) - for id := range m.removedowner { - ids = append(ids, id) - } - return ids - } - return nil -} - -// ClearedEdges returns all edge names that were cleared in this mutation. -func (m *UserMutation) ClearedEdges() []string { - edges := make([]string, 0, 1) - if m.clearedowner { - edges = append(edges, user.EdgeOwner) - } - return edges -} - -// EdgeCleared returns a boolean which indicates if the edge with the given name -// was cleared in this mutation. -func (m *UserMutation) EdgeCleared(name string) bool { - switch name { - case user.EdgeOwner: - return m.clearedowner - } - 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 *UserMutation) ClearEdge(name string) error { - switch name { - } - return fmt.Errorf("unknown User 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 *UserMutation) ResetEdge(name string) error { - switch name { - case user.EdgeOwner: - m.ResetOwner() - return nil - } - return fmt.Errorf("unknown User edge %s", name) -} diff --git a/ent/passwordtoken.go b/ent/passwordtoken.go deleted file mode 100644 index 1bb4935..0000000 --- a/ent/passwordtoken.go +++ /dev/null @@ -1,158 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package ent - -import ( - "fmt" - "strings" - "time" - - "entgo.io/ent" - "entgo.io/ent/dialect/sql" - - "git.grosinger.net/tgrosinger/saasitone/ent/passwordtoken" - "git.grosinger.net/tgrosinger/saasitone/ent/user" -) - -// PasswordToken is the model entity for the PasswordToken schema. -type PasswordToken struct { - config `json:"-"` - // ID of the ent. - ID int `json:"id,omitempty"` - // Hash holds the value of the "hash" field. - Hash string `json:"-"` - // CreatedAt holds the value of the "created_at" field. - CreatedAt time.Time `json:"created_at,omitempty"` - // Edges holds the relations/edges for other nodes in the graph. - // The values are being populated by the PasswordTokenQuery when eager-loading is set. - Edges PasswordTokenEdges `json:"edges"` - password_token_user *int - selectValues sql.SelectValues -} - -// PasswordTokenEdges holds the relations/edges for other nodes in the graph. -type PasswordTokenEdges struct { - // User holds the value of the user edge. - User *User `json:"user,omitempty"` - // loadedTypes holds the information for reporting if a - // type was loaded (or requested) in eager-loading or not. - loadedTypes [1]bool -} - -// UserOrErr returns the User value or an error if the edge -// was not loaded in eager-loading, or loaded but was not found. -func (e PasswordTokenEdges) UserOrErr() (*User, error) { - if e.loadedTypes[0] { - if e.User == nil { - // Edge was loaded but was not found. - return nil, &NotFoundError{label: user.Label} - } - return e.User, nil - } - return nil, &NotLoadedError{edge: "user"} -} - -// scanValues returns the types for scanning values from sql.Rows. -func (*PasswordToken) scanValues(columns []string) ([]any, error) { - values := make([]any, len(columns)) - for i := range columns { - switch columns[i] { - case passwordtoken.FieldID: - values[i] = new(sql.NullInt64) - case passwordtoken.FieldHash: - values[i] = new(sql.NullString) - case passwordtoken.FieldCreatedAt: - values[i] = new(sql.NullTime) - case passwordtoken.ForeignKeys[0]: // password_token_user - values[i] = new(sql.NullInt64) - default: - values[i] = new(sql.UnknownType) - } - } - return values, nil -} - -// assignValues assigns the values that were returned from sql.Rows (after scanning) -// to the PasswordToken fields. -func (pt *PasswordToken) 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 passwordtoken.FieldID: - value, ok := values[i].(*sql.NullInt64) - if !ok { - return fmt.Errorf("unexpected type %T for field id", value) - } - pt.ID = int(value.Int64) - case passwordtoken.FieldHash: - if value, ok := values[i].(*sql.NullString); !ok { - return fmt.Errorf("unexpected type %T for field hash", values[i]) - } else if value.Valid { - pt.Hash = value.String - } - case passwordtoken.FieldCreatedAt: - if value, ok := values[i].(*sql.NullTime); !ok { - return fmt.Errorf("unexpected type %T for field created_at", values[i]) - } else if value.Valid { - pt.CreatedAt = value.Time - } - case passwordtoken.ForeignKeys[0]: - if value, ok := values[i].(*sql.NullInt64); !ok { - return fmt.Errorf("unexpected type %T for edge-field password_token_user", value) - } else if value.Valid { - pt.password_token_user = new(int) - *pt.password_token_user = int(value.Int64) - } - default: - pt.selectValues.Set(columns[i], values[i]) - } - } - return nil -} - -// Value returns the ent.Value that was dynamically selected and assigned to the PasswordToken. -// This includes values selected through modifiers, order, etc. -func (pt *PasswordToken) Value(name string) (ent.Value, error) { - return pt.selectValues.Get(name) -} - -// QueryUser queries the "user" edge of the PasswordToken entity. -func (pt *PasswordToken) QueryUser() *UserQuery { - return NewPasswordTokenClient(pt.config).QueryUser(pt) -} - -// Update returns a builder for updating this PasswordToken. -// Note that you need to call PasswordToken.Unwrap() before calling this method if this PasswordToken -// was returned from a transaction, and the transaction was committed or rolled back. -func (pt *PasswordToken) Update() *PasswordTokenUpdateOne { - return NewPasswordTokenClient(pt.config).UpdateOne(pt) -} - -// Unwrap unwraps the PasswordToken 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 (pt *PasswordToken) Unwrap() *PasswordToken { - _tx, ok := pt.config.driver.(*txDriver) - if !ok { - panic("ent: PasswordToken is not a transactional entity") - } - pt.config.driver = _tx.drv - return pt -} - -// String implements the fmt.Stringer. -func (pt *PasswordToken) String() string { - var builder strings.Builder - builder.WriteString("PasswordToken(") - builder.WriteString(fmt.Sprintf("id=%v, ", pt.ID)) - builder.WriteString("hash=") - builder.WriteString(", ") - builder.WriteString("created_at=") - builder.WriteString(pt.CreatedAt.Format(time.ANSIC)) - builder.WriteByte(')') - return builder.String() -} - -// PasswordTokens is a parsable slice of PasswordToken. -type PasswordTokens []*PasswordToken diff --git a/ent/passwordtoken/passwordtoken.go b/ent/passwordtoken/passwordtoken.go deleted file mode 100644 index 6e9c6c9..0000000 --- a/ent/passwordtoken/passwordtoken.go +++ /dev/null @@ -1,99 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package passwordtoken - -import ( - "time" - - "entgo.io/ent/dialect/sql" - "entgo.io/ent/dialect/sql/sqlgraph" -) - -const ( - // Label holds the string label denoting the passwordtoken type in the database. - Label = "password_token" - // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldHash holds the string denoting the hash field in the database. - FieldHash = "hash" - // FieldCreatedAt holds the string denoting the created_at field in the database. - FieldCreatedAt = "created_at" - // EdgeUser holds the string denoting the user edge name in mutations. - EdgeUser = "user" - // Table holds the table name of the passwordtoken in the database. - Table = "password_tokens" - // UserTable is the table that holds the user relation/edge. - UserTable = "password_tokens" - // UserInverseTable is the table name for the User entity. - // It exists in this package in order to avoid circular dependency with the "user" package. - UserInverseTable = "users" - // UserColumn is the table column denoting the user relation/edge. - UserColumn = "password_token_user" -) - -// Columns holds all SQL columns for passwordtoken fields. -var Columns = []string{ - FieldID, - FieldHash, - FieldCreatedAt, -} - -// ForeignKeys holds the SQL foreign-keys that are owned by the "password_tokens" -// table and are not defined as standalone fields in the schema. -var ForeignKeys = []string{ - "password_token_user", -} - -// 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 - } - } - for i := range ForeignKeys { - if column == ForeignKeys[i] { - return true - } - } - return false -} - -var ( - // HashValidator is a validator for the "hash" field. It is called by the builders before save. - HashValidator func(string) error - // DefaultCreatedAt holds the default value on creation for the "created_at" field. - DefaultCreatedAt func() time.Time -) - -// OrderOption defines the ordering options for the PasswordToken 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() -} - -// ByHash orders the results by the hash field. -func ByHash(opts ...sql.OrderTermOption) OrderOption { - return sql.OrderByField(FieldHash, opts...).ToFunc() -} - -// ByCreatedAt orders the results by the created_at field. -func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption { - return sql.OrderByField(FieldCreatedAt, opts...).ToFunc() -} - -// ByUserField orders the results by user field. -func ByUserField(field string, opts ...sql.OrderTermOption) OrderOption { - return func(s *sql.Selector) { - sqlgraph.OrderByNeighborTerms(s, newUserStep(), sql.OrderByField(field, opts...)) - } -} -func newUserStep() *sqlgraph.Step { - return sqlgraph.NewStep( - sqlgraph.From(Table, FieldID), - sqlgraph.To(UserInverseTable, FieldID), - sqlgraph.Edge(sqlgraph.M2O, false, UserTable, UserColumn), - ) -} diff --git a/ent/passwordtoken/where.go b/ent/passwordtoken/where.go deleted file mode 100644 index 2dcd4d2..0000000 --- a/ent/passwordtoken/where.go +++ /dev/null @@ -1,210 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package passwordtoken - -import ( - "time" - - "entgo.io/ent/dialect/sql" - "entgo.io/ent/dialect/sql/sqlgraph" - - "git.grosinger.net/tgrosinger/saasitone/ent/predicate" -) - -// ID filters vertices based on their ID field. -func ID(id int) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldEQ(FieldID, id)) -} - -// IDEQ applies the EQ predicate on the ID field. -func IDEQ(id int) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldEQ(FieldID, id)) -} - -// IDNEQ applies the NEQ predicate on the ID field. -func IDNEQ(id int) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldNEQ(FieldID, id)) -} - -// IDIn applies the In predicate on the ID field. -func IDIn(ids ...int) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldIn(FieldID, ids...)) -} - -// IDNotIn applies the NotIn predicate on the ID field. -func IDNotIn(ids ...int) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldNotIn(FieldID, ids...)) -} - -// IDGT applies the GT predicate on the ID field. -func IDGT(id int) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldGT(FieldID, id)) -} - -// IDGTE applies the GTE predicate on the ID field. -func IDGTE(id int) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldGTE(FieldID, id)) -} - -// IDLT applies the LT predicate on the ID field. -func IDLT(id int) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldLT(FieldID, id)) -} - -// IDLTE applies the LTE predicate on the ID field. -func IDLTE(id int) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldLTE(FieldID, id)) -} - -// Hash applies equality check predicate on the "hash" field. It's identical to HashEQ. -func Hash(v string) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldEQ(FieldHash, v)) -} - -// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. -func CreatedAt(v time.Time) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldEQ(FieldCreatedAt, v)) -} - -// HashEQ applies the EQ predicate on the "hash" field. -func HashEQ(v string) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldEQ(FieldHash, v)) -} - -// HashNEQ applies the NEQ predicate on the "hash" field. -func HashNEQ(v string) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldNEQ(FieldHash, v)) -} - -// HashIn applies the In predicate on the "hash" field. -func HashIn(vs ...string) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldIn(FieldHash, vs...)) -} - -// HashNotIn applies the NotIn predicate on the "hash" field. -func HashNotIn(vs ...string) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldNotIn(FieldHash, vs...)) -} - -// HashGT applies the GT predicate on the "hash" field. -func HashGT(v string) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldGT(FieldHash, v)) -} - -// HashGTE applies the GTE predicate on the "hash" field. -func HashGTE(v string) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldGTE(FieldHash, v)) -} - -// HashLT applies the LT predicate on the "hash" field. -func HashLT(v string) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldLT(FieldHash, v)) -} - -// HashLTE applies the LTE predicate on the "hash" field. -func HashLTE(v string) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldLTE(FieldHash, v)) -} - -// HashContains applies the Contains predicate on the "hash" field. -func HashContains(v string) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldContains(FieldHash, v)) -} - -// HashHasPrefix applies the HasPrefix predicate on the "hash" field. -func HashHasPrefix(v string) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldHasPrefix(FieldHash, v)) -} - -// HashHasSuffix applies the HasSuffix predicate on the "hash" field. -func HashHasSuffix(v string) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldHasSuffix(FieldHash, v)) -} - -// HashEqualFold applies the EqualFold predicate on the "hash" field. -func HashEqualFold(v string) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldEqualFold(FieldHash, v)) -} - -// HashContainsFold applies the ContainsFold predicate on the "hash" field. -func HashContainsFold(v string) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldContainsFold(FieldHash, v)) -} - -// CreatedAtEQ applies the EQ predicate on the "created_at" field. -func CreatedAtEQ(v time.Time) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldEQ(FieldCreatedAt, v)) -} - -// CreatedAtNEQ applies the NEQ predicate on the "created_at" field. -func CreatedAtNEQ(v time.Time) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldNEQ(FieldCreatedAt, v)) -} - -// CreatedAtIn applies the In predicate on the "created_at" field. -func CreatedAtIn(vs ...time.Time) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldIn(FieldCreatedAt, vs...)) -} - -// CreatedAtNotIn applies the NotIn predicate on the "created_at" field. -func CreatedAtNotIn(vs ...time.Time) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldNotIn(FieldCreatedAt, vs...)) -} - -// CreatedAtGT applies the GT predicate on the "created_at" field. -func CreatedAtGT(v time.Time) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldGT(FieldCreatedAt, v)) -} - -// CreatedAtGTE applies the GTE predicate on the "created_at" field. -func CreatedAtGTE(v time.Time) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldGTE(FieldCreatedAt, v)) -} - -// CreatedAtLT applies the LT predicate on the "created_at" field. -func CreatedAtLT(v time.Time) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldLT(FieldCreatedAt, v)) -} - -// CreatedAtLTE applies the LTE predicate on the "created_at" field. -func CreatedAtLTE(v time.Time) predicate.PasswordToken { - return predicate.PasswordToken(sql.FieldLTE(FieldCreatedAt, v)) -} - -// HasUser applies the HasEdge predicate on the "user" edge. -func HasUser() predicate.PasswordToken { - return predicate.PasswordToken(func(s *sql.Selector) { - step := sqlgraph.NewStep( - sqlgraph.From(Table, FieldID), - sqlgraph.Edge(sqlgraph.M2O, false, UserTable, UserColumn), - ) - sqlgraph.HasNeighbors(s, step) - }) -} - -// HasUserWith applies the HasEdge predicate on the "user" edge with a given conditions (other predicates). -func HasUserWith(preds ...predicate.User) predicate.PasswordToken { - return predicate.PasswordToken(func(s *sql.Selector) { - step := newUserStep() - 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.PasswordToken) predicate.PasswordToken { - return predicate.PasswordToken(sql.AndPredicates(predicates...)) -} - -// Or groups predicates with the OR operator between them. -func Or(predicates ...predicate.PasswordToken) predicate.PasswordToken { - return predicate.PasswordToken(sql.OrPredicates(predicates...)) -} - -// Not applies the not operator on the given predicate. -func Not(p predicate.PasswordToken) predicate.PasswordToken { - return predicate.PasswordToken(sql.NotPredicates(p)) -} diff --git a/ent/passwordtoken_create.go b/ent/passwordtoken_create.go deleted file mode 100644 index 9c5de10..0000000 --- a/ent/passwordtoken_create.go +++ /dev/null @@ -1,253 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package ent - -import ( - "context" - "errors" - "fmt" - "time" - - "entgo.io/ent/dialect/sql/sqlgraph" - "entgo.io/ent/schema/field" - - "git.grosinger.net/tgrosinger/saasitone/ent/passwordtoken" - "git.grosinger.net/tgrosinger/saasitone/ent/user" -) - -// PasswordTokenCreate is the builder for creating a PasswordToken entity. -type PasswordTokenCreate struct { - config - mutation *PasswordTokenMutation - hooks []Hook -} - -// SetHash sets the "hash" field. -func (ptc *PasswordTokenCreate) SetHash(s string) *PasswordTokenCreate { - ptc.mutation.SetHash(s) - return ptc -} - -// SetCreatedAt sets the "created_at" field. -func (ptc *PasswordTokenCreate) SetCreatedAt(t time.Time) *PasswordTokenCreate { - ptc.mutation.SetCreatedAt(t) - return ptc -} - -// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. -func (ptc *PasswordTokenCreate) SetNillableCreatedAt(t *time.Time) *PasswordTokenCreate { - if t != nil { - ptc.SetCreatedAt(*t) - } - return ptc -} - -// SetUserID sets the "user" edge to the User entity by ID. -func (ptc *PasswordTokenCreate) SetUserID(id int) *PasswordTokenCreate { - ptc.mutation.SetUserID(id) - return ptc -} - -// SetUser sets the "user" edge to the User entity. -func (ptc *PasswordTokenCreate) SetUser(u *User) *PasswordTokenCreate { - return ptc.SetUserID(u.ID) -} - -// Mutation returns the PasswordTokenMutation object of the builder. -func (ptc *PasswordTokenCreate) Mutation() *PasswordTokenMutation { - return ptc.mutation -} - -// Save creates the PasswordToken in the database. -func (ptc *PasswordTokenCreate) Save(ctx context.Context) (*PasswordToken, error) { - ptc.defaults() - return withHooks(ctx, ptc.sqlSave, ptc.mutation, ptc.hooks) -} - -// SaveX calls Save and panics if Save returns an error. -func (ptc *PasswordTokenCreate) SaveX(ctx context.Context) *PasswordToken { - v, err := ptc.Save(ctx) - if err != nil { - panic(err) - } - return v -} - -// Exec executes the query. -func (ptc *PasswordTokenCreate) Exec(ctx context.Context) error { - _, err := ptc.Save(ctx) - return err -} - -// ExecX is like Exec, but panics if an error occurs. -func (ptc *PasswordTokenCreate) ExecX(ctx context.Context) { - if err := ptc.Exec(ctx); err != nil { - panic(err) - } -} - -// defaults sets the default values of the builder before save. -func (ptc *PasswordTokenCreate) defaults() { - if _, ok := ptc.mutation.CreatedAt(); !ok { - v := passwordtoken.DefaultCreatedAt() - ptc.mutation.SetCreatedAt(v) - } -} - -// check runs all checks and user-defined validators on the builder. -func (ptc *PasswordTokenCreate) check() error { - if _, ok := ptc.mutation.Hash(); !ok { - return &ValidationError{Name: "hash", err: errors.New(`ent: missing required field "PasswordToken.hash"`)} - } - if v, ok := ptc.mutation.Hash(); ok { - if err := passwordtoken.HashValidator(v); err != nil { - return &ValidationError{Name: "hash", err: fmt.Errorf(`ent: validator failed for field "PasswordToken.hash": %w`, err)} - } - } - if _, ok := ptc.mutation.CreatedAt(); !ok { - return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "PasswordToken.created_at"`)} - } - if _, ok := ptc.mutation.UserID(); !ok { - return &ValidationError{Name: "user", err: errors.New(`ent: missing required edge "PasswordToken.user"`)} - } - return nil -} - -func (ptc *PasswordTokenCreate) sqlSave(ctx context.Context) (*PasswordToken, error) { - if err := ptc.check(); err != nil { - return nil, err - } - _node, _spec := ptc.createSpec() - if err := sqlgraph.CreateNode(ctx, ptc.driver, _spec); err != nil { - if sqlgraph.IsConstraintError(err) { - err = &ConstraintError{msg: err.Error(), wrap: err} - } - return nil, err - } - id := _spec.ID.Value.(int64) - _node.ID = int(id) - ptc.mutation.id = &_node.ID - ptc.mutation.done = true - return _node, nil -} - -func (ptc *PasswordTokenCreate) createSpec() (*PasswordToken, *sqlgraph.CreateSpec) { - var ( - _node = &PasswordToken{config: ptc.config} - _spec = sqlgraph.NewCreateSpec(passwordtoken.Table, sqlgraph.NewFieldSpec(passwordtoken.FieldID, field.TypeInt)) - ) - if value, ok := ptc.mutation.Hash(); ok { - _spec.SetField(passwordtoken.FieldHash, field.TypeString, value) - _node.Hash = value - } - if value, ok := ptc.mutation.CreatedAt(); ok { - _spec.SetField(passwordtoken.FieldCreatedAt, field.TypeTime, value) - _node.CreatedAt = value - } - if nodes := ptc.mutation.UserIDs(); len(nodes) > 0 { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2O, - Inverse: false, - Table: passwordtoken.UserTable, - Columns: []string{passwordtoken.UserColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt), - }, - } - for _, k := range nodes { - edge.Target.Nodes = append(edge.Target.Nodes, k) - } - _node.password_token_user = &nodes[0] - _spec.Edges = append(_spec.Edges, edge) - } - return _node, _spec -} - -// PasswordTokenCreateBulk is the builder for creating many PasswordToken entities in bulk. -type PasswordTokenCreateBulk struct { - config - err error - builders []*PasswordTokenCreate -} - -// Save creates the PasswordToken entities in the database. -func (ptcb *PasswordTokenCreateBulk) Save(ctx context.Context) ([]*PasswordToken, error) { - if ptcb.err != nil { - return nil, ptcb.err - } - specs := make([]*sqlgraph.CreateSpec, len(ptcb.builders)) - nodes := make([]*PasswordToken, len(ptcb.builders)) - mutators := make([]Mutator, len(ptcb.builders)) - for i := range ptcb.builders { - func(i int, root context.Context) { - builder := ptcb.builders[i] - builder.defaults() - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*PasswordTokenMutation) - 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, ptcb.builders[i+1].mutation) - } else { - spec := &sqlgraph.BatchCreateSpec{Nodes: specs} - // Invoke the actual operation on the latest mutation in the chain. - if err = sqlgraph.BatchCreate(ctx, ptcb.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 { - id := specs[i].ID.Value.(int64) - nodes[i].ID = int(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, ptcb.builders[0].mutation); err != nil { - return nil, err - } - } - return nodes, nil -} - -// SaveX is like Save, but panics if an error occurs. -func (ptcb *PasswordTokenCreateBulk) SaveX(ctx context.Context) []*PasswordToken { - v, err := ptcb.Save(ctx) - if err != nil { - panic(err) - } - return v -} - -// Exec executes the query. -func (ptcb *PasswordTokenCreateBulk) Exec(ctx context.Context) error { - _, err := ptcb.Save(ctx) - return err -} - -// ExecX is like Exec, but panics if an error occurs. -func (ptcb *PasswordTokenCreateBulk) ExecX(ctx context.Context) { - if err := ptcb.Exec(ctx); err != nil { - panic(err) - } -} diff --git a/ent/passwordtoken_delete.go b/ent/passwordtoken_delete.go deleted file mode 100644 index a21ad70..0000000 --- a/ent/passwordtoken_delete.go +++ /dev/null @@ -1,89 +0,0 @@ -// 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/schema/field" - - "git.grosinger.net/tgrosinger/saasitone/ent/passwordtoken" - "git.grosinger.net/tgrosinger/saasitone/ent/predicate" -) - -// PasswordTokenDelete is the builder for deleting a PasswordToken entity. -type PasswordTokenDelete struct { - config - hooks []Hook - mutation *PasswordTokenMutation -} - -// Where appends a list predicates to the PasswordTokenDelete builder. -func (ptd *PasswordTokenDelete) Where(ps ...predicate.PasswordToken) *PasswordTokenDelete { - ptd.mutation.Where(ps...) - return ptd -} - -// Exec executes the deletion query and returns how many vertices were deleted. -func (ptd *PasswordTokenDelete) Exec(ctx context.Context) (int, error) { - return withHooks(ctx, ptd.sqlExec, ptd.mutation, ptd.hooks) -} - -// ExecX is like Exec, but panics if an error occurs. -func (ptd *PasswordTokenDelete) ExecX(ctx context.Context) int { - n, err := ptd.Exec(ctx) - if err != nil { - panic(err) - } - return n -} - -func (ptd *PasswordTokenDelete) sqlExec(ctx context.Context) (int, error) { - _spec := sqlgraph.NewDeleteSpec(passwordtoken.Table, sqlgraph.NewFieldSpec(passwordtoken.FieldID, field.TypeInt)) - if ps := ptd.mutation.predicates; len(ps) > 0 { - _spec.Predicate = func(selector *sql.Selector) { - for i := range ps { - ps[i](selector) - } - } - } - affected, err := sqlgraph.DeleteNodes(ctx, ptd.driver, _spec) - if err != nil && sqlgraph.IsConstraintError(err) { - err = &ConstraintError{msg: err.Error(), wrap: err} - } - ptd.mutation.done = true - return affected, err -} - -// PasswordTokenDeleteOne is the builder for deleting a single PasswordToken entity. -type PasswordTokenDeleteOne struct { - ptd *PasswordTokenDelete -} - -// Where appends a list predicates to the PasswordTokenDelete builder. -func (ptdo *PasswordTokenDeleteOne) Where(ps ...predicate.PasswordToken) *PasswordTokenDeleteOne { - ptdo.ptd.mutation.Where(ps...) - return ptdo -} - -// Exec executes the deletion query. -func (ptdo *PasswordTokenDeleteOne) Exec(ctx context.Context) error { - n, err := ptdo.ptd.Exec(ctx) - switch { - case err != nil: - return err - case n == 0: - return &NotFoundError{passwordtoken.Label} - default: - return nil - } -} - -// ExecX is like Exec, but panics if an error occurs. -func (ptdo *PasswordTokenDeleteOne) ExecX(ctx context.Context) { - if err := ptdo.Exec(ctx); err != nil { - panic(err) - } -} diff --git a/ent/passwordtoken_query.go b/ent/passwordtoken_query.go deleted file mode 100644 index 1c4ce81..0000000 --- a/ent/passwordtoken_query.go +++ /dev/null @@ -1,614 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package ent - -import ( - "context" - "fmt" - "math" - - "entgo.io/ent/dialect/sql" - "entgo.io/ent/dialect/sql/sqlgraph" - "entgo.io/ent/schema/field" - - "git.grosinger.net/tgrosinger/saasitone/ent/passwordtoken" - "git.grosinger.net/tgrosinger/saasitone/ent/predicate" - "git.grosinger.net/tgrosinger/saasitone/ent/user" -) - -// PasswordTokenQuery is the builder for querying PasswordToken entities. -type PasswordTokenQuery struct { - config - ctx *QueryContext - order []passwordtoken.OrderOption - inters []Interceptor - predicates []predicate.PasswordToken - withUser *UserQuery - withFKs bool - // intermediate query (i.e. traversal path). - sql *sql.Selector - path func(context.Context) (*sql.Selector, error) -} - -// Where adds a new predicate for the PasswordTokenQuery builder. -func (ptq *PasswordTokenQuery) Where(ps ...predicate.PasswordToken) *PasswordTokenQuery { - ptq.predicates = append(ptq.predicates, ps...) - return ptq -} - -// Limit the number of records to be returned by this query. -func (ptq *PasswordTokenQuery) Limit(limit int) *PasswordTokenQuery { - ptq.ctx.Limit = &limit - return ptq -} - -// Offset to start from. -func (ptq *PasswordTokenQuery) Offset(offset int) *PasswordTokenQuery { - ptq.ctx.Offset = &offset - return ptq -} - -// 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 (ptq *PasswordTokenQuery) Unique(unique bool) *PasswordTokenQuery { - ptq.ctx.Unique = &unique - return ptq -} - -// Order specifies how the records should be ordered. -func (ptq *PasswordTokenQuery) Order(o ...passwordtoken.OrderOption) *PasswordTokenQuery { - ptq.order = append(ptq.order, o...) - return ptq -} - -// QueryUser chains the current query on the "user" edge. -func (ptq *PasswordTokenQuery) QueryUser() *UserQuery { - query := (&UserClient{config: ptq.config}).Query() - query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { - if err := ptq.prepareQuery(ctx); err != nil { - return nil, err - } - selector := ptq.sqlQuery(ctx) - if err := selector.Err(); err != nil { - return nil, err - } - step := sqlgraph.NewStep( - sqlgraph.From(passwordtoken.Table, passwordtoken.FieldID, selector), - sqlgraph.To(user.Table, user.FieldID), - sqlgraph.Edge(sqlgraph.M2O, false, passwordtoken.UserTable, passwordtoken.UserColumn), - ) - fromU = sqlgraph.SetNeighbors(ptq.driver.Dialect(), step) - return fromU, nil - } - return query -} - -// First returns the first PasswordToken entity from the query. -// Returns a *NotFoundError when no PasswordToken was found. -func (ptq *PasswordTokenQuery) First(ctx context.Context) (*PasswordToken, error) { - nodes, err := ptq.Limit(1).All(setContextOp(ctx, ptq.ctx, "First")) - if err != nil { - return nil, err - } - if len(nodes) == 0 { - return nil, &NotFoundError{passwordtoken.Label} - } - return nodes[0], nil -} - -// FirstX is like First, but panics if an error occurs. -func (ptq *PasswordTokenQuery) FirstX(ctx context.Context) *PasswordToken { - node, err := ptq.First(ctx) - if err != nil && !IsNotFound(err) { - panic(err) - } - return node -} - -// FirstID returns the first PasswordToken ID from the query. -// Returns a *NotFoundError when no PasswordToken ID was found. -func (ptq *PasswordTokenQuery) FirstID(ctx context.Context) (id int, err error) { - var ids []int - if ids, err = ptq.Limit(1).IDs(setContextOp(ctx, ptq.ctx, "FirstID")); err != nil { - return - } - if len(ids) == 0 { - err = &NotFoundError{passwordtoken.Label} - return - } - return ids[0], nil -} - -// FirstIDX is like FirstID, but panics if an error occurs. -func (ptq *PasswordTokenQuery) FirstIDX(ctx context.Context) int { - id, err := ptq.FirstID(ctx) - if err != nil && !IsNotFound(err) { - panic(err) - } - return id -} - -// Only returns a single PasswordToken entity found by the query, ensuring it only returns one. -// Returns a *NotSingularError when more than one PasswordToken entity is found. -// Returns a *NotFoundError when no PasswordToken entities are found. -func (ptq *PasswordTokenQuery) Only(ctx context.Context) (*PasswordToken, error) { - nodes, err := ptq.Limit(2).All(setContextOp(ctx, ptq.ctx, "Only")) - if err != nil { - return nil, err - } - switch len(nodes) { - case 1: - return nodes[0], nil - case 0: - return nil, &NotFoundError{passwordtoken.Label} - default: - return nil, &NotSingularError{passwordtoken.Label} - } -} - -// OnlyX is like Only, but panics if an error occurs. -func (ptq *PasswordTokenQuery) OnlyX(ctx context.Context) *PasswordToken { - node, err := ptq.Only(ctx) - if err != nil { - panic(err) - } - return node -} - -// OnlyID is like Only, but returns the only PasswordToken ID in the query. -// Returns a *NotSingularError when more than one PasswordToken ID is found. -// Returns a *NotFoundError when no entities are found. -func (ptq *PasswordTokenQuery) OnlyID(ctx context.Context) (id int, err error) { - var ids []int - if ids, err = ptq.Limit(2).IDs(setContextOp(ctx, ptq.ctx, "OnlyID")); err != nil { - return - } - switch len(ids) { - case 1: - id = ids[0] - case 0: - err = &NotFoundError{passwordtoken.Label} - default: - err = &NotSingularError{passwordtoken.Label} - } - return -} - -// OnlyIDX is like OnlyID, but panics if an error occurs. -func (ptq *PasswordTokenQuery) OnlyIDX(ctx context.Context) int { - id, err := ptq.OnlyID(ctx) - if err != nil { - panic(err) - } - return id -} - -// All executes the query and returns a list of PasswordTokens. -func (ptq *PasswordTokenQuery) All(ctx context.Context) ([]*PasswordToken, error) { - ctx = setContextOp(ctx, ptq.ctx, "All") - if err := ptq.prepareQuery(ctx); err != nil { - return nil, err - } - qr := querierAll[[]*PasswordToken, *PasswordTokenQuery]() - return withInterceptors[[]*PasswordToken](ctx, ptq, qr, ptq.inters) -} - -// AllX is like All, but panics if an error occurs. -func (ptq *PasswordTokenQuery) AllX(ctx context.Context) []*PasswordToken { - nodes, err := ptq.All(ctx) - if err != nil { - panic(err) - } - return nodes -} - -// IDs executes the query and returns a list of PasswordToken IDs. -func (ptq *PasswordTokenQuery) IDs(ctx context.Context) (ids []int, err error) { - if ptq.ctx.Unique == nil && ptq.path != nil { - ptq.Unique(true) - } - ctx = setContextOp(ctx, ptq.ctx, "IDs") - if err = ptq.Select(passwordtoken.FieldID).Scan(ctx, &ids); err != nil { - return nil, err - } - return ids, nil -} - -// IDsX is like IDs, but panics if an error occurs. -func (ptq *PasswordTokenQuery) IDsX(ctx context.Context) []int { - ids, err := ptq.IDs(ctx) - if err != nil { - panic(err) - } - return ids -} - -// Count returns the count of the given query. -func (ptq *PasswordTokenQuery) Count(ctx context.Context) (int, error) { - ctx = setContextOp(ctx, ptq.ctx, "Count") - if err := ptq.prepareQuery(ctx); err != nil { - return 0, err - } - return withInterceptors[int](ctx, ptq, querierCount[*PasswordTokenQuery](), ptq.inters) -} - -// CountX is like Count, but panics if an error occurs. -func (ptq *PasswordTokenQuery) CountX(ctx context.Context) int { - count, err := ptq.Count(ctx) - if err != nil { - panic(err) - } - return count -} - -// Exist returns true if the query has elements in the graph. -func (ptq *PasswordTokenQuery) Exist(ctx context.Context) (bool, error) { - ctx = setContextOp(ctx, ptq.ctx, "Exist") - switch _, err := ptq.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 (ptq *PasswordTokenQuery) ExistX(ctx context.Context) bool { - exist, err := ptq.Exist(ctx) - if err != nil { - panic(err) - } - return exist -} - -// Clone returns a duplicate of the PasswordTokenQuery builder, including all associated steps. It can be -// used to prepare common query builders and use them differently after the clone is made. -func (ptq *PasswordTokenQuery) Clone() *PasswordTokenQuery { - if ptq == nil { - return nil - } - return &PasswordTokenQuery{ - config: ptq.config, - ctx: ptq.ctx.Clone(), - order: append([]passwordtoken.OrderOption{}, ptq.order...), - inters: append([]Interceptor{}, ptq.inters...), - predicates: append([]predicate.PasswordToken{}, ptq.predicates...), - withUser: ptq.withUser.Clone(), - // clone intermediate query. - sql: ptq.sql.Clone(), - path: ptq.path, - } -} - -// WithUser tells the query-builder to eager-load the nodes that are connected to -// the "user" edge. The optional arguments are used to configure the query builder of the edge. -func (ptq *PasswordTokenQuery) WithUser(opts ...func(*UserQuery)) *PasswordTokenQuery { - query := (&UserClient{config: ptq.config}).Query() - for _, opt := range opts { - opt(query) - } - ptq.withUser = query - return ptq -} - -// 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 { -// Hash string `json:"hash,omitempty"` -// Count int `json:"count,omitempty"` -// } -// -// client.PasswordToken.Query(). -// GroupBy(passwordtoken.FieldHash). -// Aggregate(ent.Count()). -// Scan(ctx, &v) -func (ptq *PasswordTokenQuery) GroupBy(field string, fields ...string) *PasswordTokenGroupBy { - ptq.ctx.Fields = append([]string{field}, fields...) - grbuild := &PasswordTokenGroupBy{build: ptq} - grbuild.flds = &ptq.ctx.Fields - grbuild.label = passwordtoken.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 { -// Hash string `json:"hash,omitempty"` -// } -// -// client.PasswordToken.Query(). -// Select(passwordtoken.FieldHash). -// Scan(ctx, &v) -func (ptq *PasswordTokenQuery) Select(fields ...string) *PasswordTokenSelect { - ptq.ctx.Fields = append(ptq.ctx.Fields, fields...) - sbuild := &PasswordTokenSelect{PasswordTokenQuery: ptq} - sbuild.label = passwordtoken.Label - sbuild.flds, sbuild.scan = &ptq.ctx.Fields, sbuild.Scan - return sbuild -} - -// Aggregate returns a PasswordTokenSelect configured with the given aggregations. -func (ptq *PasswordTokenQuery) Aggregate(fns ...AggregateFunc) *PasswordTokenSelect { - return ptq.Select().Aggregate(fns...) -} - -func (ptq *PasswordTokenQuery) prepareQuery(ctx context.Context) error { - for _, inter := range ptq.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, ptq); err != nil { - return err - } - } - } - for _, f := range ptq.ctx.Fields { - if !passwordtoken.ValidColumn(f) { - return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} - } - } - if ptq.path != nil { - prev, err := ptq.path(ctx) - if err != nil { - return err - } - ptq.sql = prev - } - return nil -} - -func (ptq *PasswordTokenQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*PasswordToken, error) { - var ( - nodes = []*PasswordToken{} - withFKs = ptq.withFKs - _spec = ptq.querySpec() - loadedTypes = [1]bool{ - ptq.withUser != nil, - } - ) - if ptq.withUser != nil { - withFKs = true - } - if withFKs { - _spec.Node.Columns = append(_spec.Node.Columns, passwordtoken.ForeignKeys...) - } - _spec.ScanValues = func(columns []string) ([]any, error) { - return (*PasswordToken).scanValues(nil, columns) - } - _spec.Assign = func(columns []string, values []any) error { - node := &PasswordToken{config: ptq.config} - nodes = append(nodes, node) - node.Edges.loadedTypes = loadedTypes - return node.assignValues(columns, values) - } - for i := range hooks { - hooks[i](ctx, _spec) - } - if err := sqlgraph.QueryNodes(ctx, ptq.driver, _spec); err != nil { - return nil, err - } - if len(nodes) == 0 { - return nodes, nil - } - if query := ptq.withUser; query != nil { - if err := ptq.loadUser(ctx, query, nodes, nil, - func(n *PasswordToken, e *User) { n.Edges.User = e }); err != nil { - return nil, err - } - } - return nodes, nil -} - -func (ptq *PasswordTokenQuery) loadUser(ctx context.Context, query *UserQuery, nodes []*PasswordToken, init func(*PasswordToken), assign func(*PasswordToken, *User)) error { - ids := make([]int, 0, len(nodes)) - nodeids := make(map[int][]*PasswordToken) - for i := range nodes { - if nodes[i].password_token_user == nil { - continue - } - fk := *nodes[i].password_token_user - if _, ok := nodeids[fk]; !ok { - ids = append(ids, fk) - } - nodeids[fk] = append(nodeids[fk], nodes[i]) - } - if len(ids) == 0 { - return nil - } - query.Where(user.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 "password_token_user" returned %v`, n.ID) - } - for i := range nodes { - assign(nodes[i], n) - } - } - return nil -} - -func (ptq *PasswordTokenQuery) sqlCount(ctx context.Context) (int, error) { - _spec := ptq.querySpec() - _spec.Node.Columns = ptq.ctx.Fields - if len(ptq.ctx.Fields) > 0 { - _spec.Unique = ptq.ctx.Unique != nil && *ptq.ctx.Unique - } - return sqlgraph.CountNodes(ctx, ptq.driver, _spec) -} - -func (ptq *PasswordTokenQuery) querySpec() *sqlgraph.QuerySpec { - _spec := sqlgraph.NewQuerySpec(passwordtoken.Table, passwordtoken.Columns, sqlgraph.NewFieldSpec(passwordtoken.FieldID, field.TypeInt)) - _spec.From = ptq.sql - if unique := ptq.ctx.Unique; unique != nil { - _spec.Unique = *unique - } else if ptq.path != nil { - _spec.Unique = true - } - if fields := ptq.ctx.Fields; len(fields) > 0 { - _spec.Node.Columns = make([]string, 0, len(fields)) - _spec.Node.Columns = append(_spec.Node.Columns, passwordtoken.FieldID) - for i := range fields { - if fields[i] != passwordtoken.FieldID { - _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) - } - } - } - if ps := ptq.predicates; len(ps) > 0 { - _spec.Predicate = func(selector *sql.Selector) { - for i := range ps { - ps[i](selector) - } - } - } - if limit := ptq.ctx.Limit; limit != nil { - _spec.Limit = *limit - } - if offset := ptq.ctx.Offset; offset != nil { - _spec.Offset = *offset - } - if ps := ptq.order; len(ps) > 0 { - _spec.Order = func(selector *sql.Selector) { - for i := range ps { - ps[i](selector) - } - } - } - return _spec -} - -func (ptq *PasswordTokenQuery) sqlQuery(ctx context.Context) *sql.Selector { - builder := sql.Dialect(ptq.driver.Dialect()) - t1 := builder.Table(passwordtoken.Table) - columns := ptq.ctx.Fields - if len(columns) == 0 { - columns = passwordtoken.Columns - } - selector := builder.Select(t1.Columns(columns...)...).From(t1) - if ptq.sql != nil { - selector = ptq.sql - selector.Select(selector.Columns(columns...)...) - } - if ptq.ctx.Unique != nil && *ptq.ctx.Unique { - selector.Distinct() - } - for _, p := range ptq.predicates { - p(selector) - } - for _, p := range ptq.order { - p(selector) - } - if offset := ptq.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 := ptq.ctx.Limit; limit != nil { - selector.Limit(*limit) - } - return selector -} - -// PasswordTokenGroupBy is the group-by builder for PasswordToken entities. -type PasswordTokenGroupBy struct { - selector - build *PasswordTokenQuery -} - -// Aggregate adds the given aggregation functions to the group-by query. -func (ptgb *PasswordTokenGroupBy) Aggregate(fns ...AggregateFunc) *PasswordTokenGroupBy { - ptgb.fns = append(ptgb.fns, fns...) - return ptgb -} - -// Scan applies the selector query and scans the result into the given value. -func (ptgb *PasswordTokenGroupBy) Scan(ctx context.Context, v any) error { - ctx = setContextOp(ctx, ptgb.build.ctx, "GroupBy") - if err := ptgb.build.prepareQuery(ctx); err != nil { - return err - } - return scanWithInterceptors[*PasswordTokenQuery, *PasswordTokenGroupBy](ctx, ptgb.build, ptgb, ptgb.build.inters, v) -} - -func (ptgb *PasswordTokenGroupBy) sqlScan(ctx context.Context, root *PasswordTokenQuery, v any) error { - selector := root.sqlQuery(ctx).Select() - aggregation := make([]string, 0, len(ptgb.fns)) - for _, fn := range ptgb.fns { - aggregation = append(aggregation, fn(selector)) - } - if len(selector.SelectedColumns()) == 0 { - columns := make([]string, 0, len(*ptgb.flds)+len(ptgb.fns)) - for _, f := range *ptgb.flds { - columns = append(columns, selector.C(f)) - } - columns = append(columns, aggregation...) - selector.Select(columns...) - } - selector.GroupBy(selector.Columns(*ptgb.flds...)...) - if err := selector.Err(); err != nil { - return err - } - rows := &sql.Rows{} - query, args := selector.Query() - if err := ptgb.build.driver.Query(ctx, query, args, rows); err != nil { - return err - } - defer rows.Close() - return sql.ScanSlice(rows, v) -} - -// PasswordTokenSelect is the builder for selecting fields of PasswordToken entities. -type PasswordTokenSelect struct { - *PasswordTokenQuery - selector -} - -// Aggregate adds the given aggregation functions to the selector query. -func (pts *PasswordTokenSelect) Aggregate(fns ...AggregateFunc) *PasswordTokenSelect { - pts.fns = append(pts.fns, fns...) - return pts -} - -// Scan applies the selector query and scans the result into the given value. -func (pts *PasswordTokenSelect) Scan(ctx context.Context, v any) error { - ctx = setContextOp(ctx, pts.ctx, "Select") - if err := pts.prepareQuery(ctx); err != nil { - return err - } - return scanWithInterceptors[*PasswordTokenQuery, *PasswordTokenSelect](ctx, pts.PasswordTokenQuery, pts, pts.inters, v) -} - -func (pts *PasswordTokenSelect) sqlScan(ctx context.Context, root *PasswordTokenQuery, v any) error { - selector := root.sqlQuery(ctx) - aggregation := make([]string, 0, len(pts.fns)) - for _, fn := range pts.fns { - aggregation = append(aggregation, fn(selector)) - } - switch n := len(*pts.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 := pts.driver.Query(ctx, query, args, rows); err != nil { - return err - } - defer rows.Close() - return sql.ScanSlice(rows, v) -} diff --git a/ent/passwordtoken_update.go b/ent/passwordtoken_update.go deleted file mode 100644 index 9133fbb..0000000 --- a/ent/passwordtoken_update.go +++ /dev/null @@ -1,370 +0,0 @@ -// 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/schema/field" - - "git.grosinger.net/tgrosinger/saasitone/ent/passwordtoken" - "git.grosinger.net/tgrosinger/saasitone/ent/predicate" - "git.grosinger.net/tgrosinger/saasitone/ent/user" -) - -// PasswordTokenUpdate is the builder for updating PasswordToken entities. -type PasswordTokenUpdate struct { - config - hooks []Hook - mutation *PasswordTokenMutation -} - -// Where appends a list predicates to the PasswordTokenUpdate builder. -func (ptu *PasswordTokenUpdate) Where(ps ...predicate.PasswordToken) *PasswordTokenUpdate { - ptu.mutation.Where(ps...) - return ptu -} - -// SetHash sets the "hash" field. -func (ptu *PasswordTokenUpdate) SetHash(s string) *PasswordTokenUpdate { - ptu.mutation.SetHash(s) - return ptu -} - -// SetNillableHash sets the "hash" field if the given value is not nil. -func (ptu *PasswordTokenUpdate) SetNillableHash(s *string) *PasswordTokenUpdate { - if s != nil { - ptu.SetHash(*s) - } - return ptu -} - -// SetCreatedAt sets the "created_at" field. -func (ptu *PasswordTokenUpdate) SetCreatedAt(t time.Time) *PasswordTokenUpdate { - ptu.mutation.SetCreatedAt(t) - return ptu -} - -// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. -func (ptu *PasswordTokenUpdate) SetNillableCreatedAt(t *time.Time) *PasswordTokenUpdate { - if t != nil { - ptu.SetCreatedAt(*t) - } - return ptu -} - -// SetUserID sets the "user" edge to the User entity by ID. -func (ptu *PasswordTokenUpdate) SetUserID(id int) *PasswordTokenUpdate { - ptu.mutation.SetUserID(id) - return ptu -} - -// SetUser sets the "user" edge to the User entity. -func (ptu *PasswordTokenUpdate) SetUser(u *User) *PasswordTokenUpdate { - return ptu.SetUserID(u.ID) -} - -// Mutation returns the PasswordTokenMutation object of the builder. -func (ptu *PasswordTokenUpdate) Mutation() *PasswordTokenMutation { - return ptu.mutation -} - -// ClearUser clears the "user" edge to the User entity. -func (ptu *PasswordTokenUpdate) ClearUser() *PasswordTokenUpdate { - ptu.mutation.ClearUser() - return ptu -} - -// Save executes the query and returns the number of nodes affected by the update operation. -func (ptu *PasswordTokenUpdate) Save(ctx context.Context) (int, error) { - return withHooks(ctx, ptu.sqlSave, ptu.mutation, ptu.hooks) -} - -// SaveX is like Save, but panics if an error occurs. -func (ptu *PasswordTokenUpdate) SaveX(ctx context.Context) int { - affected, err := ptu.Save(ctx) - if err != nil { - panic(err) - } - return affected -} - -// Exec executes the query. -func (ptu *PasswordTokenUpdate) Exec(ctx context.Context) error { - _, err := ptu.Save(ctx) - return err -} - -// ExecX is like Exec, but panics if an error occurs. -func (ptu *PasswordTokenUpdate) ExecX(ctx context.Context) { - if err := ptu.Exec(ctx); err != nil { - panic(err) - } -} - -// check runs all checks and user-defined validators on the builder. -func (ptu *PasswordTokenUpdate) check() error { - if v, ok := ptu.mutation.Hash(); ok { - if err := passwordtoken.HashValidator(v); err != nil { - return &ValidationError{Name: "hash", err: fmt.Errorf(`ent: validator failed for field "PasswordToken.hash": %w`, err)} - } - } - if _, ok := ptu.mutation.UserID(); ptu.mutation.UserCleared() && !ok { - return errors.New(`ent: clearing a required unique edge "PasswordToken.user"`) - } - return nil -} - -func (ptu *PasswordTokenUpdate) sqlSave(ctx context.Context) (n int, err error) { - if err := ptu.check(); err != nil { - return n, err - } - _spec := sqlgraph.NewUpdateSpec(passwordtoken.Table, passwordtoken.Columns, sqlgraph.NewFieldSpec(passwordtoken.FieldID, field.TypeInt)) - if ps := ptu.mutation.predicates; len(ps) > 0 { - _spec.Predicate = func(selector *sql.Selector) { - for i := range ps { - ps[i](selector) - } - } - } - if value, ok := ptu.mutation.Hash(); ok { - _spec.SetField(passwordtoken.FieldHash, field.TypeString, value) - } - if value, ok := ptu.mutation.CreatedAt(); ok { - _spec.SetField(passwordtoken.FieldCreatedAt, field.TypeTime, value) - } - if ptu.mutation.UserCleared() { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2O, - Inverse: false, - Table: passwordtoken.UserTable, - Columns: []string{passwordtoken.UserColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt), - }, - } - _spec.Edges.Clear = append(_spec.Edges.Clear, edge) - } - if nodes := ptu.mutation.UserIDs(); len(nodes) > 0 { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2O, - Inverse: false, - Table: passwordtoken.UserTable, - Columns: []string{passwordtoken.UserColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt), - }, - } - for _, k := range nodes { - edge.Target.Nodes = append(edge.Target.Nodes, k) - } - _spec.Edges.Add = append(_spec.Edges.Add, edge) - } - if n, err = sqlgraph.UpdateNodes(ctx, ptu.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { - err = &NotFoundError{passwordtoken.Label} - } else if sqlgraph.IsConstraintError(err) { - err = &ConstraintError{msg: err.Error(), wrap: err} - } - return 0, err - } - ptu.mutation.done = true - return n, nil -} - -// PasswordTokenUpdateOne is the builder for updating a single PasswordToken entity. -type PasswordTokenUpdateOne struct { - config - fields []string - hooks []Hook - mutation *PasswordTokenMutation -} - -// SetHash sets the "hash" field. -func (ptuo *PasswordTokenUpdateOne) SetHash(s string) *PasswordTokenUpdateOne { - ptuo.mutation.SetHash(s) - return ptuo -} - -// SetNillableHash sets the "hash" field if the given value is not nil. -func (ptuo *PasswordTokenUpdateOne) SetNillableHash(s *string) *PasswordTokenUpdateOne { - if s != nil { - ptuo.SetHash(*s) - } - return ptuo -} - -// SetCreatedAt sets the "created_at" field. -func (ptuo *PasswordTokenUpdateOne) SetCreatedAt(t time.Time) *PasswordTokenUpdateOne { - ptuo.mutation.SetCreatedAt(t) - return ptuo -} - -// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. -func (ptuo *PasswordTokenUpdateOne) SetNillableCreatedAt(t *time.Time) *PasswordTokenUpdateOne { - if t != nil { - ptuo.SetCreatedAt(*t) - } - return ptuo -} - -// SetUserID sets the "user" edge to the User entity by ID. -func (ptuo *PasswordTokenUpdateOne) SetUserID(id int) *PasswordTokenUpdateOne { - ptuo.mutation.SetUserID(id) - return ptuo -} - -// SetUser sets the "user" edge to the User entity. -func (ptuo *PasswordTokenUpdateOne) SetUser(u *User) *PasswordTokenUpdateOne { - return ptuo.SetUserID(u.ID) -} - -// Mutation returns the PasswordTokenMutation object of the builder. -func (ptuo *PasswordTokenUpdateOne) Mutation() *PasswordTokenMutation { - return ptuo.mutation -} - -// ClearUser clears the "user" edge to the User entity. -func (ptuo *PasswordTokenUpdateOne) ClearUser() *PasswordTokenUpdateOne { - ptuo.mutation.ClearUser() - return ptuo -} - -// Where appends a list predicates to the PasswordTokenUpdate builder. -func (ptuo *PasswordTokenUpdateOne) Where(ps ...predicate.PasswordToken) *PasswordTokenUpdateOne { - ptuo.mutation.Where(ps...) - return ptuo -} - -// Select allows selecting one or more fields (columns) of the returned entity. -// The default is selecting all fields defined in the entity schema. -func (ptuo *PasswordTokenUpdateOne) Select(field string, fields ...string) *PasswordTokenUpdateOne { - ptuo.fields = append([]string{field}, fields...) - return ptuo -} - -// Save executes the query and returns the updated PasswordToken entity. -func (ptuo *PasswordTokenUpdateOne) Save(ctx context.Context) (*PasswordToken, error) { - return withHooks(ctx, ptuo.sqlSave, ptuo.mutation, ptuo.hooks) -} - -// SaveX is like Save, but panics if an error occurs. -func (ptuo *PasswordTokenUpdateOne) SaveX(ctx context.Context) *PasswordToken { - node, err := ptuo.Save(ctx) - if err != nil { - panic(err) - } - return node -} - -// Exec executes the query on the entity. -func (ptuo *PasswordTokenUpdateOne) Exec(ctx context.Context) error { - _, err := ptuo.Save(ctx) - return err -} - -// ExecX is like Exec, but panics if an error occurs. -func (ptuo *PasswordTokenUpdateOne) ExecX(ctx context.Context) { - if err := ptuo.Exec(ctx); err != nil { - panic(err) - } -} - -// check runs all checks and user-defined validators on the builder. -func (ptuo *PasswordTokenUpdateOne) check() error { - if v, ok := ptuo.mutation.Hash(); ok { - if err := passwordtoken.HashValidator(v); err != nil { - return &ValidationError{Name: "hash", err: fmt.Errorf(`ent: validator failed for field "PasswordToken.hash": %w`, err)} - } - } - if _, ok := ptuo.mutation.UserID(); ptuo.mutation.UserCleared() && !ok { - return errors.New(`ent: clearing a required unique edge "PasswordToken.user"`) - } - return nil -} - -func (ptuo *PasswordTokenUpdateOne) sqlSave(ctx context.Context) (_node *PasswordToken, err error) { - if err := ptuo.check(); err != nil { - return _node, err - } - _spec := sqlgraph.NewUpdateSpec(passwordtoken.Table, passwordtoken.Columns, sqlgraph.NewFieldSpec(passwordtoken.FieldID, field.TypeInt)) - id, ok := ptuo.mutation.ID() - if !ok { - return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "PasswordToken.id" for update`)} - } - _spec.Node.ID.Value = id - if fields := ptuo.fields; len(fields) > 0 { - _spec.Node.Columns = make([]string, 0, len(fields)) - _spec.Node.Columns = append(_spec.Node.Columns, passwordtoken.FieldID) - for _, f := range fields { - if !passwordtoken.ValidColumn(f) { - return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} - } - if f != passwordtoken.FieldID { - _spec.Node.Columns = append(_spec.Node.Columns, f) - } - } - } - if ps := ptuo.mutation.predicates; len(ps) > 0 { - _spec.Predicate = func(selector *sql.Selector) { - for i := range ps { - ps[i](selector) - } - } - } - if value, ok := ptuo.mutation.Hash(); ok { - _spec.SetField(passwordtoken.FieldHash, field.TypeString, value) - } - if value, ok := ptuo.mutation.CreatedAt(); ok { - _spec.SetField(passwordtoken.FieldCreatedAt, field.TypeTime, value) - } - if ptuo.mutation.UserCleared() { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2O, - Inverse: false, - Table: passwordtoken.UserTable, - Columns: []string{passwordtoken.UserColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt), - }, - } - _spec.Edges.Clear = append(_spec.Edges.Clear, edge) - } - if nodes := ptuo.mutation.UserIDs(); len(nodes) > 0 { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.M2O, - Inverse: false, - Table: passwordtoken.UserTable, - Columns: []string{passwordtoken.UserColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt), - }, - } - for _, k := range nodes { - edge.Target.Nodes = append(edge.Target.Nodes, k) - } - _spec.Edges.Add = append(_spec.Edges.Add, edge) - } - _node = &PasswordToken{config: ptuo.config} - _spec.Assign = _node.assignValues - _spec.ScanValues = _node.scanValues - if err = sqlgraph.UpdateNode(ctx, ptuo.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { - err = &NotFoundError{passwordtoken.Label} - } else if sqlgraph.IsConstraintError(err) { - err = &ConstraintError{msg: err.Error(), wrap: err} - } - return nil, err - } - ptuo.mutation.done = true - return _node, nil -} diff --git a/ent/predicate/predicate.go b/ent/predicate/predicate.go deleted file mode 100644 index ecc90c4..0000000 --- a/ent/predicate/predicate.go +++ /dev/null @@ -1,13 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package predicate - -import ( - "entgo.io/ent/dialect/sql" -) - -// PasswordToken is the predicate function for passwordtoken builders. -type PasswordToken func(*sql.Selector) - -// User is the predicate function for user builders. -type User func(*sql.Selector) diff --git a/ent/runtime.go b/ent/runtime.go deleted file mode 100644 index d856d39..0000000 --- a/ent/runtime.go +++ /dev/null @@ -1,5 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package ent - -// The schema-stitching logic is generated in git.grosinger.net/tgrosinger/saasitone/ent/runtime/runtime.go diff --git a/ent/runtime/runtime.go b/ent/runtime/runtime.go deleted file mode 100644 index dd823d0..0000000 --- a/ent/runtime/runtime.go +++ /dev/null @@ -1,56 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package runtime - -import ( - "time" - - "git.grosinger.net/tgrosinger/saasitone/ent/passwordtoken" - "git.grosinger.net/tgrosinger/saasitone/ent/schema" - "git.grosinger.net/tgrosinger/saasitone/ent/user" -) - -// 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() { - passwordtokenFields := schema.PasswordToken{}.Fields() - _ = passwordtokenFields - // passwordtokenDescHash is the schema descriptor for hash field. - passwordtokenDescHash := passwordtokenFields[0].Descriptor() - // passwordtoken.HashValidator is a validator for the "hash" field. It is called by the builders before save. - passwordtoken.HashValidator = passwordtokenDescHash.Validators[0].(func(string) error) - // passwordtokenDescCreatedAt is the schema descriptor for created_at field. - passwordtokenDescCreatedAt := passwordtokenFields[1].Descriptor() - // passwordtoken.DefaultCreatedAt holds the default value on creation for the created_at field. - passwordtoken.DefaultCreatedAt = passwordtokenDescCreatedAt.Default.(func() time.Time) - userHooks := schema.User{}.Hooks() - user.Hooks[0] = userHooks[0] - userFields := schema.User{}.Fields() - _ = userFields - // userDescName is the schema descriptor for name field. - userDescName := userFields[0].Descriptor() - // user.NameValidator is a validator for the "name" field. It is called by the builders before save. - user.NameValidator = userDescName.Validators[0].(func(string) error) - // userDescEmail is the schema descriptor for email field. - userDescEmail := userFields[1].Descriptor() - // user.EmailValidator is a validator for the "email" field. It is called by the builders before save. - user.EmailValidator = userDescEmail.Validators[0].(func(string) error) - // userDescPassword is the schema descriptor for password field. - userDescPassword := userFields[2].Descriptor() - // user.PasswordValidator is a validator for the "password" field. It is called by the builders before save. - user.PasswordValidator = userDescPassword.Validators[0].(func(string) error) - // userDescVerified is the schema descriptor for verified field. - userDescVerified := userFields[3].Descriptor() - // user.DefaultVerified holds the default value on creation for the verified field. - user.DefaultVerified = userDescVerified.Default.(bool) - // userDescCreatedAt is the schema descriptor for created_at field. - userDescCreatedAt := userFields[4].Descriptor() - // user.DefaultCreatedAt holds the default value on creation for the created_at field. - user.DefaultCreatedAt = userDescCreatedAt.Default.(func() time.Time) -} - -const ( - Version = "v0.12.5" // Version of ent codegen. - Sum = "h1:KREM5E4CSoej4zeGa88Ou/gfturAnpUv0mzAjch1sj4=" // Sum of ent codegen. -) diff --git a/ent/schema/passwordtoken.go b/ent/schema/passwordtoken.go deleted file mode 100644 index e518d16..0000000 --- a/ent/schema/passwordtoken.go +++ /dev/null @@ -1,34 +0,0 @@ -package schema - -import ( - "time" - - "entgo.io/ent" - "entgo.io/ent/schema/edge" - "entgo.io/ent/schema/field" -) - -// PasswordToken holds the schema definition for the PasswordToken entity. -type PasswordToken struct { - ent.Schema -} - -// Fields of the PasswordToken. -func (PasswordToken) Fields() []ent.Field { - return []ent.Field{ - field.String("hash"). - Sensitive(). - NotEmpty(), - field.Time("created_at"). - Default(time.Now), - } -} - -// Edges of the PasswordToken. -func (PasswordToken) Edges() []ent.Edge { - return []ent.Edge{ - edge.To("user", User.Type). - Required(). - Unique(), - } -} diff --git a/ent/schema/user.go b/ent/schema/user.go deleted file mode 100644 index 1c89c7e..0000000 --- a/ent/schema/user.go +++ /dev/null @@ -1,64 +0,0 @@ -package schema - -import ( - "context" - "strings" - "time" - - "entgo.io/ent" - "entgo.io/ent/schema/edge" - "entgo.io/ent/schema/field" - - ge "git.grosinger.net/tgrosinger/saasitone/ent" - "git.grosinger.net/tgrosinger/saasitone/ent/hook" -) - -// User holds the schema definition for the User entity. -type User struct { - ent.Schema -} - -// Fields of the User. -func (User) Fields() []ent.Field { - return []ent.Field{ - field.String("name"). - NotEmpty(), - field.String("email"). - NotEmpty(). - Unique(), - field.String("password"). - Sensitive(). - NotEmpty(), - field.Bool("verified"). - Default(false), - field.Time("created_at"). - Default(time.Now). - Immutable(), - } -} - -// Edges of the User. -func (User) Edges() []ent.Edge { - return []ent.Edge{ - edge.From("owner", PasswordToken.Type). - Ref("user"), - } -} - -// Hooks of the User. -func (User) Hooks() []ent.Hook { - return []ent.Hook{ - hook.On( - func(next ent.Mutator) ent.Mutator { - return hook.UserFunc(func(ctx context.Context, m *ge.UserMutation) (ent.Value, error) { - if v, exists := m.Email(); exists { - m.SetEmail(strings.ToLower(v)) - } - return next.Mutate(ctx, m) - }) - }, - // Limit the hook only for these operations. - ent.OpCreate|ent.OpUpdate|ent.OpUpdateOne, - ), - } -} diff --git a/ent/tx.go b/ent/tx.go deleted file mode 100644 index 6d1cb6c..0000000 --- a/ent/tx.go +++ /dev/null @@ -1,213 +0,0 @@ -// 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 - // PasswordToken is the client for interacting with the PasswordToken builders. - PasswordToken *PasswordTokenClient - // User is the client for interacting with the User builders. - User *UserClient - - // 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.PasswordToken = NewPasswordTokenClient(tx.config) - tx.User = NewUserClient(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: PasswordToken.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/ent/user.go b/ent/user.go deleted file mode 100644 index 09991a1..0000000 --- a/ent/user.go +++ /dev/null @@ -1,178 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package ent - -import ( - "fmt" - "strings" - "time" - - "entgo.io/ent" - "entgo.io/ent/dialect/sql" - - "git.grosinger.net/tgrosinger/saasitone/ent/user" -) - -// User is the model entity for the User schema. -type User struct { - config `json:"-"` - // ID of the ent. - ID int `json:"id,omitempty"` - // Name holds the value of the "name" field. - Name string `json:"name,omitempty"` - // Email holds the value of the "email" field. - Email string `json:"email,omitempty"` - // Password holds the value of the "password" field. - Password string `json:"-"` - // Verified holds the value of the "verified" field. - Verified bool `json:"verified,omitempty"` - // CreatedAt holds the value of the "created_at" field. - CreatedAt time.Time `json:"created_at,omitempty"` - // Edges holds the relations/edges for other nodes in the graph. - // The values are being populated by the UserQuery when eager-loading is set. - Edges UserEdges `json:"edges"` - selectValues sql.SelectValues -} - -// UserEdges holds the relations/edges for other nodes in the graph. -type UserEdges struct { - // Owner holds the value of the owner edge. - Owner []*PasswordToken `json:"owner,omitempty"` - // loadedTypes holds the information for reporting if a - // type was loaded (or requested) in eager-loading or not. - loadedTypes [1]bool -} - -// OwnerOrErr returns the Owner value or an error if the edge -// was not loaded in eager-loading. -func (e UserEdges) OwnerOrErr() ([]*PasswordToken, error) { - if e.loadedTypes[0] { - return e.Owner, nil - } - return nil, &NotLoadedError{edge: "owner"} -} - -// scanValues returns the types for scanning values from sql.Rows. -func (*User) scanValues(columns []string) ([]any, error) { - values := make([]any, len(columns)) - for i := range columns { - switch columns[i] { - case user.FieldVerified: - values[i] = new(sql.NullBool) - case user.FieldID: - values[i] = new(sql.NullInt64) - case user.FieldName, user.FieldEmail, user.FieldPassword: - values[i] = new(sql.NullString) - case user.FieldCreatedAt: - 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 User fields. -func (u *User) 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 user.FieldID: - value, ok := values[i].(*sql.NullInt64) - if !ok { - return fmt.Errorf("unexpected type %T for field id", value) - } - u.ID = int(value.Int64) - case user.FieldName: - if value, ok := values[i].(*sql.NullString); !ok { - return fmt.Errorf("unexpected type %T for field name", values[i]) - } else if value.Valid { - u.Name = value.String - } - case user.FieldEmail: - if value, ok := values[i].(*sql.NullString); !ok { - return fmt.Errorf("unexpected type %T for field email", values[i]) - } else if value.Valid { - u.Email = value.String - } - case user.FieldPassword: - if value, ok := values[i].(*sql.NullString); !ok { - return fmt.Errorf("unexpected type %T for field password", values[i]) - } else if value.Valid { - u.Password = value.String - } - case user.FieldVerified: - if value, ok := values[i].(*sql.NullBool); !ok { - return fmt.Errorf("unexpected type %T for field verified", values[i]) - } else if value.Valid { - u.Verified = value.Bool - } - case user.FieldCreatedAt: - if value, ok := values[i].(*sql.NullTime); !ok { - return fmt.Errorf("unexpected type %T for field created_at", values[i]) - } else if value.Valid { - u.CreatedAt = value.Time - } - default: - u.selectValues.Set(columns[i], values[i]) - } - } - return nil -} - -// Value returns the ent.Value that was dynamically selected and assigned to the User. -// This includes values selected through modifiers, order, etc. -func (u *User) Value(name string) (ent.Value, error) { - return u.selectValues.Get(name) -} - -// QueryOwner queries the "owner" edge of the User entity. -func (u *User) QueryOwner() *PasswordTokenQuery { - return NewUserClient(u.config).QueryOwner(u) -} - -// Update returns a builder for updating this User. -// Note that you need to call User.Unwrap() before calling this method if this User -// was returned from a transaction, and the transaction was committed or rolled back. -func (u *User) Update() *UserUpdateOne { - return NewUserClient(u.config).UpdateOne(u) -} - -// Unwrap unwraps the User 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 (u *User) Unwrap() *User { - _tx, ok := u.config.driver.(*txDriver) - if !ok { - panic("ent: User is not a transactional entity") - } - u.config.driver = _tx.drv - return u -} - -// String implements the fmt.Stringer. -func (u *User) String() string { - var builder strings.Builder - builder.WriteString("User(") - builder.WriteString(fmt.Sprintf("id=%v, ", u.ID)) - builder.WriteString("name=") - builder.WriteString(u.Name) - builder.WriteString(", ") - builder.WriteString("email=") - builder.WriteString(u.Email) - builder.WriteString(", ") - builder.WriteString("password=") - builder.WriteString(", ") - builder.WriteString("verified=") - builder.WriteString(fmt.Sprintf("%v", u.Verified)) - builder.WriteString(", ") - builder.WriteString("created_at=") - builder.WriteString(u.CreatedAt.Format(time.ANSIC)) - builder.WriteByte(')') - return builder.String() -} - -// Users is a parsable slice of User. -type Users []*User diff --git a/ent/user/user.go b/ent/user/user.go deleted file mode 100644 index b3f3559..0000000 --- a/ent/user/user.go +++ /dev/null @@ -1,133 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package user - -import ( - "time" - - "entgo.io/ent" - "entgo.io/ent/dialect/sql" - "entgo.io/ent/dialect/sql/sqlgraph" -) - -const ( - // Label holds the string label denoting the user type in the database. - Label = "user" - // FieldID holds the string denoting the id field in the database. - FieldID = "id" - // FieldName holds the string denoting the name field in the database. - FieldName = "name" - // FieldEmail holds the string denoting the email field in the database. - FieldEmail = "email" - // FieldPassword holds the string denoting the password field in the database. - FieldPassword = "password" - // FieldVerified holds the string denoting the verified field in the database. - FieldVerified = "verified" - // FieldCreatedAt holds the string denoting the created_at field in the database. - FieldCreatedAt = "created_at" - // EdgeOwner holds the string denoting the owner edge name in mutations. - EdgeOwner = "owner" - // Table holds the table name of the user in the database. - Table = "users" - // OwnerTable is the table that holds the owner relation/edge. - OwnerTable = "password_tokens" - // OwnerInverseTable is the table name for the PasswordToken entity. - // It exists in this package in order to avoid circular dependency with the "passwordtoken" package. - OwnerInverseTable = "password_tokens" - // OwnerColumn is the table column denoting the owner relation/edge. - OwnerColumn = "password_token_user" -) - -// Columns holds all SQL columns for user fields. -var Columns = []string{ - FieldID, - FieldName, - FieldEmail, - FieldPassword, - FieldVerified, - FieldCreatedAt, -} - -// 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 -} - -// Note that the variables below are initialized by the runtime -// package on the initialization of the application. Therefore, -// it should be imported in the main as follows: -// -// import _ "git.grosinger.net/tgrosinger/saasitone/ent/runtime" -var ( - Hooks [1]ent.Hook - // NameValidator is a validator for the "name" field. It is called by the builders before save. - NameValidator func(string) error - // EmailValidator is a validator for the "email" field. It is called by the builders before save. - EmailValidator func(string) error - // PasswordValidator is a validator for the "password" field. It is called by the builders before save. - PasswordValidator func(string) error - // DefaultVerified holds the default value on creation for the "verified" field. - DefaultVerified bool - // DefaultCreatedAt holds the default value on creation for the "created_at" field. - DefaultCreatedAt func() time.Time -) - -// OrderOption defines the ordering options for the User 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() -} - -// ByName orders the results by the name field. -func ByName(opts ...sql.OrderTermOption) OrderOption { - return sql.OrderByField(FieldName, opts...).ToFunc() -} - -// ByEmail orders the results by the email field. -func ByEmail(opts ...sql.OrderTermOption) OrderOption { - return sql.OrderByField(FieldEmail, opts...).ToFunc() -} - -// ByPassword orders the results by the password field. -func ByPassword(opts ...sql.OrderTermOption) OrderOption { - return sql.OrderByField(FieldPassword, opts...).ToFunc() -} - -// ByVerified orders the results by the verified field. -func ByVerified(opts ...sql.OrderTermOption) OrderOption { - return sql.OrderByField(FieldVerified, opts...).ToFunc() -} - -// ByCreatedAt orders the results by the created_at field. -func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption { - return sql.OrderByField(FieldCreatedAt, opts...).ToFunc() -} - -// ByOwnerCount orders the results by owner count. -func ByOwnerCount(opts ...sql.OrderTermOption) OrderOption { - return func(s *sql.Selector) { - sqlgraph.OrderByNeighborsCount(s, newOwnerStep(), opts...) - } -} - -// ByOwner orders the results by owner terms. -func ByOwner(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption { - return func(s *sql.Selector) { - sqlgraph.OrderByNeighborTerms(s, newOwnerStep(), append([]sql.OrderTerm{term}, terms...)...) - } -} - -func newOwnerStep() *sqlgraph.Step { - return sqlgraph.NewStep( - sqlgraph.From(Table, FieldID), - sqlgraph.To(OwnerInverseTable, FieldID), - sqlgraph.Edge(sqlgraph.O2M, true, OwnerTable, OwnerColumn), - ) -} diff --git a/ent/user/where.go b/ent/user/where.go deleted file mode 100644 index d13d6cf..0000000 --- a/ent/user/where.go +++ /dev/null @@ -1,365 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package user - -import ( - "time" - - "entgo.io/ent/dialect/sql" - "entgo.io/ent/dialect/sql/sqlgraph" - - "git.grosinger.net/tgrosinger/saasitone/ent/predicate" -) - -// ID filters vertices based on their ID field. -func ID(id int) predicate.User { - return predicate.User(sql.FieldEQ(FieldID, id)) -} - -// IDEQ applies the EQ predicate on the ID field. -func IDEQ(id int) predicate.User { - return predicate.User(sql.FieldEQ(FieldID, id)) -} - -// IDNEQ applies the NEQ predicate on the ID field. -func IDNEQ(id int) predicate.User { - return predicate.User(sql.FieldNEQ(FieldID, id)) -} - -// IDIn applies the In predicate on the ID field. -func IDIn(ids ...int) predicate.User { - return predicate.User(sql.FieldIn(FieldID, ids...)) -} - -// IDNotIn applies the NotIn predicate on the ID field. -func IDNotIn(ids ...int) predicate.User { - return predicate.User(sql.FieldNotIn(FieldID, ids...)) -} - -// IDGT applies the GT predicate on the ID field. -func IDGT(id int) predicate.User { - return predicate.User(sql.FieldGT(FieldID, id)) -} - -// IDGTE applies the GTE predicate on the ID field. -func IDGTE(id int) predicate.User { - return predicate.User(sql.FieldGTE(FieldID, id)) -} - -// IDLT applies the LT predicate on the ID field. -func IDLT(id int) predicate.User { - return predicate.User(sql.FieldLT(FieldID, id)) -} - -// IDLTE applies the LTE predicate on the ID field. -func IDLTE(id int) predicate.User { - return predicate.User(sql.FieldLTE(FieldID, id)) -} - -// Name applies equality check predicate on the "name" field. It's identical to NameEQ. -func Name(v string) predicate.User { - return predicate.User(sql.FieldEQ(FieldName, v)) -} - -// Email applies equality check predicate on the "email" field. It's identical to EmailEQ. -func Email(v string) predicate.User { - return predicate.User(sql.FieldEQ(FieldEmail, v)) -} - -// Password applies equality check predicate on the "password" field. It's identical to PasswordEQ. -func Password(v string) predicate.User { - return predicate.User(sql.FieldEQ(FieldPassword, v)) -} - -// Verified applies equality check predicate on the "verified" field. It's identical to VerifiedEQ. -func Verified(v bool) predicate.User { - return predicate.User(sql.FieldEQ(FieldVerified, v)) -} - -// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ. -func CreatedAt(v time.Time) predicate.User { - return predicate.User(sql.FieldEQ(FieldCreatedAt, v)) -} - -// NameEQ applies the EQ predicate on the "name" field. -func NameEQ(v string) predicate.User { - return predicate.User(sql.FieldEQ(FieldName, v)) -} - -// NameNEQ applies the NEQ predicate on the "name" field. -func NameNEQ(v string) predicate.User { - return predicate.User(sql.FieldNEQ(FieldName, v)) -} - -// NameIn applies the In predicate on the "name" field. -func NameIn(vs ...string) predicate.User { - return predicate.User(sql.FieldIn(FieldName, vs...)) -} - -// NameNotIn applies the NotIn predicate on the "name" field. -func NameNotIn(vs ...string) predicate.User { - return predicate.User(sql.FieldNotIn(FieldName, vs...)) -} - -// NameGT applies the GT predicate on the "name" field. -func NameGT(v string) predicate.User { - return predicate.User(sql.FieldGT(FieldName, v)) -} - -// NameGTE applies the GTE predicate on the "name" field. -func NameGTE(v string) predicate.User { - return predicate.User(sql.FieldGTE(FieldName, v)) -} - -// NameLT applies the LT predicate on the "name" field. -func NameLT(v string) predicate.User { - return predicate.User(sql.FieldLT(FieldName, v)) -} - -// NameLTE applies the LTE predicate on the "name" field. -func NameLTE(v string) predicate.User { - return predicate.User(sql.FieldLTE(FieldName, v)) -} - -// NameContains applies the Contains predicate on the "name" field. -func NameContains(v string) predicate.User { - return predicate.User(sql.FieldContains(FieldName, v)) -} - -// NameHasPrefix applies the HasPrefix predicate on the "name" field. -func NameHasPrefix(v string) predicate.User { - return predicate.User(sql.FieldHasPrefix(FieldName, v)) -} - -// NameHasSuffix applies the HasSuffix predicate on the "name" field. -func NameHasSuffix(v string) predicate.User { - return predicate.User(sql.FieldHasSuffix(FieldName, v)) -} - -// NameEqualFold applies the EqualFold predicate on the "name" field. -func NameEqualFold(v string) predicate.User { - return predicate.User(sql.FieldEqualFold(FieldName, v)) -} - -// NameContainsFold applies the ContainsFold predicate on the "name" field. -func NameContainsFold(v string) predicate.User { - return predicate.User(sql.FieldContainsFold(FieldName, v)) -} - -// EmailEQ applies the EQ predicate on the "email" field. -func EmailEQ(v string) predicate.User { - return predicate.User(sql.FieldEQ(FieldEmail, v)) -} - -// EmailNEQ applies the NEQ predicate on the "email" field. -func EmailNEQ(v string) predicate.User { - return predicate.User(sql.FieldNEQ(FieldEmail, v)) -} - -// EmailIn applies the In predicate on the "email" field. -func EmailIn(vs ...string) predicate.User { - return predicate.User(sql.FieldIn(FieldEmail, vs...)) -} - -// EmailNotIn applies the NotIn predicate on the "email" field. -func EmailNotIn(vs ...string) predicate.User { - return predicate.User(sql.FieldNotIn(FieldEmail, vs...)) -} - -// EmailGT applies the GT predicate on the "email" field. -func EmailGT(v string) predicate.User { - return predicate.User(sql.FieldGT(FieldEmail, v)) -} - -// EmailGTE applies the GTE predicate on the "email" field. -func EmailGTE(v string) predicate.User { - return predicate.User(sql.FieldGTE(FieldEmail, v)) -} - -// EmailLT applies the LT predicate on the "email" field. -func EmailLT(v string) predicate.User { - return predicate.User(sql.FieldLT(FieldEmail, v)) -} - -// EmailLTE applies the LTE predicate on the "email" field. -func EmailLTE(v string) predicate.User { - return predicate.User(sql.FieldLTE(FieldEmail, v)) -} - -// EmailContains applies the Contains predicate on the "email" field. -func EmailContains(v string) predicate.User { - return predicate.User(sql.FieldContains(FieldEmail, v)) -} - -// EmailHasPrefix applies the HasPrefix predicate on the "email" field. -func EmailHasPrefix(v string) predicate.User { - return predicate.User(sql.FieldHasPrefix(FieldEmail, v)) -} - -// EmailHasSuffix applies the HasSuffix predicate on the "email" field. -func EmailHasSuffix(v string) predicate.User { - return predicate.User(sql.FieldHasSuffix(FieldEmail, v)) -} - -// EmailEqualFold applies the EqualFold predicate on the "email" field. -func EmailEqualFold(v string) predicate.User { - return predicate.User(sql.FieldEqualFold(FieldEmail, v)) -} - -// EmailContainsFold applies the ContainsFold predicate on the "email" field. -func EmailContainsFold(v string) predicate.User { - return predicate.User(sql.FieldContainsFold(FieldEmail, v)) -} - -// PasswordEQ applies the EQ predicate on the "password" field. -func PasswordEQ(v string) predicate.User { - return predicate.User(sql.FieldEQ(FieldPassword, v)) -} - -// PasswordNEQ applies the NEQ predicate on the "password" field. -func PasswordNEQ(v string) predicate.User { - return predicate.User(sql.FieldNEQ(FieldPassword, v)) -} - -// PasswordIn applies the In predicate on the "password" field. -func PasswordIn(vs ...string) predicate.User { - return predicate.User(sql.FieldIn(FieldPassword, vs...)) -} - -// PasswordNotIn applies the NotIn predicate on the "password" field. -func PasswordNotIn(vs ...string) predicate.User { - return predicate.User(sql.FieldNotIn(FieldPassword, vs...)) -} - -// PasswordGT applies the GT predicate on the "password" field. -func PasswordGT(v string) predicate.User { - return predicate.User(sql.FieldGT(FieldPassword, v)) -} - -// PasswordGTE applies the GTE predicate on the "password" field. -func PasswordGTE(v string) predicate.User { - return predicate.User(sql.FieldGTE(FieldPassword, v)) -} - -// PasswordLT applies the LT predicate on the "password" field. -func PasswordLT(v string) predicate.User { - return predicate.User(sql.FieldLT(FieldPassword, v)) -} - -// PasswordLTE applies the LTE predicate on the "password" field. -func PasswordLTE(v string) predicate.User { - return predicate.User(sql.FieldLTE(FieldPassword, v)) -} - -// PasswordContains applies the Contains predicate on the "password" field. -func PasswordContains(v string) predicate.User { - return predicate.User(sql.FieldContains(FieldPassword, v)) -} - -// PasswordHasPrefix applies the HasPrefix predicate on the "password" field. -func PasswordHasPrefix(v string) predicate.User { - return predicate.User(sql.FieldHasPrefix(FieldPassword, v)) -} - -// PasswordHasSuffix applies the HasSuffix predicate on the "password" field. -func PasswordHasSuffix(v string) predicate.User { - return predicate.User(sql.FieldHasSuffix(FieldPassword, v)) -} - -// PasswordEqualFold applies the EqualFold predicate on the "password" field. -func PasswordEqualFold(v string) predicate.User { - return predicate.User(sql.FieldEqualFold(FieldPassword, v)) -} - -// PasswordContainsFold applies the ContainsFold predicate on the "password" field. -func PasswordContainsFold(v string) predicate.User { - return predicate.User(sql.FieldContainsFold(FieldPassword, v)) -} - -// VerifiedEQ applies the EQ predicate on the "verified" field. -func VerifiedEQ(v bool) predicate.User { - return predicate.User(sql.FieldEQ(FieldVerified, v)) -} - -// VerifiedNEQ applies the NEQ predicate on the "verified" field. -func VerifiedNEQ(v bool) predicate.User { - return predicate.User(sql.FieldNEQ(FieldVerified, v)) -} - -// CreatedAtEQ applies the EQ predicate on the "created_at" field. -func CreatedAtEQ(v time.Time) predicate.User { - return predicate.User(sql.FieldEQ(FieldCreatedAt, v)) -} - -// CreatedAtNEQ applies the NEQ predicate on the "created_at" field. -func CreatedAtNEQ(v time.Time) predicate.User { - return predicate.User(sql.FieldNEQ(FieldCreatedAt, v)) -} - -// CreatedAtIn applies the In predicate on the "created_at" field. -func CreatedAtIn(vs ...time.Time) predicate.User { - return predicate.User(sql.FieldIn(FieldCreatedAt, vs...)) -} - -// CreatedAtNotIn applies the NotIn predicate on the "created_at" field. -func CreatedAtNotIn(vs ...time.Time) predicate.User { - return predicate.User(sql.FieldNotIn(FieldCreatedAt, vs...)) -} - -// CreatedAtGT applies the GT predicate on the "created_at" field. -func CreatedAtGT(v time.Time) predicate.User { - return predicate.User(sql.FieldGT(FieldCreatedAt, v)) -} - -// CreatedAtGTE applies the GTE predicate on the "created_at" field. -func CreatedAtGTE(v time.Time) predicate.User { - return predicate.User(sql.FieldGTE(FieldCreatedAt, v)) -} - -// CreatedAtLT applies the LT predicate on the "created_at" field. -func CreatedAtLT(v time.Time) predicate.User { - return predicate.User(sql.FieldLT(FieldCreatedAt, v)) -} - -// CreatedAtLTE applies the LTE predicate on the "created_at" field. -func CreatedAtLTE(v time.Time) predicate.User { - return predicate.User(sql.FieldLTE(FieldCreatedAt, v)) -} - -// HasOwner applies the HasEdge predicate on the "owner" edge. -func HasOwner() predicate.User { - return predicate.User(func(s *sql.Selector) { - step := sqlgraph.NewStep( - sqlgraph.From(Table, FieldID), - sqlgraph.Edge(sqlgraph.O2M, true, OwnerTable, OwnerColumn), - ) - sqlgraph.HasNeighbors(s, step) - }) -} - -// HasOwnerWith applies the HasEdge predicate on the "owner" edge with a given conditions (other predicates). -func HasOwnerWith(preds ...predicate.PasswordToken) predicate.User { - return predicate.User(func(s *sql.Selector) { - step := newOwnerStep() - 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.User) predicate.User { - return predicate.User(sql.AndPredicates(predicates...)) -} - -// Or groups predicates with the OR operator between them. -func Or(predicates ...predicate.User) predicate.User { - return predicate.User(sql.OrPredicates(predicates...)) -} - -// Not applies the not operator on the given predicate. -func Not(p predicate.User) predicate.User { - return predicate.User(sql.NotPredicates(p)) -} diff --git a/ent/user_create.go b/ent/user_create.go deleted file mode 100644 index a42719a..0000000 --- a/ent/user_create.go +++ /dev/null @@ -1,320 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package ent - -import ( - "context" - "errors" - "fmt" - "time" - - "entgo.io/ent/dialect/sql/sqlgraph" - "entgo.io/ent/schema/field" - - "git.grosinger.net/tgrosinger/saasitone/ent/passwordtoken" - "git.grosinger.net/tgrosinger/saasitone/ent/user" -) - -// UserCreate is the builder for creating a User entity. -type UserCreate struct { - config - mutation *UserMutation - hooks []Hook -} - -// SetName sets the "name" field. -func (uc *UserCreate) SetName(s string) *UserCreate { - uc.mutation.SetName(s) - return uc -} - -// SetEmail sets the "email" field. -func (uc *UserCreate) SetEmail(s string) *UserCreate { - uc.mutation.SetEmail(s) - return uc -} - -// SetPassword sets the "password" field. -func (uc *UserCreate) SetPassword(s string) *UserCreate { - uc.mutation.SetPassword(s) - return uc -} - -// SetVerified sets the "verified" field. -func (uc *UserCreate) SetVerified(b bool) *UserCreate { - uc.mutation.SetVerified(b) - return uc -} - -// SetNillableVerified sets the "verified" field if the given value is not nil. -func (uc *UserCreate) SetNillableVerified(b *bool) *UserCreate { - if b != nil { - uc.SetVerified(*b) - } - return uc -} - -// SetCreatedAt sets the "created_at" field. -func (uc *UserCreate) SetCreatedAt(t time.Time) *UserCreate { - uc.mutation.SetCreatedAt(t) - return uc -} - -// SetNillableCreatedAt sets the "created_at" field if the given value is not nil. -func (uc *UserCreate) SetNillableCreatedAt(t *time.Time) *UserCreate { - if t != nil { - uc.SetCreatedAt(*t) - } - return uc -} - -// AddOwnerIDs adds the "owner" edge to the PasswordToken entity by IDs. -func (uc *UserCreate) AddOwnerIDs(ids ...int) *UserCreate { - uc.mutation.AddOwnerIDs(ids...) - return uc -} - -// AddOwner adds the "owner" edges to the PasswordToken entity. -func (uc *UserCreate) AddOwner(p ...*PasswordToken) *UserCreate { - ids := make([]int, len(p)) - for i := range p { - ids[i] = p[i].ID - } - return uc.AddOwnerIDs(ids...) -} - -// Mutation returns the UserMutation object of the builder. -func (uc *UserCreate) Mutation() *UserMutation { - return uc.mutation -} - -// Save creates the User in the database. -func (uc *UserCreate) Save(ctx context.Context) (*User, error) { - if err := uc.defaults(); err != nil { - return nil, err - } - return withHooks(ctx, uc.sqlSave, uc.mutation, uc.hooks) -} - -// SaveX calls Save and panics if Save returns an error. -func (uc *UserCreate) SaveX(ctx context.Context) *User { - v, err := uc.Save(ctx) - if err != nil { - panic(err) - } - return v -} - -// Exec executes the query. -func (uc *UserCreate) Exec(ctx context.Context) error { - _, err := uc.Save(ctx) - return err -} - -// ExecX is like Exec, but panics if an error occurs. -func (uc *UserCreate) ExecX(ctx context.Context) { - if err := uc.Exec(ctx); err != nil { - panic(err) - } -} - -// defaults sets the default values of the builder before save. -func (uc *UserCreate) defaults() error { - if _, ok := uc.mutation.Verified(); !ok { - v := user.DefaultVerified - uc.mutation.SetVerified(v) - } - if _, ok := uc.mutation.CreatedAt(); !ok { - if user.DefaultCreatedAt == nil { - return fmt.Errorf("ent: uninitialized user.DefaultCreatedAt (forgotten import ent/runtime?)") - } - v := user.DefaultCreatedAt() - uc.mutation.SetCreatedAt(v) - } - return nil -} - -// check runs all checks and user-defined validators on the builder. -func (uc *UserCreate) check() error { - if _, ok := uc.mutation.Name(); !ok { - return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "User.name"`)} - } - if v, ok := uc.mutation.Name(); ok { - if err := user.NameValidator(v); err != nil { - return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "User.name": %w`, err)} - } - } - if _, ok := uc.mutation.Email(); !ok { - return &ValidationError{Name: "email", err: errors.New(`ent: missing required field "User.email"`)} - } - if v, ok := uc.mutation.Email(); ok { - if err := user.EmailValidator(v); err != nil { - return &ValidationError{Name: "email", err: fmt.Errorf(`ent: validator failed for field "User.email": %w`, err)} - } - } - if _, ok := uc.mutation.Password(); !ok { - return &ValidationError{Name: "password", err: errors.New(`ent: missing required field "User.password"`)} - } - if v, ok := uc.mutation.Password(); ok { - if err := user.PasswordValidator(v); err != nil { - return &ValidationError{Name: "password", err: fmt.Errorf(`ent: validator failed for field "User.password": %w`, err)} - } - } - if _, ok := uc.mutation.Verified(); !ok { - return &ValidationError{Name: "verified", err: errors.New(`ent: missing required field "User.verified"`)} - } - if _, ok := uc.mutation.CreatedAt(); !ok { - return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "User.created_at"`)} - } - return nil -} - -func (uc *UserCreate) sqlSave(ctx context.Context) (*User, error) { - if err := uc.check(); err != nil { - return nil, err - } - _node, _spec := uc.createSpec() - if err := sqlgraph.CreateNode(ctx, uc.driver, _spec); err != nil { - if sqlgraph.IsConstraintError(err) { - err = &ConstraintError{msg: err.Error(), wrap: err} - } - return nil, err - } - id := _spec.ID.Value.(int64) - _node.ID = int(id) - uc.mutation.id = &_node.ID - uc.mutation.done = true - return _node, nil -} - -func (uc *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) { - var ( - _node = &User{config: uc.config} - _spec = sqlgraph.NewCreateSpec(user.Table, sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt)) - ) - if value, ok := uc.mutation.Name(); ok { - _spec.SetField(user.FieldName, field.TypeString, value) - _node.Name = value - } - if value, ok := uc.mutation.Email(); ok { - _spec.SetField(user.FieldEmail, field.TypeString, value) - _node.Email = value - } - if value, ok := uc.mutation.Password(); ok { - _spec.SetField(user.FieldPassword, field.TypeString, value) - _node.Password = value - } - if value, ok := uc.mutation.Verified(); ok { - _spec.SetField(user.FieldVerified, field.TypeBool, value) - _node.Verified = value - } - if value, ok := uc.mutation.CreatedAt(); ok { - _spec.SetField(user.FieldCreatedAt, field.TypeTime, value) - _node.CreatedAt = value - } - if nodes := uc.mutation.OwnerIDs(); len(nodes) > 0 { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, - Inverse: true, - Table: user.OwnerTable, - Columns: []string{user.OwnerColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: sqlgraph.NewFieldSpec(passwordtoken.FieldID, field.TypeInt), - }, - } - for _, k := range nodes { - edge.Target.Nodes = append(edge.Target.Nodes, k) - } - _spec.Edges = append(_spec.Edges, edge) - } - return _node, _spec -} - -// UserCreateBulk is the builder for creating many User entities in bulk. -type UserCreateBulk struct { - config - err error - builders []*UserCreate -} - -// Save creates the User entities in the database. -func (ucb *UserCreateBulk) Save(ctx context.Context) ([]*User, error) { - if ucb.err != nil { - return nil, ucb.err - } - specs := make([]*sqlgraph.CreateSpec, len(ucb.builders)) - nodes := make([]*User, len(ucb.builders)) - mutators := make([]Mutator, len(ucb.builders)) - for i := range ucb.builders { - func(i int, root context.Context) { - builder := ucb.builders[i] - builder.defaults() - var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) { - mutation, ok := m.(*UserMutation) - 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, ucb.builders[i+1].mutation) - } else { - spec := &sqlgraph.BatchCreateSpec{Nodes: specs} - // Invoke the actual operation on the latest mutation in the chain. - if err = sqlgraph.BatchCreate(ctx, ucb.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 { - id := specs[i].ID.Value.(int64) - nodes[i].ID = int(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, ucb.builders[0].mutation); err != nil { - return nil, err - } - } - return nodes, nil -} - -// SaveX is like Save, but panics if an error occurs. -func (ucb *UserCreateBulk) SaveX(ctx context.Context) []*User { - v, err := ucb.Save(ctx) - if err != nil { - panic(err) - } - return v -} - -// Exec executes the query. -func (ucb *UserCreateBulk) Exec(ctx context.Context) error { - _, err := ucb.Save(ctx) - return err -} - -// ExecX is like Exec, but panics if an error occurs. -func (ucb *UserCreateBulk) ExecX(ctx context.Context) { - if err := ucb.Exec(ctx); err != nil { - panic(err) - } -} diff --git a/ent/user_delete.go b/ent/user_delete.go deleted file mode 100644 index 20f59ac..0000000 --- a/ent/user_delete.go +++ /dev/null @@ -1,89 +0,0 @@ -// 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/schema/field" - - "git.grosinger.net/tgrosinger/saasitone/ent/predicate" - "git.grosinger.net/tgrosinger/saasitone/ent/user" -) - -// UserDelete is the builder for deleting a User entity. -type UserDelete struct { - config - hooks []Hook - mutation *UserMutation -} - -// Where appends a list predicates to the UserDelete builder. -func (ud *UserDelete) Where(ps ...predicate.User) *UserDelete { - ud.mutation.Where(ps...) - return ud -} - -// Exec executes the deletion query and returns how many vertices were deleted. -func (ud *UserDelete) Exec(ctx context.Context) (int, error) { - return withHooks(ctx, ud.sqlExec, ud.mutation, ud.hooks) -} - -// ExecX is like Exec, but panics if an error occurs. -func (ud *UserDelete) ExecX(ctx context.Context) int { - n, err := ud.Exec(ctx) - if err != nil { - panic(err) - } - return n -} - -func (ud *UserDelete) sqlExec(ctx context.Context) (int, error) { - _spec := sqlgraph.NewDeleteSpec(user.Table, sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt)) - if ps := ud.mutation.predicates; len(ps) > 0 { - _spec.Predicate = func(selector *sql.Selector) { - for i := range ps { - ps[i](selector) - } - } - } - affected, err := sqlgraph.DeleteNodes(ctx, ud.driver, _spec) - if err != nil && sqlgraph.IsConstraintError(err) { - err = &ConstraintError{msg: err.Error(), wrap: err} - } - ud.mutation.done = true - return affected, err -} - -// UserDeleteOne is the builder for deleting a single User entity. -type UserDeleteOne struct { - ud *UserDelete -} - -// Where appends a list predicates to the UserDelete builder. -func (udo *UserDeleteOne) Where(ps ...predicate.User) *UserDeleteOne { - udo.ud.mutation.Where(ps...) - return udo -} - -// Exec executes the deletion query. -func (udo *UserDeleteOne) Exec(ctx context.Context) error { - n, err := udo.ud.Exec(ctx) - switch { - case err != nil: - return err - case n == 0: - return &NotFoundError{user.Label} - default: - return nil - } -} - -// ExecX is like Exec, but panics if an error occurs. -func (udo *UserDeleteOne) ExecX(ctx context.Context) { - if err := udo.Exec(ctx); err != nil { - panic(err) - } -} diff --git a/ent/user_query.go b/ent/user_query.go deleted file mode 100644 index bebe185..0000000 --- a/ent/user_query.go +++ /dev/null @@ -1,607 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package ent - -import ( - "context" - "database/sql/driver" - "fmt" - "math" - - "entgo.io/ent/dialect/sql" - "entgo.io/ent/dialect/sql/sqlgraph" - "entgo.io/ent/schema/field" - - "git.grosinger.net/tgrosinger/saasitone/ent/passwordtoken" - "git.grosinger.net/tgrosinger/saasitone/ent/predicate" - "git.grosinger.net/tgrosinger/saasitone/ent/user" -) - -// UserQuery is the builder for querying User entities. -type UserQuery struct { - config - ctx *QueryContext - order []user.OrderOption - inters []Interceptor - predicates []predicate.User - withOwner *PasswordTokenQuery - // intermediate query (i.e. traversal path). - sql *sql.Selector - path func(context.Context) (*sql.Selector, error) -} - -// Where adds a new predicate for the UserQuery builder. -func (uq *UserQuery) Where(ps ...predicate.User) *UserQuery { - uq.predicates = append(uq.predicates, ps...) - return uq -} - -// Limit the number of records to be returned by this query. -func (uq *UserQuery) Limit(limit int) *UserQuery { - uq.ctx.Limit = &limit - return uq -} - -// Offset to start from. -func (uq *UserQuery) Offset(offset int) *UserQuery { - uq.ctx.Offset = &offset - return uq -} - -// 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 (uq *UserQuery) Unique(unique bool) *UserQuery { - uq.ctx.Unique = &unique - return uq -} - -// Order specifies how the records should be ordered. -func (uq *UserQuery) Order(o ...user.OrderOption) *UserQuery { - uq.order = append(uq.order, o...) - return uq -} - -// QueryOwner chains the current query on the "owner" edge. -func (uq *UserQuery) QueryOwner() *PasswordTokenQuery { - query := (&PasswordTokenClient{config: uq.config}).Query() - query.path = func(ctx context.Context) (fromU *sql.Selector, err error) { - if err := uq.prepareQuery(ctx); err != nil { - return nil, err - } - selector := uq.sqlQuery(ctx) - if err := selector.Err(); err != nil { - return nil, err - } - step := sqlgraph.NewStep( - sqlgraph.From(user.Table, user.FieldID, selector), - sqlgraph.To(passwordtoken.Table, passwordtoken.FieldID), - sqlgraph.Edge(sqlgraph.O2M, true, user.OwnerTable, user.OwnerColumn), - ) - fromU = sqlgraph.SetNeighbors(uq.driver.Dialect(), step) - return fromU, nil - } - return query -} - -// First returns the first User entity from the query. -// Returns a *NotFoundError when no User was found. -func (uq *UserQuery) First(ctx context.Context) (*User, error) { - nodes, err := uq.Limit(1).All(setContextOp(ctx, uq.ctx, "First")) - if err != nil { - return nil, err - } - if len(nodes) == 0 { - return nil, &NotFoundError{user.Label} - } - return nodes[0], nil -} - -// FirstX is like First, but panics if an error occurs. -func (uq *UserQuery) FirstX(ctx context.Context) *User { - node, err := uq.First(ctx) - if err != nil && !IsNotFound(err) { - panic(err) - } - return node -} - -// FirstID returns the first User ID from the query. -// Returns a *NotFoundError when no User ID was found. -func (uq *UserQuery) FirstID(ctx context.Context) (id int, err error) { - var ids []int - if ids, err = uq.Limit(1).IDs(setContextOp(ctx, uq.ctx, "FirstID")); err != nil { - return - } - if len(ids) == 0 { - err = &NotFoundError{user.Label} - return - } - return ids[0], nil -} - -// FirstIDX is like FirstID, but panics if an error occurs. -func (uq *UserQuery) FirstIDX(ctx context.Context) int { - id, err := uq.FirstID(ctx) - if err != nil && !IsNotFound(err) { - panic(err) - } - return id -} - -// Only returns a single User entity found by the query, ensuring it only returns one. -// Returns a *NotSingularError when more than one User entity is found. -// Returns a *NotFoundError when no User entities are found. -func (uq *UserQuery) Only(ctx context.Context) (*User, error) { - nodes, err := uq.Limit(2).All(setContextOp(ctx, uq.ctx, "Only")) - if err != nil { - return nil, err - } - switch len(nodes) { - case 1: - return nodes[0], nil - case 0: - return nil, &NotFoundError{user.Label} - default: - return nil, &NotSingularError{user.Label} - } -} - -// OnlyX is like Only, but panics if an error occurs. -func (uq *UserQuery) OnlyX(ctx context.Context) *User { - node, err := uq.Only(ctx) - if err != nil { - panic(err) - } - return node -} - -// OnlyID is like Only, but returns the only User ID in the query. -// Returns a *NotSingularError when more than one User ID is found. -// Returns a *NotFoundError when no entities are found. -func (uq *UserQuery) OnlyID(ctx context.Context) (id int, err error) { - var ids []int - if ids, err = uq.Limit(2).IDs(setContextOp(ctx, uq.ctx, "OnlyID")); err != nil { - return - } - switch len(ids) { - case 1: - id = ids[0] - case 0: - err = &NotFoundError{user.Label} - default: - err = &NotSingularError{user.Label} - } - return -} - -// OnlyIDX is like OnlyID, but panics if an error occurs. -func (uq *UserQuery) OnlyIDX(ctx context.Context) int { - id, err := uq.OnlyID(ctx) - if err != nil { - panic(err) - } - return id -} - -// All executes the query and returns a list of Users. -func (uq *UserQuery) All(ctx context.Context) ([]*User, error) { - ctx = setContextOp(ctx, uq.ctx, "All") - if err := uq.prepareQuery(ctx); err != nil { - return nil, err - } - qr := querierAll[[]*User, *UserQuery]() - return withInterceptors[[]*User](ctx, uq, qr, uq.inters) -} - -// AllX is like All, but panics if an error occurs. -func (uq *UserQuery) AllX(ctx context.Context) []*User { - nodes, err := uq.All(ctx) - if err != nil { - panic(err) - } - return nodes -} - -// IDs executes the query and returns a list of User IDs. -func (uq *UserQuery) IDs(ctx context.Context) (ids []int, err error) { - if uq.ctx.Unique == nil && uq.path != nil { - uq.Unique(true) - } - ctx = setContextOp(ctx, uq.ctx, "IDs") - if err = uq.Select(user.FieldID).Scan(ctx, &ids); err != nil { - return nil, err - } - return ids, nil -} - -// IDsX is like IDs, but panics if an error occurs. -func (uq *UserQuery) IDsX(ctx context.Context) []int { - ids, err := uq.IDs(ctx) - if err != nil { - panic(err) - } - return ids -} - -// Count returns the count of the given query. -func (uq *UserQuery) Count(ctx context.Context) (int, error) { - ctx = setContextOp(ctx, uq.ctx, "Count") - if err := uq.prepareQuery(ctx); err != nil { - return 0, err - } - return withInterceptors[int](ctx, uq, querierCount[*UserQuery](), uq.inters) -} - -// CountX is like Count, but panics if an error occurs. -func (uq *UserQuery) CountX(ctx context.Context) int { - count, err := uq.Count(ctx) - if err != nil { - panic(err) - } - return count -} - -// Exist returns true if the query has elements in the graph. -func (uq *UserQuery) Exist(ctx context.Context) (bool, error) { - ctx = setContextOp(ctx, uq.ctx, "Exist") - switch _, err := uq.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 (uq *UserQuery) ExistX(ctx context.Context) bool { - exist, err := uq.Exist(ctx) - if err != nil { - panic(err) - } - return exist -} - -// Clone returns a duplicate of the UserQuery builder, including all associated steps. It can be -// used to prepare common query builders and use them differently after the clone is made. -func (uq *UserQuery) Clone() *UserQuery { - if uq == nil { - return nil - } - return &UserQuery{ - config: uq.config, - ctx: uq.ctx.Clone(), - order: append([]user.OrderOption{}, uq.order...), - inters: append([]Interceptor{}, uq.inters...), - predicates: append([]predicate.User{}, uq.predicates...), - withOwner: uq.withOwner.Clone(), - // clone intermediate query. - sql: uq.sql.Clone(), - path: uq.path, - } -} - -// WithOwner tells the query-builder to eager-load the nodes that are connected to -// the "owner" edge. The optional arguments are used to configure the query builder of the edge. -func (uq *UserQuery) WithOwner(opts ...func(*PasswordTokenQuery)) *UserQuery { - query := (&PasswordTokenClient{config: uq.config}).Query() - for _, opt := range opts { - opt(query) - } - uq.withOwner = query - return uq -} - -// 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 { -// Name string `json:"name,omitempty"` -// Count int `json:"count,omitempty"` -// } -// -// client.User.Query(). -// GroupBy(user.FieldName). -// Aggregate(ent.Count()). -// Scan(ctx, &v) -func (uq *UserQuery) GroupBy(field string, fields ...string) *UserGroupBy { - uq.ctx.Fields = append([]string{field}, fields...) - grbuild := &UserGroupBy{build: uq} - grbuild.flds = &uq.ctx.Fields - grbuild.label = user.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 { -// Name string `json:"name,omitempty"` -// } -// -// client.User.Query(). -// Select(user.FieldName). -// Scan(ctx, &v) -func (uq *UserQuery) Select(fields ...string) *UserSelect { - uq.ctx.Fields = append(uq.ctx.Fields, fields...) - sbuild := &UserSelect{UserQuery: uq} - sbuild.label = user.Label - sbuild.flds, sbuild.scan = &uq.ctx.Fields, sbuild.Scan - return sbuild -} - -// Aggregate returns a UserSelect configured with the given aggregations. -func (uq *UserQuery) Aggregate(fns ...AggregateFunc) *UserSelect { - return uq.Select().Aggregate(fns...) -} - -func (uq *UserQuery) prepareQuery(ctx context.Context) error { - for _, inter := range uq.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, uq); err != nil { - return err - } - } - } - for _, f := range uq.ctx.Fields { - if !user.ValidColumn(f) { - return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} - } - } - if uq.path != nil { - prev, err := uq.path(ctx) - if err != nil { - return err - } - uq.sql = prev - } - return nil -} - -func (uq *UserQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*User, error) { - var ( - nodes = []*User{} - _spec = uq.querySpec() - loadedTypes = [1]bool{ - uq.withOwner != nil, - } - ) - _spec.ScanValues = func(columns []string) ([]any, error) { - return (*User).scanValues(nil, columns) - } - _spec.Assign = func(columns []string, values []any) error { - node := &User{config: uq.config} - nodes = append(nodes, node) - node.Edges.loadedTypes = loadedTypes - return node.assignValues(columns, values) - } - for i := range hooks { - hooks[i](ctx, _spec) - } - if err := sqlgraph.QueryNodes(ctx, uq.driver, _spec); err != nil { - return nil, err - } - if len(nodes) == 0 { - return nodes, nil - } - if query := uq.withOwner; query != nil { - if err := uq.loadOwner(ctx, query, nodes, - func(n *User) { n.Edges.Owner = []*PasswordToken{} }, - func(n *User, e *PasswordToken) { n.Edges.Owner = append(n.Edges.Owner, e) }); err != nil { - return nil, err - } - } - return nodes, nil -} - -func (uq *UserQuery) loadOwner(ctx context.Context, query *PasswordTokenQuery, nodes []*User, init func(*User), assign func(*User, *PasswordToken)) error { - fks := make([]driver.Value, 0, len(nodes)) - nodeids := make(map[int]*User) - for i := range nodes { - fks = append(fks, nodes[i].ID) - nodeids[nodes[i].ID] = nodes[i] - if init != nil { - init(nodes[i]) - } - } - query.withFKs = true - query.Where(predicate.PasswordToken(func(s *sql.Selector) { - s.Where(sql.InValues(s.C(user.OwnerColumn), fks...)) - })) - neighbors, err := query.All(ctx) - if err != nil { - return err - } - for _, n := range neighbors { - fk := n.password_token_user - if fk == nil { - return fmt.Errorf(`foreign-key "password_token_user" is nil for node %v`, n.ID) - } - node, ok := nodeids[*fk] - if !ok { - return fmt.Errorf(`unexpected referenced foreign-key "password_token_user" returned %v for node %v`, *fk, n.ID) - } - assign(node, n) - } - return nil -} - -func (uq *UserQuery) sqlCount(ctx context.Context) (int, error) { - _spec := uq.querySpec() - _spec.Node.Columns = uq.ctx.Fields - if len(uq.ctx.Fields) > 0 { - _spec.Unique = uq.ctx.Unique != nil && *uq.ctx.Unique - } - return sqlgraph.CountNodes(ctx, uq.driver, _spec) -} - -func (uq *UserQuery) querySpec() *sqlgraph.QuerySpec { - _spec := sqlgraph.NewQuerySpec(user.Table, user.Columns, sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt)) - _spec.From = uq.sql - if unique := uq.ctx.Unique; unique != nil { - _spec.Unique = *unique - } else if uq.path != nil { - _spec.Unique = true - } - if fields := uq.ctx.Fields; len(fields) > 0 { - _spec.Node.Columns = make([]string, 0, len(fields)) - _spec.Node.Columns = append(_spec.Node.Columns, user.FieldID) - for i := range fields { - if fields[i] != user.FieldID { - _spec.Node.Columns = append(_spec.Node.Columns, fields[i]) - } - } - } - if ps := uq.predicates; len(ps) > 0 { - _spec.Predicate = func(selector *sql.Selector) { - for i := range ps { - ps[i](selector) - } - } - } - if limit := uq.ctx.Limit; limit != nil { - _spec.Limit = *limit - } - if offset := uq.ctx.Offset; offset != nil { - _spec.Offset = *offset - } - if ps := uq.order; len(ps) > 0 { - _spec.Order = func(selector *sql.Selector) { - for i := range ps { - ps[i](selector) - } - } - } - return _spec -} - -func (uq *UserQuery) sqlQuery(ctx context.Context) *sql.Selector { - builder := sql.Dialect(uq.driver.Dialect()) - t1 := builder.Table(user.Table) - columns := uq.ctx.Fields - if len(columns) == 0 { - columns = user.Columns - } - selector := builder.Select(t1.Columns(columns...)...).From(t1) - if uq.sql != nil { - selector = uq.sql - selector.Select(selector.Columns(columns...)...) - } - if uq.ctx.Unique != nil && *uq.ctx.Unique { - selector.Distinct() - } - for _, p := range uq.predicates { - p(selector) - } - for _, p := range uq.order { - p(selector) - } - if offset := uq.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 := uq.ctx.Limit; limit != nil { - selector.Limit(*limit) - } - return selector -} - -// UserGroupBy is the group-by builder for User entities. -type UserGroupBy struct { - selector - build *UserQuery -} - -// Aggregate adds the given aggregation functions to the group-by query. -func (ugb *UserGroupBy) Aggregate(fns ...AggregateFunc) *UserGroupBy { - ugb.fns = append(ugb.fns, fns...) - return ugb -} - -// Scan applies the selector query and scans the result into the given value. -func (ugb *UserGroupBy) Scan(ctx context.Context, v any) error { - ctx = setContextOp(ctx, ugb.build.ctx, "GroupBy") - if err := ugb.build.prepareQuery(ctx); err != nil { - return err - } - return scanWithInterceptors[*UserQuery, *UserGroupBy](ctx, ugb.build, ugb, ugb.build.inters, v) -} - -func (ugb *UserGroupBy) sqlScan(ctx context.Context, root *UserQuery, v any) error { - selector := root.sqlQuery(ctx).Select() - aggregation := make([]string, 0, len(ugb.fns)) - for _, fn := range ugb.fns { - aggregation = append(aggregation, fn(selector)) - } - if len(selector.SelectedColumns()) == 0 { - columns := make([]string, 0, len(*ugb.flds)+len(ugb.fns)) - for _, f := range *ugb.flds { - columns = append(columns, selector.C(f)) - } - columns = append(columns, aggregation...) - selector.Select(columns...) - } - selector.GroupBy(selector.Columns(*ugb.flds...)...) - if err := selector.Err(); err != nil { - return err - } - rows := &sql.Rows{} - query, args := selector.Query() - if err := ugb.build.driver.Query(ctx, query, args, rows); err != nil { - return err - } - defer rows.Close() - return sql.ScanSlice(rows, v) -} - -// UserSelect is the builder for selecting fields of User entities. -type UserSelect struct { - *UserQuery - selector -} - -// Aggregate adds the given aggregation functions to the selector query. -func (us *UserSelect) Aggregate(fns ...AggregateFunc) *UserSelect { - us.fns = append(us.fns, fns...) - return us -} - -// Scan applies the selector query and scans the result into the given value. -func (us *UserSelect) Scan(ctx context.Context, v any) error { - ctx = setContextOp(ctx, us.ctx, "Select") - if err := us.prepareQuery(ctx); err != nil { - return err - } - return scanWithInterceptors[*UserQuery, *UserSelect](ctx, us.UserQuery, us, us.inters, v) -} - -func (us *UserSelect) sqlScan(ctx context.Context, root *UserQuery, v any) error { - selector := root.sqlQuery(ctx) - aggregation := make([]string, 0, len(us.fns)) - for _, fn := range us.fns { - aggregation = append(aggregation, fn(selector)) - } - switch n := len(*us.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 := us.driver.Query(ctx, query, args, rows); err != nil { - return err - } - defer rows.Close() - return sql.ScanSlice(rows, v) -} diff --git a/ent/user_update.go b/ent/user_update.go deleted file mode 100644 index d1b144f..0000000 --- a/ent/user_update.go +++ /dev/null @@ -1,521 +0,0 @@ -// Code generated by ent, DO NOT EDIT. - -package ent - -import ( - "context" - "errors" - "fmt" - - "entgo.io/ent/dialect/sql" - "entgo.io/ent/dialect/sql/sqlgraph" - "entgo.io/ent/schema/field" - - "git.grosinger.net/tgrosinger/saasitone/ent/passwordtoken" - "git.grosinger.net/tgrosinger/saasitone/ent/predicate" - "git.grosinger.net/tgrosinger/saasitone/ent/user" -) - -// UserUpdate is the builder for updating User entities. -type UserUpdate struct { - config - hooks []Hook - mutation *UserMutation -} - -// Where appends a list predicates to the UserUpdate builder. -func (uu *UserUpdate) Where(ps ...predicate.User) *UserUpdate { - uu.mutation.Where(ps...) - return uu -} - -// SetName sets the "name" field. -func (uu *UserUpdate) SetName(s string) *UserUpdate { - uu.mutation.SetName(s) - return uu -} - -// SetNillableName sets the "name" field if the given value is not nil. -func (uu *UserUpdate) SetNillableName(s *string) *UserUpdate { - if s != nil { - uu.SetName(*s) - } - return uu -} - -// SetEmail sets the "email" field. -func (uu *UserUpdate) SetEmail(s string) *UserUpdate { - uu.mutation.SetEmail(s) - return uu -} - -// SetNillableEmail sets the "email" field if the given value is not nil. -func (uu *UserUpdate) SetNillableEmail(s *string) *UserUpdate { - if s != nil { - uu.SetEmail(*s) - } - return uu -} - -// SetPassword sets the "password" field. -func (uu *UserUpdate) SetPassword(s string) *UserUpdate { - uu.mutation.SetPassword(s) - return uu -} - -// SetNillablePassword sets the "password" field if the given value is not nil. -func (uu *UserUpdate) SetNillablePassword(s *string) *UserUpdate { - if s != nil { - uu.SetPassword(*s) - } - return uu -} - -// SetVerified sets the "verified" field. -func (uu *UserUpdate) SetVerified(b bool) *UserUpdate { - uu.mutation.SetVerified(b) - return uu -} - -// SetNillableVerified sets the "verified" field if the given value is not nil. -func (uu *UserUpdate) SetNillableVerified(b *bool) *UserUpdate { - if b != nil { - uu.SetVerified(*b) - } - return uu -} - -// AddOwnerIDs adds the "owner" edge to the PasswordToken entity by IDs. -func (uu *UserUpdate) AddOwnerIDs(ids ...int) *UserUpdate { - uu.mutation.AddOwnerIDs(ids...) - return uu -} - -// AddOwner adds the "owner" edges to the PasswordToken entity. -func (uu *UserUpdate) AddOwner(p ...*PasswordToken) *UserUpdate { - ids := make([]int, len(p)) - for i := range p { - ids[i] = p[i].ID - } - return uu.AddOwnerIDs(ids...) -} - -// Mutation returns the UserMutation object of the builder. -func (uu *UserUpdate) Mutation() *UserMutation { - return uu.mutation -} - -// ClearOwner clears all "owner" edges to the PasswordToken entity. -func (uu *UserUpdate) ClearOwner() *UserUpdate { - uu.mutation.ClearOwner() - return uu -} - -// RemoveOwnerIDs removes the "owner" edge to PasswordToken entities by IDs. -func (uu *UserUpdate) RemoveOwnerIDs(ids ...int) *UserUpdate { - uu.mutation.RemoveOwnerIDs(ids...) - return uu -} - -// RemoveOwner removes "owner" edges to PasswordToken entities. -func (uu *UserUpdate) RemoveOwner(p ...*PasswordToken) *UserUpdate { - ids := make([]int, len(p)) - for i := range p { - ids[i] = p[i].ID - } - return uu.RemoveOwnerIDs(ids...) -} - -// Save executes the query and returns the number of nodes affected by the update operation. -func (uu *UserUpdate) Save(ctx context.Context) (int, error) { - return withHooks(ctx, uu.sqlSave, uu.mutation, uu.hooks) -} - -// SaveX is like Save, but panics if an error occurs. -func (uu *UserUpdate) SaveX(ctx context.Context) int { - affected, err := uu.Save(ctx) - if err != nil { - panic(err) - } - return affected -} - -// Exec executes the query. -func (uu *UserUpdate) Exec(ctx context.Context) error { - _, err := uu.Save(ctx) - return err -} - -// ExecX is like Exec, but panics if an error occurs. -func (uu *UserUpdate) ExecX(ctx context.Context) { - if err := uu.Exec(ctx); err != nil { - panic(err) - } -} - -// check runs all checks and user-defined validators on the builder. -func (uu *UserUpdate) check() error { - if v, ok := uu.mutation.Name(); ok { - if err := user.NameValidator(v); err != nil { - return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "User.name": %w`, err)} - } - } - if v, ok := uu.mutation.Email(); ok { - if err := user.EmailValidator(v); err != nil { - return &ValidationError{Name: "email", err: fmt.Errorf(`ent: validator failed for field "User.email": %w`, err)} - } - } - if v, ok := uu.mutation.Password(); ok { - if err := user.PasswordValidator(v); err != nil { - return &ValidationError{Name: "password", err: fmt.Errorf(`ent: validator failed for field "User.password": %w`, err)} - } - } - return nil -} - -func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) { - if err := uu.check(); err != nil { - return n, err - } - _spec := sqlgraph.NewUpdateSpec(user.Table, user.Columns, sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt)) - if ps := uu.mutation.predicates; len(ps) > 0 { - _spec.Predicate = func(selector *sql.Selector) { - for i := range ps { - ps[i](selector) - } - } - } - if value, ok := uu.mutation.Name(); ok { - _spec.SetField(user.FieldName, field.TypeString, value) - } - if value, ok := uu.mutation.Email(); ok { - _spec.SetField(user.FieldEmail, field.TypeString, value) - } - if value, ok := uu.mutation.Password(); ok { - _spec.SetField(user.FieldPassword, field.TypeString, value) - } - if value, ok := uu.mutation.Verified(); ok { - _spec.SetField(user.FieldVerified, field.TypeBool, value) - } - if uu.mutation.OwnerCleared() { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, - Inverse: true, - Table: user.OwnerTable, - Columns: []string{user.OwnerColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: sqlgraph.NewFieldSpec(passwordtoken.FieldID, field.TypeInt), - }, - } - _spec.Edges.Clear = append(_spec.Edges.Clear, edge) - } - if nodes := uu.mutation.RemovedOwnerIDs(); len(nodes) > 0 && !uu.mutation.OwnerCleared() { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, - Inverse: true, - Table: user.OwnerTable, - Columns: []string{user.OwnerColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: sqlgraph.NewFieldSpec(passwordtoken.FieldID, field.TypeInt), - }, - } - for _, k := range nodes { - edge.Target.Nodes = append(edge.Target.Nodes, k) - } - _spec.Edges.Clear = append(_spec.Edges.Clear, edge) - } - if nodes := uu.mutation.OwnerIDs(); len(nodes) > 0 { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, - Inverse: true, - Table: user.OwnerTable, - Columns: []string{user.OwnerColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: sqlgraph.NewFieldSpec(passwordtoken.FieldID, field.TypeInt), - }, - } - for _, k := range nodes { - edge.Target.Nodes = append(edge.Target.Nodes, k) - } - _spec.Edges.Add = append(_spec.Edges.Add, edge) - } - if n, err = sqlgraph.UpdateNodes(ctx, uu.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { - err = &NotFoundError{user.Label} - } else if sqlgraph.IsConstraintError(err) { - err = &ConstraintError{msg: err.Error(), wrap: err} - } - return 0, err - } - uu.mutation.done = true - return n, nil -} - -// UserUpdateOne is the builder for updating a single User entity. -type UserUpdateOne struct { - config - fields []string - hooks []Hook - mutation *UserMutation -} - -// SetName sets the "name" field. -func (uuo *UserUpdateOne) SetName(s string) *UserUpdateOne { - uuo.mutation.SetName(s) - return uuo -} - -// SetNillableName sets the "name" field if the given value is not nil. -func (uuo *UserUpdateOne) SetNillableName(s *string) *UserUpdateOne { - if s != nil { - uuo.SetName(*s) - } - return uuo -} - -// SetEmail sets the "email" field. -func (uuo *UserUpdateOne) SetEmail(s string) *UserUpdateOne { - uuo.mutation.SetEmail(s) - return uuo -} - -// SetNillableEmail sets the "email" field if the given value is not nil. -func (uuo *UserUpdateOne) SetNillableEmail(s *string) *UserUpdateOne { - if s != nil { - uuo.SetEmail(*s) - } - return uuo -} - -// SetPassword sets the "password" field. -func (uuo *UserUpdateOne) SetPassword(s string) *UserUpdateOne { - uuo.mutation.SetPassword(s) - return uuo -} - -// SetNillablePassword sets the "password" field if the given value is not nil. -func (uuo *UserUpdateOne) SetNillablePassword(s *string) *UserUpdateOne { - if s != nil { - uuo.SetPassword(*s) - } - return uuo -} - -// SetVerified sets the "verified" field. -func (uuo *UserUpdateOne) SetVerified(b bool) *UserUpdateOne { - uuo.mutation.SetVerified(b) - return uuo -} - -// SetNillableVerified sets the "verified" field if the given value is not nil. -func (uuo *UserUpdateOne) SetNillableVerified(b *bool) *UserUpdateOne { - if b != nil { - uuo.SetVerified(*b) - } - return uuo -} - -// AddOwnerIDs adds the "owner" edge to the PasswordToken entity by IDs. -func (uuo *UserUpdateOne) AddOwnerIDs(ids ...int) *UserUpdateOne { - uuo.mutation.AddOwnerIDs(ids...) - return uuo -} - -// AddOwner adds the "owner" edges to the PasswordToken entity. -func (uuo *UserUpdateOne) AddOwner(p ...*PasswordToken) *UserUpdateOne { - ids := make([]int, len(p)) - for i := range p { - ids[i] = p[i].ID - } - return uuo.AddOwnerIDs(ids...) -} - -// Mutation returns the UserMutation object of the builder. -func (uuo *UserUpdateOne) Mutation() *UserMutation { - return uuo.mutation -} - -// ClearOwner clears all "owner" edges to the PasswordToken entity. -func (uuo *UserUpdateOne) ClearOwner() *UserUpdateOne { - uuo.mutation.ClearOwner() - return uuo -} - -// RemoveOwnerIDs removes the "owner" edge to PasswordToken entities by IDs. -func (uuo *UserUpdateOne) RemoveOwnerIDs(ids ...int) *UserUpdateOne { - uuo.mutation.RemoveOwnerIDs(ids...) - return uuo -} - -// RemoveOwner removes "owner" edges to PasswordToken entities. -func (uuo *UserUpdateOne) RemoveOwner(p ...*PasswordToken) *UserUpdateOne { - ids := make([]int, len(p)) - for i := range p { - ids[i] = p[i].ID - } - return uuo.RemoveOwnerIDs(ids...) -} - -// Where appends a list predicates to the UserUpdate builder. -func (uuo *UserUpdateOne) Where(ps ...predicate.User) *UserUpdateOne { - uuo.mutation.Where(ps...) - return uuo -} - -// Select allows selecting one or more fields (columns) of the returned entity. -// The default is selecting all fields defined in the entity schema. -func (uuo *UserUpdateOne) Select(field string, fields ...string) *UserUpdateOne { - uuo.fields = append([]string{field}, fields...) - return uuo -} - -// Save executes the query and returns the updated User entity. -func (uuo *UserUpdateOne) Save(ctx context.Context) (*User, error) { - return withHooks(ctx, uuo.sqlSave, uuo.mutation, uuo.hooks) -} - -// SaveX is like Save, but panics if an error occurs. -func (uuo *UserUpdateOne) SaveX(ctx context.Context) *User { - node, err := uuo.Save(ctx) - if err != nil { - panic(err) - } - return node -} - -// Exec executes the query on the entity. -func (uuo *UserUpdateOne) Exec(ctx context.Context) error { - _, err := uuo.Save(ctx) - return err -} - -// ExecX is like Exec, but panics if an error occurs. -func (uuo *UserUpdateOne) ExecX(ctx context.Context) { - if err := uuo.Exec(ctx); err != nil { - panic(err) - } -} - -// check runs all checks and user-defined validators on the builder. -func (uuo *UserUpdateOne) check() error { - if v, ok := uuo.mutation.Name(); ok { - if err := user.NameValidator(v); err != nil { - return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "User.name": %w`, err)} - } - } - if v, ok := uuo.mutation.Email(); ok { - if err := user.EmailValidator(v); err != nil { - return &ValidationError{Name: "email", err: fmt.Errorf(`ent: validator failed for field "User.email": %w`, err)} - } - } - if v, ok := uuo.mutation.Password(); ok { - if err := user.PasswordValidator(v); err != nil { - return &ValidationError{Name: "password", err: fmt.Errorf(`ent: validator failed for field "User.password": %w`, err)} - } - } - return nil -} - -func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) { - if err := uuo.check(); err != nil { - return _node, err - } - _spec := sqlgraph.NewUpdateSpec(user.Table, user.Columns, sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt)) - id, ok := uuo.mutation.ID() - if !ok { - return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "User.id" for update`)} - } - _spec.Node.ID.Value = id - if fields := uuo.fields; len(fields) > 0 { - _spec.Node.Columns = make([]string, 0, len(fields)) - _spec.Node.Columns = append(_spec.Node.Columns, user.FieldID) - for _, f := range fields { - if !user.ValidColumn(f) { - return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)} - } - if f != user.FieldID { - _spec.Node.Columns = append(_spec.Node.Columns, f) - } - } - } - if ps := uuo.mutation.predicates; len(ps) > 0 { - _spec.Predicate = func(selector *sql.Selector) { - for i := range ps { - ps[i](selector) - } - } - } - if value, ok := uuo.mutation.Name(); ok { - _spec.SetField(user.FieldName, field.TypeString, value) - } - if value, ok := uuo.mutation.Email(); ok { - _spec.SetField(user.FieldEmail, field.TypeString, value) - } - if value, ok := uuo.mutation.Password(); ok { - _spec.SetField(user.FieldPassword, field.TypeString, value) - } - if value, ok := uuo.mutation.Verified(); ok { - _spec.SetField(user.FieldVerified, field.TypeBool, value) - } - if uuo.mutation.OwnerCleared() { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, - Inverse: true, - Table: user.OwnerTable, - Columns: []string{user.OwnerColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: sqlgraph.NewFieldSpec(passwordtoken.FieldID, field.TypeInt), - }, - } - _spec.Edges.Clear = append(_spec.Edges.Clear, edge) - } - if nodes := uuo.mutation.RemovedOwnerIDs(); len(nodes) > 0 && !uuo.mutation.OwnerCleared() { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, - Inverse: true, - Table: user.OwnerTable, - Columns: []string{user.OwnerColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: sqlgraph.NewFieldSpec(passwordtoken.FieldID, field.TypeInt), - }, - } - for _, k := range nodes { - edge.Target.Nodes = append(edge.Target.Nodes, k) - } - _spec.Edges.Clear = append(_spec.Edges.Clear, edge) - } - if nodes := uuo.mutation.OwnerIDs(); len(nodes) > 0 { - edge := &sqlgraph.EdgeSpec{ - Rel: sqlgraph.O2M, - Inverse: true, - Table: user.OwnerTable, - Columns: []string{user.OwnerColumn}, - Bidi: false, - Target: &sqlgraph.EdgeTarget{ - IDSpec: sqlgraph.NewFieldSpec(passwordtoken.FieldID, field.TypeInt), - }, - } - for _, k := range nodes { - edge.Target.Nodes = append(edge.Target.Nodes, k) - } - _spec.Edges.Add = append(_spec.Edges.Add, edge) - } - _node = &User{config: uuo.config} - _spec.Assign = _node.assignValues - _spec.ScanValues = _node.scanValues - if err = sqlgraph.UpdateNode(ctx, uuo.driver, _spec); err != nil { - if _, ok := err.(*sqlgraph.NotFoundError); ok { - err = &NotFoundError{user.Label} - } else if sqlgraph.IsConstraintError(err) { - err = &ConstraintError{msg: err.Error(), wrap: err} - } - return nil, err - } - uuo.mutation.done = true - return _node, nil -} diff --git a/go.mod b/go.mod index f1c8c23..404d900 100644 --- a/go.mod +++ b/go.mod @@ -37,21 +37,27 @@ require ( github.com/go-openapi/inflect v0.21.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/golang-migrate/migrate/v4 v4.17.1 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/securecookie v1.1.2 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl/v2 v2.20.1 // indirect github.com/huandu/xstrings v1.4.0 // indirect github.com/imdario/mergo v0.3.16 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/rogpeppe/go-internal v1.10.0 // indirect @@ -60,11 +66,13 @@ require ( github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/cobra v1.7.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.2 // indirect github.com/zclconf/go-cty v1.14.4 // indirect + go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.11.0 // indirect golang.org/x/exp v0.0.0-20240707233637-46b078467d37 // indirect golang.org/x/mod v0.19.0 // indirect diff --git a/go.sum b/go.sum index 91a8065..ddeda86 100644 --- a/go.sum +++ b/go.sum @@ -20,6 +20,7 @@ github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsVi github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU= 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/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -52,6 +53,8 @@ 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 v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= +github.com/golang-migrate/migrate/v4 v4.17.1 h1:4zQ6iqL6t6AiItphxJctQb3cFqWiSpMnX7wLTPnnYO4= +github.com/golang-migrate/migrate/v4 v4.17.1/go.mod h1:m8hinFyWBn0SA4QKHuKh175Pm9wjmxj3S2Mia7dbXzM= 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/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= @@ -66,6 +69,11 @@ github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTj github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ= github.com/gorilla/sessions v1.3.0 h1:XYlkq7KcpOB2ZhHBPv5WpjMIxrQosiZanfoy1HLZFzg= github.com/gorilla/sessions v1.3.0/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/hcl/v2 v2.20.1 h1:M6hgdyz7HYt1UN9e61j+qKJBqR3orTWbI1HKBJEdxtc= @@ -74,6 +82,8 @@ github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= @@ -98,6 +108,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/maypok86/otter v1.2.1 h1:xyvMW+t0vE1sKt/++GTkznLitEl7D/msqXkAbLwiC1M= @@ -110,6 +122,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/pelletier/go-toml/v2 v2.2.1 h1:9TA9+T8+8CUCO2+WYnDLCgrYi9+omqKXyjDtosvtEhg= github.com/pelletier/go-toml/v2 v2.2.1/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= @@ -119,6 +133,7 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk= @@ -131,6 +146,8 @@ github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= 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/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= @@ -141,6 +158,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 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/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -157,6 +175,8 @@ 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-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -224,6 +244,7 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pkg/db/time.go b/pkg/db/time.go new file mode 100644 index 0000000..8132030 --- /dev/null +++ b/pkg/db/time.go @@ -0,0 +1,37 @@ +package db + +import ( + "database/sql/driver" + "errors" + "time" +) + +const timeFormat = "2006-01-02 15:04:05" + +type Time struct { + time.Time +} + +func (t *Time) Scan(value any) error { + valueStr := "" + switch s := value.(type) { + case string: + valueStr = s + case []byte: + valueStr = string(s) + default: + return errors.New("Cannot scan value into Time") + } + + parsedTime, err := time.Parse(timeFormat, valueStr) + if err != nil { + return err + } + + t.Time = parsedTime + return nil +} + +func (t Time) Value() (driver.Value, error) { + return t.Format(timeFormat), nil +} diff --git a/pkg/handlers/auth.go b/pkg/handlers/auth.go index bd928b2..eb39277 100644 --- a/pkg/handlers/auth.go +++ b/pkg/handlers/auth.go @@ -1,18 +1,19 @@ package handlers import ( + "database/sql" "fmt" "strings" "github.com/go-playground/validator/v10" "github.com/labstack/echo/v4" - "git.grosinger.net/tgrosinger/saasitone/ent" - "git.grosinger.net/tgrosinger/saasitone/ent/user" "git.grosinger.net/tgrosinger/saasitone/pkg/context" "git.grosinger.net/tgrosinger/saasitone/pkg/form" "git.grosinger.net/tgrosinger/saasitone/pkg/log" "git.grosinger.net/tgrosinger/saasitone/pkg/middleware" + "git.grosinger.net/tgrosinger/saasitone/pkg/models" + "git.grosinger.net/tgrosinger/saasitone/pkg/models/sqlc" "git.grosinger.net/tgrosinger/saasitone/pkg/msg" "git.grosinger.net/tgrosinger/saasitone/pkg/page" "git.grosinger.net/tgrosinger/saasitone/pkg/redirect" @@ -37,7 +38,7 @@ type ( Auth struct { auth *services.AuthClient mail *services.MailClient - orm *ent.Client + db *models.Client *services.TemplateRenderer } @@ -73,7 +74,7 @@ func init() { func (h *Auth) Init(c *services.Container) error { h.TemplateRenderer = c.TemplateRenderer - h.orm = c.ORM + h.db = c.DB h.auth = c.Auth h.mail = c.Mail return nil @@ -92,7 +93,7 @@ func (h *Auth) Routes(g *echo.Group) { noAuth.POST("/password", h.ForgotPasswordSubmit).Name = routeNameForgotPasswordSubmit resetGroup := noAuth.Group("/password/reset", - middleware.LoadUser(h.orm), + middleware.LoadUser(h.db), middleware.LoadValidPasswordToken(h.auth), ) resetGroup.GET("/token/:user/:password_token/:token", h.ResetPasswordPage).Name = routeNameResetPassword @@ -129,16 +130,10 @@ func (h *Auth) ForgotPasswordSubmit(ctx echo.Context) error { } // Attempt to load the user - u, err := h.orm.User. - Query(). - Where(user.Email(strings.ToLower(input.Email))). - Only(ctx.Request().Context()) - - switch err.(type) { - case *ent.NotFoundError: + u, err := h.db.C.GetUserByEmail(ctx.Request().Context(), strings.ToLower(input.Email)) + if err == sql.ErrNoRows { return succeed() - case nil: - default: + } else if err != nil { return fail(err, "error querying user during forgot password") } @@ -198,16 +193,10 @@ func (h *Auth) LoginSubmit(ctx echo.Context) error { } // Attempt to load the user - u, err := h.orm.User. - Query(). - Where(user.Email(strings.ToLower(input.Email))). - Only(ctx.Request().Context()) - - switch err.(type) { - case *ent.NotFoundError: + u, err := h.db.C.GetUserByEmail(ctx.Request().Context(), strings.ToLower(input.Email)) + if err == sql.ErrNoRows { return authFailed() - case nil: - default: + } else if err != nil { return fail(err, "error querying user during login") } @@ -271,28 +260,27 @@ func (h *Auth) RegisterSubmit(ctx echo.Context) error { } // Attempt creating the user - u, err := h.orm.User. - Create(). - SetName(input.Name). - SetEmail(input.Email). - SetPassword(pwHash). - Save(ctx.Request().Context()) + u, err := h.db.C.CreateUser(ctx.Request().Context(), sqlc.CreateUserParams{ + Name: input.Name, + Email: input.Email, + Password: pwHash, + }) + if err != nil { + if strings.HasPrefix(err.Error(), "UNIQUE constraint failed") { + msg.Warning(ctx, "A user with this email address already exists. Please log in.") + return redirect.New(ctx). + Route(routeNameLogin). + Go() + } - switch err.(type) { - case nil: - log.Ctx(ctx).Info("user created", - "user_name", u.Name, - "user_id", u.ID, - ) - case *ent.ConstraintError: - msg.Warning(ctx, "A user with this email address already exists. Please log in.") - return redirect.New(ctx). - Route(routeNameLogin). - Go() - default: return fail(err, "unable to create user") } + log.Ctx(ctx).Info("user created", + "user_name", u.Name, + "user_id", u.ID, + ) + // Log the user in err = h.auth.Login(ctx, u.ID) if err != nil { @@ -316,7 +304,7 @@ func (h *Auth) RegisterSubmit(ctx echo.Context) error { Go() } -func (h *Auth) sendVerificationEmail(ctx echo.Context, usr *ent.User) { +func (h *Auth) sendVerificationEmail(ctx echo.Context, usr sqlc.User) { // Generate a token token, err := h.auth.GenerateEmailVerificationToken(usr.Email) if err != nil { @@ -376,13 +364,13 @@ func (h *Auth) ResetPasswordSubmit(ctx echo.Context) error { } // Get the requesting user - usr := ctx.Get(context.UserKey).(*ent.User) + usr := ctx.Get(context.UserKey).(*sqlc.User) // Update the user - _, err = usr. - Update(). - SetPassword(hash). - Save(ctx.Request().Context()) + err = h.db.C.UpdateUserPassword(ctx.Request().Context(), sqlc.UpdateUserPasswordParams{ + Password: hash, + ID: usr.ID, + }) if err != nil { return fail(err, "unable to update password") } @@ -400,9 +388,6 @@ func (h *Auth) ResetPasswordSubmit(ctx echo.Context) error { } func (h *Auth) VerifyEmail(ctx echo.Context) error { - var usr *ent.User - - // Validate the token token := ctx.Param("token") email, err := h.auth.ValidateEmailVerificationToken(token) if err != nil { @@ -412,35 +397,9 @@ func (h *Auth) VerifyEmail(ctx echo.Context) error { Go() } - // Check if it matches the authenticated user - if u := ctx.Get(context.AuthenticatedUserKey); u != nil { - authUser := u.(*ent.User) - - if authUser.Email == email { - usr = authUser - } - } - - // Query to find a matching user, if needed - if usr == nil { - usr, err = h.orm.User. - Query(). - Where(user.Email(email)). - Only(ctx.Request().Context()) - if err != nil { - return fail(err, "query failed loading email verification token user") - } - } - - // Verify the user, if needed - if !usr.Verified { - usr, err = usr. - Update(). - SetVerified(true). - Save(ctx.Request().Context()) - if err != nil { - return fail(err, "failed to set user as verified") - } + err = h.db.C.UpdateUserSetVerified(ctx.Request().Context(), email) + if err != nil { + return fail(err, "failed to set user as verified") } msg.Success(ctx, "Your email has been successfully verified.") diff --git a/pkg/middleware/auth.go b/pkg/middleware/auth.go index 91e50d2..f36126b 100644 --- a/pkg/middleware/auth.go +++ b/pkg/middleware/auth.go @@ -1,15 +1,15 @@ package middleware import ( + "errors" "fmt" "net/http" "strconv" "github.com/labstack/echo/v4" - "git.grosinger.net/tgrosinger/saasitone/ent" "git.grosinger.net/tgrosinger/saasitone/pkg/context" - "git.grosinger.net/tgrosinger/saasitone/pkg/log" + "git.grosinger.net/tgrosinger/saasitone/pkg/models/sqlc" "git.grosinger.net/tgrosinger/saasitone/pkg/msg" "git.grosinger.net/tgrosinger/saasitone/pkg/services" ) @@ -19,17 +19,13 @@ func LoadAuthenticatedUser(authClient *services.AuthClient) echo.MiddlewareFunc return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { u, err := authClient.GetAuthenticatedUser(c) - switch err.(type) { - case *ent.NotFoundError: - log.Ctx(c).Warn("auth user not found") - case services.NotAuthenticatedError: - case nil: - c.Set(context.AuthenticatedUserKey, u) - default: + if err != nil && !errors.Is(err, services.NotAuthenticatedError{}) { return echo.NewHTTPError( http.StatusInternalServerError, fmt.Sprintf("error querying for authenticated user: %v", err), ) + } else if u != nil { + c.Set(context.AuthenticatedUserKey, u) } return next(c) @@ -48,7 +44,7 @@ func LoadValidPasswordToken(authClient *services.AuthClient) echo.MiddlewareFunc if c.Get(context.UserKey) == nil { return echo.NewHTTPError(http.StatusInternalServerError) } - usr := c.Get(context.UserKey).(*ent.User) + usr := c.Get(context.UserKey).(*sqlc.User) // Extract the token ID tokenID, err := strconv.Atoi(c.Param("password_token")) diff --git a/pkg/middleware/auth_test.go b/pkg/middleware/auth_test.go index 7999a2b..495c0f7 100644 --- a/pkg/middleware/auth_test.go +++ b/pkg/middleware/auth_test.go @@ -8,9 +8,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "git.grosinger.net/tgrosinger/saasitone/ent" "git.grosinger.net/tgrosinger/saasitone/pkg/context" "git.grosinger.net/tgrosinger/saasitone/pkg/tests" + "git.grosinger.net/tgrosinger/saasitone/pkg/models/sqlc" ) func TestLoadAuthenticatedUser(t *testing.T) { @@ -29,7 +29,7 @@ func TestLoadAuthenticatedUser(t *testing.T) { // Verify the midldeware returns the authenticated user _ = tests.ExecuteMiddleware(ctx, mw) require.NotNil(t, ctx.Get(context.AuthenticatedUserKey)) - ctxUsr, ok := ctx.Get(context.AuthenticatedUserKey).(*ent.User) + ctxUsr, ok := ctx.Get(context.AuthenticatedUserKey).(*sqlc.User) require.True(t, ok) assert.Equal(t, usr.ID, ctxUsr.ID) } @@ -81,7 +81,7 @@ func TestLoadValidPasswordToken(t *testing.T) { // Add user and password token context but no token and expect a redirect ctx.SetParamNames("user", "password_token") ctx.SetParamValues(fmt.Sprintf("%d", usr.ID), "1") - _ = tests.ExecuteMiddleware(ctx, LoadUser(c.ORM)) + _ = tests.ExecuteMiddleware(ctx, LoadUser(c.DB)) err = tests.ExecuteMiddleware(ctx, LoadValidPasswordToken(c.Auth)) assert.NoError(t, err) assert.Equal(t, http.StatusFound, ctx.Response().Status) @@ -89,7 +89,7 @@ func TestLoadValidPasswordToken(t *testing.T) { // Add user context and invalid password token and expect a redirect ctx.SetParamNames("user", "password_token", "token") ctx.SetParamValues(fmt.Sprintf("%d", usr.ID), "1", "faketoken") - _ = tests.ExecuteMiddleware(ctx, LoadUser(c.ORM)) + _ = tests.ExecuteMiddleware(ctx, LoadUser(c.DB)) err = tests.ExecuteMiddleware(ctx, LoadValidPasswordToken(c.Auth)) assert.NoError(t, err) assert.Equal(t, http.StatusFound, ctx.Response().Status) @@ -101,10 +101,10 @@ func TestLoadValidPasswordToken(t *testing.T) { // Add user and valid password token ctx.SetParamNames("user", "password_token", "token") ctx.SetParamValues(fmt.Sprintf("%d", usr.ID), fmt.Sprintf("%d", pt.ID), token) - _ = tests.ExecuteMiddleware(ctx, LoadUser(c.ORM)) + _ = tests.ExecuteMiddleware(ctx, LoadUser(c.DB)) err = tests.ExecuteMiddleware(ctx, LoadValidPasswordToken(c.Auth)) assert.Nil(t, err) - ctxPt, ok := ctx.Get(context.PasswordTokenKey).(*ent.PasswordToken) + ctxPt, ok := ctx.Get(context.PasswordTokenKey).(*sqlc.PasswordToken) require.True(t, ok) assert.Equal(t, pt.ID, ctxPt.ID) } diff --git a/pkg/middleware/entity.go b/pkg/middleware/entity.go index b89fb2b..2490956 100644 --- a/pkg/middleware/entity.go +++ b/pkg/middleware/entity.go @@ -1,19 +1,19 @@ package middleware import ( + "database/sql" "fmt" "net/http" "strconv" "github.com/labstack/echo/v4" - "git.grosinger.net/tgrosinger/saasitone/ent" - "git.grosinger.net/tgrosinger/saasitone/ent/user" "git.grosinger.net/tgrosinger/saasitone/pkg/context" + "git.grosinger.net/tgrosinger/saasitone/pkg/models" ) // LoadUser loads the user based on the ID provided as a path parameter -func LoadUser(orm *ent.Client) echo.MiddlewareFunc { +func LoadUser(db *models.Client) echo.MiddlewareFunc { return func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error { userID, err := strconv.Atoi(c.Param("user")) @@ -21,23 +21,20 @@ func LoadUser(orm *ent.Client) echo.MiddlewareFunc { return echo.NewHTTPError(http.StatusNotFound) } - u, err := orm.User. - Query(). - Where(user.ID(userID)). - Only(c.Request().Context()) - - switch err.(type) { - case nil: - c.Set(context.UserKey, u) + u, err := db.C.GetUserByID(c.Request().Context(), userID) + if err == nil { + c.Set(context.UserKey, &u) return next(c) - case *ent.NotFoundError: - return echo.NewHTTPError(http.StatusNotFound) - default: - return echo.NewHTTPError( - http.StatusInternalServerError, - fmt.Sprintf("error querying user: %v", err), - ) } + + if err == sql.ErrNoRows { + return echo.NewHTTPError(http.StatusNotFound) + } + + return echo.NewHTTPError( + http.StatusInternalServerError, + fmt.Sprintf("error querying user: %v", err), + ) } } } diff --git a/pkg/middleware/entity_test.go b/pkg/middleware/entity_test.go index 7cf0b9b..af6aa32 100644 --- a/pkg/middleware/entity_test.go +++ b/pkg/middleware/entity_test.go @@ -7,17 +7,17 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "git.grosinger.net/tgrosinger/saasitone/ent" "git.grosinger.net/tgrosinger/saasitone/pkg/context" "git.grosinger.net/tgrosinger/saasitone/pkg/tests" + "git.grosinger.net/tgrosinger/saasitone/pkg/models/sqlc" ) func TestLoadUser(t *testing.T) { ctx, _ := tests.NewContext(c.Web, "/") ctx.SetParamNames("user") ctx.SetParamValues(fmt.Sprintf("%d", usr.ID)) - _ = tests.ExecuteMiddleware(ctx, LoadUser(c.ORM)) - ctxUsr, ok := ctx.Get(context.UserKey).(*ent.User) + _ = tests.ExecuteMiddleware(ctx, LoadUser(c.DB)) + ctxUsr, ok := ctx.Get(context.UserKey).(*sqlc.User) require.True(t, ok) assert.Equal(t, usr.ID, ctxUsr.ID) } diff --git a/pkg/middleware/middleware_test.go b/pkg/middleware/middleware_test.go index 213b4df..5a0e259 100644 --- a/pkg/middleware/middleware_test.go +++ b/pkg/middleware/middleware_test.go @@ -5,14 +5,14 @@ import ( "testing" "git.grosinger.net/tgrosinger/saasitone/config" - "git.grosinger.net/tgrosinger/saasitone/ent" + "git.grosinger.net/tgrosinger/saasitone/pkg/models/sqlc" "git.grosinger.net/tgrosinger/saasitone/pkg/services" "git.grosinger.net/tgrosinger/saasitone/pkg/tests" ) var ( c *services.Container - usr *ent.User + usr *sqlc.User ) func TestMain(m *testing.M) { @@ -24,7 +24,7 @@ func TestMain(m *testing.M) { // Create a user var err error - if usr, err = tests.CreateUser(c.ORM); err != nil { + if usr, err = tests.CreateUser(c.DB); err != nil { panic(err) } diff --git a/pkg/models/db.go b/pkg/models/db.go new file mode 100644 index 0000000..8f2f15b --- /dev/null +++ b/pkg/models/db.go @@ -0,0 +1,119 @@ +package models + +import ( + "database/sql" + "fmt" + "log/slog" + + "github.com/golang-migrate/migrate/v4" + "github.com/golang-migrate/migrate/v4/database/sqlite3" + "github.com/golang-migrate/migrate/v4/source/file" + + "git.grosinger.net/tgrosinger/saasitone/config" + "git.grosinger.net/tgrosinger/saasitone/pkg/models/sqlc" +) + +// TODO: Move this into services and have DBClient and NewDBClient + +type Client struct { + db *sql.DB + C *sqlc.Queries + + User *UserClient +} + +func New(cfg *config.Config) (*Client, error) { + logger := slog.Default() + + dbFilepath := cfg.Storage.DatabaseFile + if cfg.App.Environment == config.EnvTest { + // In memory only + dbFilepath = ":memory:" + } + + logger.Info("Opening database file", + "filepath", dbFilepath) + + fn := fmt.Sprintf("file:%s?_fk=1&_journal=WAL&cache=shared&_busy_timeout=5000", dbFilepath) + db, err := sql.Open("sqlite3", fn) + if err != nil { + return nil, err + } + + client := Client{ + db: db, + C: sqlc.New(db), + } + client.User = &UserClient{db: db} + + migrationsDirPath := cfg.Storage.MigrationsDir + logger.Info("Loading schema migrations", + "filepath", migrationsDirPath) + err = client.initSchema(migrationsDirPath) + if err != nil { + return nil, err + } + + return &client, nil +} + +// initSchema ensures that the database is current with the migrations contained +// in db/migrations. +func (c *Client) initSchema(migrationsDir string) error { + driver, err := sqlite3.WithInstance(c.db, &sqlite3.Config{}) + if err != nil { + return err + } + + fSrc, err := (&file.File{}).Open(migrationsDir) + if err != nil { + fmt.Println("Got here 2: " + migrationsDir) + return err + } + + m, err := migrate.NewWithInstance("file", fSrc, "sqlite", driver) + if err != nil { + return err + } + + err = m.Up() + if err == migrate.ErrNoChange { + return nil + } + return err +} + +// WithTx executes the provided callback with access to a database transaction. +// If the callback returns an error the transaction will be rolled back. +func (c *Client) WithTx(fn func(tx *sql.Tx) error) error { + tx, err := c.db.Begin() + if err != nil { + return err + } + + err = fn(tx) + if err != nil { + _ = tx.Rollback() + return err + } + + return tx.Commit() +} + +func (c *Client) WithSqlcTx(fn func(*sqlc.Queries) error) error { + return c.WithTx( + func(tx *sql.Tx) error { + return fn(c.C.WithTx(tx)) + }, + ) +} + +// DB returns the underlying database object. Avoid whenever possible and use +// either sqlc (preferred) or sub-clients. +func (c *Client) DB() *sql.DB { + return c.db +} + +func (c *Client) Close() error { + return c.db.Close() +} diff --git a/pkg/models/sqlc/db.go b/pkg/models/sqlc/db.go new file mode 100644 index 0000000..8ed64d1 --- /dev/null +++ b/pkg/models/sqlc/db.go @@ -0,0 +1,31 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.25.0 + +package sqlc + +import ( + "context" + "database/sql" +) + +type DBTX interface { + ExecContext(context.Context, string, ...interface{}) (sql.Result, error) + PrepareContext(context.Context, string) (*sql.Stmt, error) + QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error) + QueryRowContext(context.Context, string, ...interface{}) *sql.Row +} + +func New(db DBTX) *Queries { + return &Queries{db: db} +} + +type Queries struct { + db DBTX +} + +func (q *Queries) WithTx(tx *sql.Tx) *Queries { + return &Queries{ + db: tx, + } +} diff --git a/pkg/models/sqlc/models.go b/pkg/models/sqlc/models.go new file mode 100644 index 0000000..1af994a --- /dev/null +++ b/pkg/models/sqlc/models.go @@ -0,0 +1,25 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.25.0 + +package sqlc + +import ( + "git.grosinger.net/tgrosinger/saasitone/pkg/db" +) + +type PasswordToken struct { + ID int `db:"id"` + Hash string `db:"hash"` + CreatedAt db.Time `db:"created_at"` + PasswordTokenUser int `db:"password_token_user"` +} + +type User struct { + ID int `db:"id"` + Name string `db:"name"` + Email string `db:"email"` + Password string `db:"password"` + Verified int `db:"verified"` + CreatedAt db.Time `db:"created_at"` +} diff --git a/pkg/models/sqlc/password_tokens.sql.go b/pkg/models/sqlc/password_tokens.sql.go new file mode 100644 index 0000000..c627923 --- /dev/null +++ b/pkg/models/sqlc/password_tokens.sql.go @@ -0,0 +1,126 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.25.0 +// source: password_tokens.sql + +package sqlc + +import ( + "context" + + "git.grosinger.net/tgrosinger/saasitone/pkg/db" +) + +const createPasswordToken = `-- name: CreatePasswordToken :one +INSERT INTO password_tokens ( + hash, password_token_user +) VALUES ( + ?, ? +) RETURNING id, hash, created_at, password_token_user +` + +type CreatePasswordTokenParams struct { + Hash string `db:"hash"` + PasswordTokenUser int `db:"password_token_user"` +} + +func (q *Queries) CreatePasswordToken(ctx context.Context, arg CreatePasswordTokenParams) (PasswordToken, error) { + row := q.db.QueryRowContext(ctx, createPasswordToken, arg.Hash, arg.PasswordTokenUser) + var i PasswordToken + err := row.Scan( + &i.ID, + &i.Hash, + &i.CreatedAt, + &i.PasswordTokenUser, + ) + return i, err +} + +const deletePasswordTokens = `-- name: DeletePasswordTokens :exec +DELETE FROM password_tokens +WHERE password_token_user = ? +` + +func (q *Queries) DeletePasswordTokens(ctx context.Context, passwordTokenUser int) error { + _, err := q.db.ExecContext(ctx, deletePasswordTokens, passwordTokenUser) + return err +} + +const getAllPasswordTokensForUser = `-- name: GetAllPasswordTokensForUser :many +SELECT id, hash, created_at, password_token_user FROM password_tokens +WHERE password_token_user = ? +` + +// GetAllPasswordTokensForUser retrieves all password tokens without checking expiration. +func (q *Queries) GetAllPasswordTokensForUser(ctx context.Context, passwordTokenUser int) ([]PasswordToken, error) { + rows, err := q.db.QueryContext(ctx, getAllPasswordTokensForUser, passwordTokenUser) + if err != nil { + return nil, err + } + defer rows.Close() + var items []PasswordToken + for rows.Next() { + var i PasswordToken + if err := rows.Scan( + &i.ID, + &i.Hash, + &i.CreatedAt, + &i.PasswordTokenUser, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getValidPasswordToken = `-- name: GetValidPasswordToken :one +SELECT id, hash, created_at, password_token_user FROM password_tokens +WHERE + id = ? + AND password_token_user = ? + AND datetime(created_at) > datetime(?) +LIMIT 1 +` + +type GetValidPasswordTokenParams struct { + ID int `db:"id"` + PasswordTokenUser int `db:"password_token_user"` + Datetime interface{} `db:"datetime"` +} + +// GetValidPasswordToken returns only valid password tokens for the provided +// user, and only if the created_at time is greater than the provided time. +func (q *Queries) GetValidPasswordToken(ctx context.Context, arg GetValidPasswordTokenParams) (PasswordToken, error) { + row := q.db.QueryRowContext(ctx, getValidPasswordToken, arg.ID, arg.PasswordTokenUser, arg.Datetime) + var i PasswordToken + err := row.Scan( + &i.ID, + &i.Hash, + &i.CreatedAt, + &i.PasswordTokenUser, + ) + return i, err +} + +const updatePasswordTokenCreatedAt = `-- name: UpdatePasswordTokenCreatedAt :exec +UPDATE password_tokens +SET created_at = ? +WHERE id = ? +` + +type UpdatePasswordTokenCreatedAtParams struct { + CreatedAt db.Time `db:"created_at"` + ID int `db:"id"` +} + +func (q *Queries) UpdatePasswordTokenCreatedAt(ctx context.Context, arg UpdatePasswordTokenCreatedAtParams) error { + _, err := q.db.ExecContext(ctx, updatePasswordTokenCreatedAt, arg.CreatedAt, arg.ID) + return err +} diff --git a/pkg/models/sqlc/users.sql.go b/pkg/models/sqlc/users.sql.go new file mode 100644 index 0000000..9889fa9 --- /dev/null +++ b/pkg/models/sqlc/users.sql.go @@ -0,0 +1,105 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.25.0 +// source: users.sql + +package sqlc + +import ( + "context" +) + +const createUser = `-- name: CreateUser :one +INSERT INTO users ( + name, email, password +) VALUES ( + ?, ?, ? +) RETURNING id, name, email, password, verified, created_at +` + +type CreateUserParams struct { + Name string `db:"name"` + Email string `db:"email"` + Password string `db:"password"` +} + +func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) (User, error) { + row := q.db.QueryRowContext(ctx, createUser, arg.Name, arg.Email, arg.Password) + var i User + err := row.Scan( + &i.ID, + &i.Name, + &i.Email, + &i.Password, + &i.Verified, + &i.CreatedAt, + ) + return i, err +} + +const getUserByEmail = `-- name: GetUserByEmail :one +SELECT id, name, email, password, verified, created_at FROM users +WHERE email = lower(?) +LIMIT 1 +` + +func (q *Queries) GetUserByEmail(ctx context.Context, lower string) (User, error) { + row := q.db.QueryRowContext(ctx, getUserByEmail, lower) + var i User + err := row.Scan( + &i.ID, + &i.Name, + &i.Email, + &i.Password, + &i.Verified, + &i.CreatedAt, + ) + return i, err +} + +const getUserByID = `-- name: GetUserByID :one +SELECT id, name, email, password, verified, created_at FROM users +WHERE id = ? +LIMIT 1 +` + +func (q *Queries) GetUserByID(ctx context.Context, id int) (User, error) { + row := q.db.QueryRowContext(ctx, getUserByID, id) + var i User + err := row.Scan( + &i.ID, + &i.Name, + &i.Email, + &i.Password, + &i.Verified, + &i.CreatedAt, + ) + return i, err +} + +const updateUserPassword = `-- name: UpdateUserPassword :exec +UPDATE users +SET password = ? +WHERE id = ? +` + +type UpdateUserPasswordParams struct { + Password string `db:"password"` + ID int `db:"id"` +} + +func (q *Queries) UpdateUserPassword(ctx context.Context, arg UpdateUserPasswordParams) error { + _, err := q.db.ExecContext(ctx, updateUserPassword, arg.Password, arg.ID) + return err +} + +const updateUserSetVerified = `-- name: UpdateUserSetVerified :exec +UPDATE users +SET verified = 1 +WHERE email = ? +` + +func (q *Queries) UpdateUserSetVerified(ctx context.Context, email string) error { + _, err := q.db.ExecContext(ctx, updateUserSetVerified, email) + return err +} diff --git a/pkg/models/users.go b/pkg/models/users.go new file mode 100644 index 0000000..aa4edd1 --- /dev/null +++ b/pkg/models/users.go @@ -0,0 +1,9 @@ +package models + +import "database/sql" + +// UserClient is a struct that can be used to create custom methods for +// interacting with users in the database. +type UserClient struct { + db *sql.DB +} diff --git a/pkg/page/page.go b/pkg/page/page.go index 3f2b7e7..7252de2 100644 --- a/pkg/page/page.go +++ b/pkg/page/page.go @@ -8,9 +8,9 @@ import ( "github.com/labstack/echo/v4" echomw "github.com/labstack/echo/v4/middleware" - "git.grosinger.net/tgrosinger/saasitone/ent" "git.grosinger.net/tgrosinger/saasitone/pkg/context" "git.grosinger.net/tgrosinger/saasitone/pkg/htmx" + "git.grosinger.net/tgrosinger/saasitone/pkg/models/sqlc" "git.grosinger.net/tgrosinger/saasitone/pkg/msg" "git.grosinger.net/tgrosinger/saasitone/templates" ) @@ -67,7 +67,7 @@ type Page struct { IsAuth bool // AuthUser stores the authenticated user - AuthUser *ent.User + AuthUser *sqlc.User // StatusCode stores the HTTP status code that will be returned StatusCode int @@ -141,7 +141,7 @@ func New(ctx echo.Context) Page { if u := ctx.Get(context.AuthenticatedUserKey); u != nil { p.IsAuth = true - p.AuthUser = u.(*ent.User) + p.AuthUser = u.(*sqlc.User) } p.HTMX.Request = htmx.GetRequest(ctx) diff --git a/pkg/page/page_test.go b/pkg/page/page_test.go index e7bf6c3..bd31fdf 100644 --- a/pkg/page/page_test.go +++ b/pkg/page/page_test.go @@ -8,8 +8,8 @@ import ( echomw "github.com/labstack/echo/v4/middleware" "github.com/stretchr/testify/assert" - "git.grosinger.net/tgrosinger/saasitone/ent" "git.grosinger.net/tgrosinger/saasitone/pkg/context" + "git.grosinger.net/tgrosinger/saasitone/pkg/models/sqlc" "git.grosinger.net/tgrosinger/saasitone/pkg/msg" "git.grosinger.net/tgrosinger/saasitone/pkg/tests" ) @@ -31,7 +31,7 @@ func TestNew(t *testing.T) { assert.False(t, p.Cache.Enabled) ctx, _ = tests.NewContext(e, "/abc?def=123") - usr := &ent.User{ + usr := &sqlc.User{ ID: 1, } ctx.Set(context.AuthenticatedUserKey, usr) diff --git a/pkg/services/auth.go b/pkg/services/auth.go index 7d5dc09..43ac89e 100644 --- a/pkg/services/auth.go +++ b/pkg/services/auth.go @@ -2,6 +2,7 @@ package services import ( "crypto/rand" + "database/sql" "encoding/hex" "errors" "fmt" @@ -12,10 +13,8 @@ import ( "golang.org/x/crypto/bcrypt" "git.grosinger.net/tgrosinger/saasitone/config" - "git.grosinger.net/tgrosinger/saasitone/ent" - "git.grosinger.net/tgrosinger/saasitone/ent/passwordtoken" - "git.grosinger.net/tgrosinger/saasitone/ent/user" - "git.grosinger.net/tgrosinger/saasitone/pkg/context" + "git.grosinger.net/tgrosinger/saasitone/pkg/models" + "git.grosinger.net/tgrosinger/saasitone/pkg/models/sqlc" "git.grosinger.net/tgrosinger/saasitone/pkg/session" ) @@ -49,14 +48,14 @@ func (e InvalidPasswordTokenError) Error() string { // AuthClient is the client that handles authentication requests type AuthClient struct { config *config.Config - orm *ent.Client + db *models.Client } // NewAuthClient creates a new authentication client -func NewAuthClient(cfg *config.Config, orm *ent.Client) *AuthClient { +func NewAuthClient(cfg *config.Config, db *models.Client) *AuthClient { return &AuthClient{ config: cfg, - orm: orm, + db: db, } } @@ -96,11 +95,13 @@ func (c *AuthClient) GetAuthenticatedUserID(ctx echo.Context) (int, error) { } // GetAuthenticatedUser returns the authenticated user if the user is logged in -func (c *AuthClient) GetAuthenticatedUser(ctx echo.Context) (*ent.User, error) { +func (c *AuthClient) GetAuthenticatedUser(ctx echo.Context) (*sqlc.User, error) { if userID, err := c.GetAuthenticatedUserID(ctx); err == nil { - return c.orm.User.Query(). - Where(user.ID(userID)). - Only(ctx.Request().Context()) + u, err := c.db.C.GetUserByID(ctx.Request().Context(), userID) + if err != nil { + return nil, err + } + return &u, nil } return nil, NotAuthenticatedError{} @@ -124,25 +125,24 @@ func (c *AuthClient) CheckPassword(password, hash string) error { // For security purposes, the token itself is not stored in the database but rather // a hash of the token, exactly how passwords are handled. This method returns both // the generated token as well as the token entity which only contains the hash. -func (c *AuthClient) GeneratePasswordResetToken(ctx echo.Context, userID int) (string, *ent.PasswordToken, error) { +func (c *AuthClient) GeneratePasswordResetToken(ctx echo.Context, userID int) (string, sqlc.PasswordToken, error) { // Generate the token, which is what will go in the URL, but not the database token, err := c.RandomToken(c.config.App.PasswordToken.Length) if err != nil { - return "", nil, err + return "", sqlc.PasswordToken{}, err } // Hash the token, which is what will be stored in the database hash, err := c.HashPassword(token) if err != nil { - return "", nil, err + return "", sqlc.PasswordToken{}, err } // Create and save the password reset token - pt, err := c.orm.PasswordToken. - Create(). - SetHash(hash). - SetUserID(userID). - Save(ctx.Request().Context()) + pt, err := c.db.C.CreatePasswordToken(ctx.Request().Context(), sqlc.CreatePasswordTokenParams{ + Hash: hash, + PasswordTokenUser: userID, + }) return token, pt, err } @@ -150,43 +150,35 @@ func (c *AuthClient) GeneratePasswordResetToken(ctx echo.Context, userID int) (s // GetValidPasswordToken returns a valid, non-expired password token entity for a given user, token ID and token. // Since the actual token is not stored in the database for security purposes, if a matching password token entity is // found a hash of the provided token is compared with the hash stored in the database in order to validate. -func (c *AuthClient) GetValidPasswordToken(ctx echo.Context, userID, tokenID int, token string) (*ent.PasswordToken, error) { +func (c *AuthClient) GetValidPasswordToken(ctx echo.Context, userID, tokenID int, token string) (*sqlc.PasswordToken, error) { // Ensure expired tokens are never returned expiration := time.Now().Add(-c.config.App.PasswordToken.Expiration) // Query to find a password token entity that matches the given user and token ID - pt, err := c.orm.PasswordToken. - Query(). - Where(passwordtoken.ID(tokenID)). - Where(passwordtoken.HasUserWith(user.ID(userID))). - Where(passwordtoken.CreatedAtGTE(expiration)). - Only(ctx.Request().Context()) + pt, err := c.db.C.GetValidPasswordToken(ctx.Request().Context(), + sqlc.GetValidPasswordTokenParams{ + ID: tokenID, + PasswordTokenUser: userID, + Datetime: expiration, + }) - switch err.(type) { - case *ent.NotFoundError: - case nil: - // Check the token for a hash match - if err := c.CheckPassword(token, pt.Hash); err == nil { - return pt, nil - } - default: - if !context.IsCanceledError(err) { - return nil, err - } + if err == sql.ErrNoRows { + return nil, InvalidPasswordTokenError{} + } else if err != nil { + return nil, err } + // Check the token for a hash match + if err := c.CheckPassword(token, pt.Hash); err == nil { + return &pt, nil + } return nil, InvalidPasswordTokenError{} } // DeletePasswordTokens deletes all password tokens in the database for a belonging to a given user. // This should be called after a successful password reset. func (c *AuthClient) DeletePasswordTokens(ctx echo.Context, userID int) error { - _, err := c.orm.PasswordToken. - Delete(). - Where(passwordtoken.HasUserWith(user.ID(userID))). - Exec(ctx.Request().Context()) - - return err + return c.db.C.DeletePasswordTokens(ctx.Request().Context(), userID) } // RandomToken generates a random token string of a given length diff --git a/pkg/services/auth_test.go b/pkg/services/auth_test.go index b91c518..a32271e 100644 --- a/pkg/services/auth_test.go +++ b/pkg/services/auth_test.go @@ -9,8 +9,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "git.grosinger.net/tgrosinger/saasitone/ent/passwordtoken" - "git.grosinger.net/tgrosinger/saasitone/ent/user" + "git.grosinger.net/tgrosinger/saasitone/pkg/models/sqlc" + "git.grosinger.net/tgrosinger/saasitone/pkg/db" ) func TestAuthClient_Auth(t *testing.T) { @@ -69,13 +69,11 @@ func TestAuthClient_GetValidPasswordToken(t *testing.T) { assert.Equal(t, pt.ID, pt2.ID) // Expire the token by pushing the date far enough back - count, err := c.ORM.PasswordToken. - Update(). - SetCreatedAt(time.Now().Add(-(c.Config.App.PasswordToken.Expiration + time.Hour))). - Where(passwordtoken.ID(pt.ID)). - Save(context.Background()) + err = c.DB.C.UpdatePasswordTokenCreatedAt(context.Background(), sqlc.UpdatePasswordTokenCreatedAtParams{ + CreatedAt: db.Time{Time: time.Now().Add(-(c.Config.App.PasswordToken.Expiration + time.Hour))}, + ID: pt.ID, + }) require.NoError(t, err) - require.Equal(t, 1, count) // Expired tokens should not be valid _, err = c.Auth.GetValidPasswordToken(ctx, usr.ID, pt.ID, token) @@ -94,13 +92,9 @@ func TestAuthClient_DeletePasswordTokens(t *testing.T) { require.NoError(t, err) // Check that no tokens remain - count, err := c.ORM.PasswordToken. - Query(). - Where(passwordtoken.HasUserWith(user.ID(usr.ID))). - Count(context.Background()) - + tokens, err := c.DB.C.GetAllPasswordTokensForUser(context.Background(), usr.ID) require.NoError(t, err) - assert.Equal(t, 0, count) + assert.Len(t, tokens, 0) } func TestAuthClient_RandomToken(t *testing.T) { diff --git a/pkg/services/container.go b/pkg/services/container.go index 56cc9b5..a5a8f78 100644 --- a/pkg/services/container.go +++ b/pkg/services/container.go @@ -1,21 +1,15 @@ package services import ( - "context" - "database/sql" "fmt" "log/slog" - "os" - "strings" - entsql "entgo.io/ent/dialect/sql" "github.com/labstack/echo/v4" _ "github.com/mattn/go-sqlite3" "git.grosinger.net/tgrosinger/saasitone/config" - "git.grosinger.net/tgrosinger/saasitone/ent" - _ "git.grosinger.net/tgrosinger/saasitone/ent/runtime" // Require by ent "git.grosinger.net/tgrosinger/saasitone/pkg/funcmap" + "git.grosinger.net/tgrosinger/saasitone/pkg/models" ) // Container contains all services used by the application and provides an easy way to handle dependency @@ -33,11 +27,8 @@ type Container struct { // Cache contains the cache client Cache *CacheClient - // Database stores the connection to the database - Database *sql.DB - - // ORM stores a client to the ORM - ORM *ent.Client + // DB is the connection to the database and models for interacting with it + DB *models.Client // Mail stores an email sending client Mail *MailClient @@ -60,7 +51,6 @@ func NewContainer() *Container { c.initWeb() c.initCache() c.initDatabase() - c.initORM() c.initAuth() c.initTemplateRenderer() c.initMail() @@ -71,10 +61,7 @@ func NewContainer() *Container { // Shutdown shuts the Container down and disconnects all connections. // If the task runner was started, cancel the context to shut it down prior to calling this. func (c *Container) Shutdown() error { - if err := c.ORM.Close(); err != nil { - return err - } - if err := c.Database.Close(); err != nil { + if err := c.DB.Close(); err != nil { return err } c.Cache.Close() @@ -123,37 +110,17 @@ func (c *Container) initCache() { // initDatabase initializes the database func (c *Container) initDatabase() { - var err error - var connection string - - switch c.Config.App.Environment { - case config.EnvTest: - // TODO: Drop/recreate the DB, if this isn't in memory? - connection = c.Config.Database.TestConnection - default: - connection = c.Config.Database.Connection - } - - c.Database, err = openDB(c.Config.Database.Driver, connection) + client, err := models.New(c.Config) if err != nil { panic(err) } -} -// initORM initializes the ORM -func (c *Container) initORM() { - drv := entsql.OpenDB(c.Config.Database.Driver, c.Database) - c.ORM = ent.NewClient(ent.Driver(drv)) - - // Run the auto migration tool. - if err := c.ORM.Schema.Create(context.Background()); err != nil { - panic(err) - } + c.DB = client } // initAuth initializes the authentication client func (c *Container) initAuth() { - c.Auth = NewAuthClient(c.Config, c.ORM) + c.Auth = NewAuthClient(c.Config, c.DB) } // initTemplateRenderer initializes the template renderer @@ -175,27 +142,8 @@ func (c *Container) initTasks() { var err error // You could use a separate database for tasks, if you'd like. but using one // makes transaction support easier - c.Tasks, err = NewTaskClient(c.Config.Tasks, c.Database) + c.Tasks, err = NewTaskClient(c.Config.Tasks, c.DB.DB()) if err != nil { panic(fmt.Sprintf("failed to create task client: %v", err)) } } - -// openDB opens a database connection -func openDB(driver, connection string) (*sql.DB, error) { - // Helper to automatically create the directories that the specified sqlite file - // should reside in, if one - if driver == "sqlite3" { - d := strings.Split(connection, "/") - - if len(d) > 1 { - path := strings.Join(d[:len(d)-1], "/") - - if err := os.MkdirAll(path, 0755); err != nil { - return nil, err - } - } - } - - return sql.Open(driver, connection) -} diff --git a/pkg/services/container_test.go b/pkg/services/container_test.go index bfe4cc3..592c9c4 100644 --- a/pkg/services/container_test.go +++ b/pkg/services/container_test.go @@ -11,8 +11,7 @@ func TestNewContainer(t *testing.T) { assert.NotNil(t, c.Config) assert.NotNil(t, c.Validator) assert.NotNil(t, c.Cache) - assert.NotNil(t, c.Database) - assert.NotNil(t, c.ORM) + assert.NotNil(t, c.DB) assert.NotNil(t, c.Mail) assert.NotNil(t, c.Auth) assert.NotNil(t, c.TemplateRenderer) diff --git a/pkg/services/services_test.go b/pkg/services/services_test.go index 45c9ed4..2dbb259 100644 --- a/pkg/services/services_test.go +++ b/pkg/services/services_test.go @@ -7,14 +7,14 @@ import ( "github.com/labstack/echo/v4" "git.grosinger.net/tgrosinger/saasitone/config" - "git.grosinger.net/tgrosinger/saasitone/ent" + "git.grosinger.net/tgrosinger/saasitone/pkg/models/sqlc" "git.grosinger.net/tgrosinger/saasitone/pkg/tests" ) var ( c *Container ctx echo.Context - usr *ent.User + usr *sqlc.User ) func TestMain(m *testing.M) { @@ -30,7 +30,7 @@ func TestMain(m *testing.M) { // Create a test user var err error - if usr, err = tests.CreateUser(c.ORM); err != nil { + if usr, err = tests.CreateUser(c.DB); err != nil { panic(err) } diff --git a/pkg/tests/tests.go b/pkg/tests/tests.go index 27ab923..cf570f5 100644 --- a/pkg/tests/tests.go +++ b/pkg/tests/tests.go @@ -16,7 +16,8 @@ import ( "github.com/gorilla/sessions" "github.com/labstack/echo/v4" - "git.grosinger.net/tgrosinger/saasitone/ent" + "git.grosinger.net/tgrosinger/saasitone/pkg/models" + "git.grosinger.net/tgrosinger/saasitone/pkg/models/sqlc" "git.grosinger.net/tgrosinger/saasitone/pkg/session" ) @@ -63,12 +64,17 @@ func AssertHTTPErrorCode(t *testing.T, err error, code int) { } // CreateUser creates a random user entity -func CreateUser(orm *ent.Client) (*ent.User, error) { +func CreateUser(db *models.Client) (*sqlc.User, error) { seed := fmt.Sprintf("%d-%d", time.Now().UnixMilli(), rand.Intn(1000000)) - return orm.User. - Create(). - SetEmail(fmt.Sprintf("testuser-%s@localhost.localhost", seed)). - SetPassword("password"). - SetName(fmt.Sprintf("Test User %s", seed)). - Save(context.Background()) + + usr, err := db.C.CreateUser(context.Background(), sqlc.CreateUserParams{ + Name: fmt.Sprintf("Test User %s", seed), + Email: fmt.Sprintf("testuser-%s@localhost.localhost", seed), + Password: "password", + }) + if err != nil { + return nil, err + } + + return &usr, nil } diff --git a/sqlc.yaml b/sqlc.yaml new file mode 100644 index 0000000..5ae5d92 --- /dev/null +++ b/sqlc.yaml @@ -0,0 +1,29 @@ +version: "2" +sql: + - engine: "sqlite" + schema: "db/migrations" + queries: "db/queries" + gen: + go: + out: "pkg/models/sqlc" + emit_db_tags: true +overrides: + go: + overrides: + - db_type: "integer" + go_type: + type: "int" + - db_type: "integer" + go_type: + type: "NullInt" + import: "git.grosinger.net/tgrosinger/sassitone/pkg/conv" + nullable: true + - column: "main.password_tokens.created_at" + go_type: + type: "Time" + import: "git.grosinger.net/tgrosinger/saasitone/pkg/db" + - column: "main.users.created_at" + go_type: + type: "Time" + import: "git.grosinger.net/tgrosinger/saasitone/pkg/db" +