mirror of
https://github.com/sysadminsmedia/homebox.git
synced 2025-12-24 22:39:14 +01:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44f13f751a | ||
|
|
986d2c586e | ||
|
|
9361997a42 | ||
|
|
2e96d8c4c2 | ||
|
|
ff75daf6b3 | ||
|
|
c0953bbd26 | ||
|
|
1f7e917c70 | ||
|
|
6ff2d64996 | ||
|
|
ab22ea6a25 | ||
|
|
ce2fc7712a | ||
|
|
bd933af874 | ||
|
|
f36f17b57d | ||
|
|
504569bed0 | ||
|
|
bd06fdafaf | ||
|
|
7b28973c60 | ||
|
|
cbac17c059 | ||
|
|
6ed1f3695a | ||
|
|
3d295b5132 | ||
|
|
4d220cdd9c | ||
|
|
ad20e4e39b | ||
|
|
3e2f6a96bf | ||
|
|
2ece97c42a | ||
|
|
a8ee4d421b |
@@ -9,15 +9,15 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type EnsureAssetIDResult struct {
|
||||
type ActionAmountResult struct {
|
||||
Completed int `json:"completed"`
|
||||
}
|
||||
|
||||
// HandleGroupInvitationsCreate godoc
|
||||
// @Summary Get the current user
|
||||
// @Summary Ensures all items in the database have an asset id
|
||||
// @Tags Group
|
||||
// @Produce json
|
||||
// @Success 200 {object} EnsureAssetIDResult
|
||||
// @Success 200 {object} ActionAmountResult
|
||||
// @Router /v1/actions/ensure-asset-ids [Post]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleEnsureAssetID() server.HandlerFunc {
|
||||
@@ -30,6 +30,27 @@ func (ctrl *V1Controller) HandleEnsureAssetID() server.HandlerFunc {
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return server.Respond(w, http.StatusOK, EnsureAssetIDResult{Completed: totalCompleted})
|
||||
return server.Respond(w, http.StatusOK, ActionAmountResult{Completed: totalCompleted})
|
||||
}
|
||||
}
|
||||
|
||||
// HandleItemDateZeroOut godoc
|
||||
// @Summary Resets all item date fields to the beginning of the day
|
||||
// @Tags Group
|
||||
// @Produce json
|
||||
// @Success 200 {object} ActionAmountResult
|
||||
// @Router /v1/actions/zero-item-time-fields [Post]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleItemDateZeroOut() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
ctx := services.NewContext(r.Context())
|
||||
|
||||
totalCompleted, err := ctrl.repo.Items.ZeroOutTimeFields(ctx, ctx.GID)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to ensure asset id")
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return server.Respond(w, http.StatusOK, ActionAmountResult{Completed: totalCompleted})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package v1
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||
@@ -70,7 +71,7 @@ func (ctrl *V1Controller) HandleAuthLogin() server.HandlerFunc {
|
||||
)
|
||||
}
|
||||
|
||||
newToken, err := ctrl.svc.User.Login(r.Context(), loginForm.Username, loginForm.Password)
|
||||
newToken, err := ctrl.svc.User.Login(r.Context(), strings.ToLower(loginForm.Username), loginForm.Password)
|
||||
|
||||
if err != nil {
|
||||
return validate.NewRequestError(errors.New("authentication failed"), http.StatusInternalServerError)
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
@@ -29,18 +30,48 @@ func (ctrl *V1Controller) HandleItemsGetAll() server.HandlerFunc {
|
||||
extractQuery := func(r *http.Request) repo.ItemQuery {
|
||||
params := r.URL.Query()
|
||||
|
||||
return repo.ItemQuery{
|
||||
filterFieldItems := func(raw []string) []repo.FieldQuery {
|
||||
var items []repo.FieldQuery
|
||||
|
||||
for _, v := range raw {
|
||||
parts := strings.SplitN(v, "=", 2)
|
||||
if len(parts) == 2 {
|
||||
items = append(items, repo.FieldQuery{
|
||||
Name: parts[0],
|
||||
Value: parts[1],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
|
||||
v := repo.ItemQuery{
|
||||
Page: queryIntOrNegativeOne(params.Get("page")),
|
||||
PageSize: queryIntOrNegativeOne(params.Get("pageSize")),
|
||||
Search: params.Get("q"),
|
||||
LocationIDs: queryUUIDList(params, "locations"),
|
||||
LabelIDs: queryUUIDList(params, "labels"),
|
||||
IncludeArchived: queryBool(params.Get("includeArchived")),
|
||||
Fields: filterFieldItems(params["fields"]),
|
||||
}
|
||||
|
||||
if strings.HasPrefix(v.Search, "#") {
|
||||
aidStr := strings.TrimPrefix(v.Search, "#")
|
||||
|
||||
aid, ok := repo.ParseAssetID(aidStr)
|
||||
if ok {
|
||||
v.Search = ""
|
||||
v.AssetID = aid
|
||||
}
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
ctx := services.NewContext(r.Context())
|
||||
|
||||
items, err := ctrl.repo.Items.QueryByGroup(ctx, ctx.GID, extractQuery(r))
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
@@ -161,6 +192,48 @@ func (ctrl *V1Controller) handleItemsGeneral() server.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// HandleGetAllCustomFieldNames godocs
|
||||
// @Summary imports items into the database
|
||||
// @Tags Items
|
||||
// @Produce json
|
||||
// @Success 200
|
||||
// @Router /v1/items/fields [GET]
|
||||
// @Success 200 {object} []string
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleGetAllCustomFieldNames() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
ctx := services.NewContext(r.Context())
|
||||
|
||||
v, err := ctrl.repo.Items.GetAllCustomFieldNames(r.Context(), ctx.GID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return server.Respond(w, http.StatusOK, v)
|
||||
}
|
||||
}
|
||||
|
||||
// HandleGetAllCustomFieldValues godocs
|
||||
// @Summary imports items into the database
|
||||
// @Tags Items
|
||||
// @Produce json
|
||||
// @Success 200
|
||||
// @Router /v1/items/fields/values [GET]
|
||||
// @Success 200 {object} []string
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleGetAllCustomFieldValues() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
ctx := services.NewContext(r.Context())
|
||||
|
||||
v, err := ctrl.repo.Items.GetAllCustomFieldValues(r.Context(), ctx.GID, r.URL.Query().Get("field"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return server.Respond(w, http.StatusOK, v)
|
||||
}
|
||||
}
|
||||
|
||||
// HandleItemsImport godocs
|
||||
// @Summary imports items into the database
|
||||
// @Tags Items
|
||||
|
||||
@@ -11,6 +11,39 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// HandleLocationTreeQuery godoc
|
||||
// @Summary Get All Locations
|
||||
// @Tags Locations
|
||||
// @Produce json
|
||||
// @Param withItems query bool false "include items in response tree"
|
||||
// @Success 200 {object} server.Results{items=[]repo.TreeItem}
|
||||
// @Router /v1/locations/tree [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleLocationTreeQuery() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
user := services.UseUserCtx(r.Context())
|
||||
|
||||
q := r.URL.Query()
|
||||
|
||||
withItems := queryBool(q.Get("withItems"))
|
||||
|
||||
locTree, err := ctrl.repo.Locations.Tree(
|
||||
r.Context(),
|
||||
user.GroupID,
|
||||
repo.TreeQuery{
|
||||
WithItems: withItems,
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to get locations tree")
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return server.Respond(w, http.StatusOK, server.Results{Items: locTree})
|
||||
}
|
||||
}
|
||||
|
||||
// HandleLocationGetAll godoc
|
||||
// @Summary Get All Locations
|
||||
// @Tags Locations
|
||||
|
||||
32
backend/app/api/handlers/v1/v1_ctrl_reporting.go
Normal file
32
backend/app/api/handlers/v1/v1_ctrl_reporting.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
||||
)
|
||||
|
||||
// HandleBillOfMaterialsExport godoc
|
||||
//
|
||||
// @Summary Generates a Bill of Materials CSV
|
||||
// @Tags Reporting
|
||||
// @Produce json
|
||||
// @Success 200 {string} string "text/csv"
|
||||
// @Router /v1/reporting/bill-of-materials [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleBillOfMaterialsExport() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
actor := services.UseUserCtx(r.Context())
|
||||
|
||||
csv, err := ctrl.svc.Reporting.BillOfMaterialsTSV(r.Context(), actor.GroupID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/csv")
|
||||
w.Header().Set("Content-Disposition", "attachment; filename=bom.csv")
|
||||
_, err = w.Write(csv)
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -88,9 +88,11 @@ func (a *app) mountRoutes(repos *repo.AllRepos) {
|
||||
a.server.Put(v1Base("/groups"), v1Ctrl.HandleGroupUpdate(), userMW...)
|
||||
|
||||
a.server.Post(v1Base("/actions/ensure-asset-ids"), v1Ctrl.HandleEnsureAssetID(), userMW...)
|
||||
a.server.Post(v1Base("/actions/zero-item-time-fields"), v1Ctrl.HandleItemDateZeroOut(), userMW...)
|
||||
|
||||
a.server.Get(v1Base("/locations"), v1Ctrl.HandleLocationGetAll(), userMW...)
|
||||
a.server.Post(v1Base("/locations"), v1Ctrl.HandleLocationCreate(), userMW...)
|
||||
a.server.Get(v1Base("/locations/tree"), v1Ctrl.HandleLocationTreeQuery(), userMW...)
|
||||
a.server.Get(v1Base("/locations/{id}"), v1Ctrl.HandleLocationGet(), userMW...)
|
||||
a.server.Put(v1Base("/locations/{id}"), v1Ctrl.HandleLocationUpdate(), userMW...)
|
||||
a.server.Delete(v1Base("/locations/{id}"), v1Ctrl.HandleLocationDelete(), userMW...)
|
||||
@@ -102,8 +104,11 @@ func (a *app) mountRoutes(repos *repo.AllRepos) {
|
||||
a.server.Delete(v1Base("/labels/{id}"), v1Ctrl.HandleLabelDelete(), userMW...)
|
||||
|
||||
a.server.Get(v1Base("/items"), v1Ctrl.HandleItemsGetAll(), userMW...)
|
||||
a.server.Post(v1Base("/items/import"), v1Ctrl.HandleItemsImport(), userMW...)
|
||||
a.server.Post(v1Base("/items"), v1Ctrl.HandleItemsCreate(), userMW...)
|
||||
a.server.Post(v1Base("/items/import"), v1Ctrl.HandleItemsImport(), userMW...)
|
||||
a.server.Get(v1Base("/items/fields"), v1Ctrl.HandleGetAllCustomFieldNames(), userMW...)
|
||||
a.server.Get(v1Base("/items/fields/values"), v1Ctrl.HandleGetAllCustomFieldValues(), userMW...)
|
||||
|
||||
a.server.Get(v1Base("/items/{id}"), v1Ctrl.HandleItemGet(), userMW...)
|
||||
a.server.Put(v1Base("/items/{id}"), v1Ctrl.HandleItemUpdate(), userMW...)
|
||||
a.server.Delete(v1Base("/items/{id}"), v1Ctrl.HandleItemDelete(), userMW...)
|
||||
@@ -131,6 +136,9 @@ func (a *app) mountRoutes(repos *repo.AllRepos) {
|
||||
a.mwAuthToken, a.mwRoles(RoleModeOr, authroles.RoleUser.String(), authroles.RoleAttachments.String()),
|
||||
)
|
||||
|
||||
// Reporting Services
|
||||
a.server.Get(v1Base("/reporting/bill-of-materials"), v1Ctrl.HandleBillOfMaterialsExport(), userMW...)
|
||||
|
||||
a.server.NotFound(notFoundHandler())
|
||||
}
|
||||
|
||||
|
||||
@@ -34,12 +34,36 @@ const docTemplate = `{
|
||||
"tags": [
|
||||
"Group"
|
||||
],
|
||||
"summary": "Get the current user",
|
||||
"summary": "Ensures all items in the database have an asset id",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1.EnsureAssetIDResult"
|
||||
"$ref": "#/definitions/v1.ActionAmountResult"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/actions/zero-item-time-fields": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Group"
|
||||
],
|
||||
"summary": "Resets all item date fields to the beginning of the day",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1.ActionAmountResult"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -383,6 +407,60 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/items/fields": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Items"
|
||||
],
|
||||
"summary": "imports items into the database",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/items/fields/values": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Items"
|
||||
],
|
||||
"summary": "imports items into the database",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/items/import": {
|
||||
"post": {
|
||||
"security": [
|
||||
@@ -1045,6 +1123,53 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/locations/tree": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Locations"
|
||||
],
|
||||
"summary": "Get All Locations",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"description": "include items in response tree",
|
||||
"name": "withItems",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/server.Results"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/repo.TreeItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/locations/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -1178,6 +1303,30 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/reporting/bill-of-materials": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Reporting"
|
||||
],
|
||||
"summary": "Generates a Bill of Materials CSV",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "text/csv",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/status": {
|
||||
"get": {
|
||||
"produces": [
|
||||
@@ -1906,6 +2055,10 @@ const docTemplate = `{
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"parentId": {
|
||||
"type": "string",
|
||||
"x-nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2116,6 +2269,26 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"repo.TreeItem": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"children": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/repo.TreeItem"
|
||||
}
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"repo.UserOut": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -2240,6 +2413,14 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.ActionAmountResult": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"completed": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.ApiSummary": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -2291,14 +2472,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.EnsureAssetIDResult": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"completed": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.GroupInvitation": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -26,12 +26,36 @@
|
||||
"tags": [
|
||||
"Group"
|
||||
],
|
||||
"summary": "Get the current user",
|
||||
"summary": "Ensures all items in the database have an asset id",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1.EnsureAssetIDResult"
|
||||
"$ref": "#/definitions/v1.ActionAmountResult"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/actions/zero-item-time-fields": {
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Group"
|
||||
],
|
||||
"summary": "Resets all item date fields to the beginning of the day",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/v1.ActionAmountResult"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -375,6 +399,60 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/items/fields": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Items"
|
||||
],
|
||||
"summary": "imports items into the database",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/items/fields/values": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Items"
|
||||
],
|
||||
"summary": "imports items into the database",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/items/import": {
|
||||
"post": {
|
||||
"security": [
|
||||
@@ -1037,6 +1115,53 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/locations/tree": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Locations"
|
||||
],
|
||||
"summary": "Get All Locations",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "boolean",
|
||||
"description": "include items in response tree",
|
||||
"name": "withItems",
|
||||
"in": "query"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/server.Results"
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"items": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/repo.TreeItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/locations/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
@@ -1170,6 +1295,30 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/reporting/bill-of-materials": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"Bearer": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Reporting"
|
||||
],
|
||||
"summary": "Generates a Bill of Materials CSV",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "text/csv",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/v1/status": {
|
||||
"get": {
|
||||
"produces": [
|
||||
@@ -1898,6 +2047,10 @@
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"parentId": {
|
||||
"type": "string",
|
||||
"x-nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2108,6 +2261,26 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"repo.TreeItem": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"children": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/repo.TreeItem"
|
||||
}
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"repo.UserOut": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -2232,6 +2405,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.ActionAmountResult": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"completed": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.ApiSummary": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -2283,14 +2464,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.EnsureAssetIDResult": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"completed": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.GroupInvitation": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -322,6 +322,9 @@ definitions:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
parentId:
|
||||
type: string
|
||||
x-nullable: true
|
||||
type: object
|
||||
repo.LocationOut:
|
||||
properties:
|
||||
@@ -459,6 +462,19 @@ definitions:
|
||||
total:
|
||||
type: number
|
||||
type: object
|
||||
repo.TreeItem:
|
||||
properties:
|
||||
children:
|
||||
items:
|
||||
$ref: '#/definitions/repo.TreeItem'
|
||||
type: array
|
||||
id:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
type: object
|
||||
repo.UserOut:
|
||||
properties:
|
||||
email:
|
||||
@@ -540,6 +556,11 @@ definitions:
|
||||
token:
|
||||
type: string
|
||||
type: object
|
||||
v1.ActionAmountResult:
|
||||
properties:
|
||||
completed:
|
||||
type: integer
|
||||
type: object
|
||||
v1.ApiSummary:
|
||||
properties:
|
||||
build:
|
||||
@@ -573,11 +594,6 @@ definitions:
|
||||
new:
|
||||
type: string
|
||||
type: object
|
||||
v1.EnsureAssetIDResult:
|
||||
properties:
|
||||
completed:
|
||||
type: integer
|
||||
type: object
|
||||
v1.GroupInvitation:
|
||||
properties:
|
||||
expiresAt:
|
||||
@@ -627,10 +643,24 @@ paths:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/v1.EnsureAssetIDResult'
|
||||
$ref: '#/definitions/v1.ActionAmountResult'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Get the current user
|
||||
summary: Ensures all items in the database have an asset id
|
||||
tags:
|
||||
- Group
|
||||
/v1/actions/zero-item-time-fields:
|
||||
post:
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/v1.ActionAmountResult'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Resets all item date fields to the beginning of the day
|
||||
tags:
|
||||
- Group
|
||||
/v1/assets/{id}:
|
||||
@@ -1078,6 +1108,38 @@ paths:
|
||||
summary: Update Maintenance Entry
|
||||
tags:
|
||||
- Maintenance
|
||||
/v1/items/fields:
|
||||
get:
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: imports items into the database
|
||||
tags:
|
||||
- Items
|
||||
/v1/items/fields/values:
|
||||
get:
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: imports items into the database
|
||||
tags:
|
||||
- Items
|
||||
/v1/items/import:
|
||||
post:
|
||||
parameters:
|
||||
@@ -1301,6 +1363,32 @@ paths:
|
||||
summary: updates a location
|
||||
tags:
|
||||
- Locations
|
||||
/v1/locations/tree:
|
||||
get:
|
||||
parameters:
|
||||
- description: include items in response tree
|
||||
in: query
|
||||
name: withItems
|
||||
type: boolean
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/server.Results'
|
||||
- properties:
|
||||
items:
|
||||
items:
|
||||
$ref: '#/definitions/repo.TreeItem'
|
||||
type: array
|
||||
type: object
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Get All Locations
|
||||
tags:
|
||||
- Locations
|
||||
/v1/qrcode:
|
||||
get:
|
||||
parameters:
|
||||
@@ -1320,6 +1408,20 @@ paths:
|
||||
summary: Encode data into QRCode
|
||||
tags:
|
||||
- Items
|
||||
/v1/reporting/bill-of-materials:
|
||||
get:
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: text/csv
|
||||
schema:
|
||||
type: string
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Generates a Bill of Materials CSV
|
||||
tags:
|
||||
- Reporting
|
||||
/v1/status:
|
||||
get:
|
||||
produces:
|
||||
|
||||
@@ -3,20 +3,21 @@ module github.com/hay-kot/homebox/backend
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
ariga.io/atlas v0.9.0
|
||||
entgo.io/ent v0.11.5
|
||||
github.com/ardanlabs/conf/v2 v2.2.0
|
||||
ariga.io/atlas v0.9.1-0.20230119145809-92243f7c55cb
|
||||
entgo.io/ent v0.11.7
|
||||
github.com/ardanlabs/conf/v3 v3.1.3
|
||||
github.com/go-chi/chi/v5 v5.0.8
|
||||
github.com/go-playground/validator/v10 v10.11.1
|
||||
github.com/go-playground/validator/v10 v10.11.2
|
||||
github.com/gocarina/gocsv v0.0.0-20230123225133-763e25b40669
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/mattn/go-sqlite3 v1.14.16
|
||||
github.com/rs/zerolog v1.28.0
|
||||
github.com/rs/zerolog v1.29.0
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/swaggo/http-swagger v1.3.3
|
||||
github.com/swaggo/swag v1.8.9
|
||||
github.com/swaggo/swag v1.8.10
|
||||
github.com/yeqown/go-qrcode/v2 v2.2.1
|
||||
github.com/yeqown/go-qrcode/writer/standard v1.2.1
|
||||
golang.org/x/crypto v0.5.0
|
||||
golang.org/x/crypto v0.6.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -30,8 +31,8 @@ require (
|
||||
github.com/go-openapi/jsonreference v0.20.0 // indirect
|
||||
github.com/go-openapi/spec v0.20.7 // indirect
|
||||
github.com/go-openapi/swag v0.22.3 // indirect
|
||||
github.com/go-playground/locales v0.14.0 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.15.0 // indirect
|
||||
@@ -48,9 +49,9 @@ require (
|
||||
github.com/zclconf/go-cty v1.12.1 // indirect
|
||||
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 // indirect
|
||||
golang.org/x/mod v0.7.0 // indirect
|
||||
golang.org/x/net v0.5.0 // indirect
|
||||
golang.org/x/sys v0.4.0 // indirect
|
||||
golang.org/x/text v0.6.0 // indirect
|
||||
golang.org/x/net v0.6.0 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
golang.org/x/tools v0.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
ariga.io/atlas v0.9.0 h1:q0JMtqyA3X1YWtPcn+E/kVPwLDslb+jAC8Ejl/vW6d0=
|
||||
ariga.io/atlas v0.9.0/go.mod h1:T230JFcENj4ZZzMkZrXFDSkv+2kXkUgpJ5FQQ5hMcKU=
|
||||
entgo.io/ent v0.11.5 h1:V2qhG91C4PMQTa82Q4StoESMQ4dzkMNeStCzszxi0jQ=
|
||||
entgo.io/ent v0.11.5/go.mod h1:u7eKwNWAo/VlHIKxgwbmsFy3J7cKDxwi3jyF5TW/okY=
|
||||
ariga.io/atlas v0.9.1-0.20230119145809-92243f7c55cb h1:mbsFtavDqGdYwdDpP50LGOOZ2hgyGoJcZeOpbgKMyu4=
|
||||
ariga.io/atlas v0.9.1-0.20230119145809-92243f7c55cb/go.mod h1:T230JFcENj4ZZzMkZrXFDSkv+2kXkUgpJ5FQQ5hMcKU=
|
||||
entgo.io/ent v0.11.7 h1:V+wKFh0jhAbY/FoU+PPbdMOf2Ma5vh07R/IdF+N/nFg=
|
||||
entgo.io/ent v0.11.7/go.mod h1:ericBi6Q8l3wBH1wEIDfKxw7rcQEuRPyBfbIzjtxJ18=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
@@ -9,8 +9,8 @@ github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7l
|
||||
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
|
||||
github.com/ardanlabs/conf/v2 v2.2.0 h1:ar1+TYIYAh2Tdeg2DQroh7ruR56/vJR8BDfzDIrXgtk=
|
||||
github.com/ardanlabs/conf/v2 v2.2.0/go.mod h1:m37ZKdW9jwMUEhGX36jRNt8VzSQ/HVmSziLZH2p33nY=
|
||||
github.com/ardanlabs/conf/v3 v3.1.3 h1:16+Nzfc4PBd/ERtYERUFL/75eVKNyW15Y+vn3W1XZzQ=
|
||||
github.com/ardanlabs/conf/v3 v3.1.3/go.mod h1:bIacyuGeZjkTdtszdbvOcuq49VhHpV3+IPZ2ewOAK4I=
|
||||
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -33,15 +33,16 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh
|
||||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
|
||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
|
||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
|
||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||
github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ=
|
||||
github.com/go-playground/validator/v10 v10.11.1/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.11.2 h1:q3SHpufmypg+erIExEKUmsgmhDTyhcJ38oeKGACXohU=
|
||||
github.com/go-playground/validator/v10 v10.11.2/go.mod h1:NieE624vt4SCTJtD87arVLvdmjPAeV8BQlHtMnw9D7s=
|
||||
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
|
||||
github.com/gocarina/gocsv v0.0.0-20230123225133-763e25b40669 h1:MvZzCA/mduVWoBSVKJeMdv+AqXQmZZ8i6p8889ejt/Y=
|
||||
github.com/gocarina/gocsv v0.0.0-20230123225133-763e25b40669/go.mod h1:5YoVOkjYAQumqlV356Hj3xeYh4BdZuLE0/nRkf2NKkI=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
@@ -55,9 +56,7 @@ github.com/hashicorp/hcl/v2 v2.15.0/go.mod h1:JRmR89jycNkrrqnMmvPDMd56n1rQJ2Q6Ko
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
@@ -84,17 +83,14 @@ github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQ
|
||||
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY=
|
||||
github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
|
||||
github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w=
|
||||
github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
|
||||
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
|
||||
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
@@ -103,7 +99,6 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
||||
@@ -112,8 +107,8 @@ github.com/swaggo/files v1.0.0 h1:1gGXVIeUFCS/dta17rnP0iOpr6CXFwKD7EO5ID233e4=
|
||||
github.com/swaggo/files v1.0.0/go.mod h1:N59U6URJLyU1PQgFqPM7wXLMhJx7QAolnvfQkqO13kc=
|
||||
github.com/swaggo/http-swagger v1.3.3 h1:Hu5Z0L9ssyBLofaama21iYaF2VbWyA8jdohaaCGpHsc=
|
||||
github.com/swaggo/http-swagger v1.3.3/go.mod h1:sE+4PjD89IxMPm77FnkDz0sdO+p5lbXzrVWT6OTVVGo=
|
||||
github.com/swaggo/swag v1.8.9 h1:kHtaBe/Ob9AZzAANfcn5c6RyCke9gG9QpH0jky0I/sA=
|
||||
github.com/swaggo/swag v1.8.9/go.mod h1:ezQVUUhly8dludpVk+/PuwJWvLLanB13ygV5Pr9enSk=
|
||||
github.com/swaggo/swag v1.8.10 h1:eExW4bFa52WOjqRzRD58bgWsWfdFJso50lpbeTcmTfo=
|
||||
github.com/swaggo/swag v1.8.10/go.mod h1:ezQVUUhly8dludpVk+/PuwJWvLLanB13ygV5Pr9enSk=
|
||||
github.com/yeqown/go-qrcode/v2 v2.2.1 h1:Jc1Q916fwC05R8C7mpWDbrT9tyLPaLLKDABoC5XBCe8=
|
||||
github.com/yeqown/go-qrcode/v2 v2.2.1/go.mod h1:2Qsk2APUCPne0TsRo40DIkI5MYnbzYKCnKGEFWrxd24=
|
||||
github.com/yeqown/go-qrcode/writer/standard v1.2.1 h1:FMRZiur5yApUIe4fqtqmcdl/XQTZAZWt2DhkPx4VIW0=
|
||||
@@ -125,9 +120,8 @@ github.com/zclconf/go-cty v1.12.1 h1:PcupnljUm9EIvbgSHQnHhUr3fO6oFmkOrvs2BAFNXXY
|
||||
github.com/zclconf/go-cty v1.12.1/go.mod h1:s9IfD1LK5ccNMSWCVFCE2rJfHiZgi7JijgeWIMfhLvA=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
|
||||
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
|
||||
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 h1:QelT11PB4FXiDEXucrfNckHoFxwt8USGY1ajP1ZF5lM=
|
||||
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
@@ -135,36 +129,32 @@ golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
|
||||
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
|
||||
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
|
||||
golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
|
||||
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
@@ -175,13 +165,10 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
package services
|
||||
|
||||
import "github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
import (
|
||||
"github.com/hay-kot/homebox/backend/internal/core/services/reporting"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type AllServices struct {
|
||||
User *UserService
|
||||
Group *GroupService
|
||||
Items *ItemService
|
||||
User *UserService
|
||||
Group *GroupService
|
||||
Items *ItemService
|
||||
Reporting *reporting.ReportingService
|
||||
}
|
||||
|
||||
type OptionsFunc func(*options)
|
||||
@@ -40,5 +45,7 @@ func New(repos *repo.AllRepos, opts ...OptionsFunc) *AllServices {
|
||||
repo: repos,
|
||||
autoIncrementAssetID: options.autoIncrementAssetID,
|
||||
},
|
||||
// TODO: don't use global logger
|
||||
Reporting: reporting.NewReportingService(repos, &log.Logger),
|
||||
}
|
||||
}
|
||||
|
||||
85
backend/internal/core/services/reporting/reporting.go
Normal file
85
backend/internal/core/services/reporting/reporting.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package reporting
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/csv"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/gocarina/gocsv"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
"github.com/rs/zerolog"
|
||||
)
|
||||
|
||||
type ReportingService struct {
|
||||
repos *repo.AllRepos
|
||||
l *zerolog.Logger
|
||||
}
|
||||
|
||||
func NewReportingService(repos *repo.AllRepos, l *zerolog.Logger) *ReportingService {
|
||||
gocsv.SetCSVWriter(func(out io.Writer) *gocsv.SafeCSVWriter {
|
||||
writer := csv.NewWriter(out)
|
||||
writer.Comma = '\t'
|
||||
return gocsv.NewSafeCSVWriter(writer)
|
||||
})
|
||||
|
||||
return &ReportingService{
|
||||
repos: repos,
|
||||
l: l,
|
||||
}
|
||||
}
|
||||
|
||||
// =================================================================================================
|
||||
|
||||
// NullableTime is a custom type that implements the MarshalCSV interface
|
||||
// to allow for nullable time.Time fields in the CSV output to be empty
|
||||
// and not "0001-01-01". It also overrides the default CSV output format
|
||||
type NullableTime time.Time
|
||||
|
||||
func (t NullableTime) MarshalCSV() (string, error) {
|
||||
if time.Time(t).IsZero() {
|
||||
return "", nil
|
||||
}
|
||||
// YYYY-MM-DD
|
||||
return time.Time(t).Format("2006-01-02"), nil
|
||||
}
|
||||
|
||||
type BillOfMaterialsEntry struct {
|
||||
PurchaseDate NullableTime `csv:"Purchase Date"`
|
||||
Name string `csv:"Name"`
|
||||
Description string `csv:"Description"`
|
||||
Manufacturer string `csv:"Manufacturer"`
|
||||
SerialNumber string `csv:"Serial Number"`
|
||||
ModelNumber string `csv:"Model Number"`
|
||||
Quantity int `csv:"Quantity"`
|
||||
Price float64 `csv:"Price"`
|
||||
TotalPrice float64 `csv:"Total Price"`
|
||||
}
|
||||
|
||||
// BillOfMaterialsTSV returns a byte slice of the Bill of Materials for a given GID in TSV format
|
||||
// See BillOfMaterialsEntry for the format of the output
|
||||
func (rs *ReportingService) BillOfMaterialsTSV(ctx context.Context, GID uuid.UUID) ([]byte, error) {
|
||||
entities, err := rs.repos.Items.GetAll(ctx, GID)
|
||||
if err != nil {
|
||||
rs.l.Debug().Err(err).Msg("failed to get all items for BOM Csv Reporting")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bomEntries := make([]BillOfMaterialsEntry, len(entities))
|
||||
for i, entity := range entities {
|
||||
bomEntries[i] = BillOfMaterialsEntry{
|
||||
PurchaseDate: NullableTime(entity.PurchaseTime),
|
||||
Name: entity.Name,
|
||||
Description: entity.Description,
|
||||
Manufacturer: entity.Manufacturer,
|
||||
SerialNumber: entity.SerialNumber,
|
||||
ModelNumber: entity.ModelNumber,
|
||||
Quantity: entity.Quantity,
|
||||
Price: entity.PurchasePrice,
|
||||
TotalPrice: entity.PurchasePrice * float64(entity.Quantity),
|
||||
}
|
||||
}
|
||||
|
||||
return gocsv.MarshalBytes(&bomEntries)
|
||||
}
|
||||
@@ -12,10 +12,10 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
//go:embed testdata/import.csv
|
||||
//go:embed .testdata/import.csv
|
||||
var CSVData_Comma []byte
|
||||
|
||||
//go:embed testdata/import.tsv
|
||||
//go:embed .testdata/import.tsv
|
||||
var CSVData_Tab []byte
|
||||
|
||||
func loadcsv() [][]string {
|
||||
|
||||
@@ -51,15 +51,17 @@ func (svc *UserService) RegisterUser(ctx context.Context, data UserRegistration)
|
||||
Msg("Registering new user")
|
||||
|
||||
var (
|
||||
err error
|
||||
group repo.Group
|
||||
token repo.GroupInvitation
|
||||
isOwner = false
|
||||
err error
|
||||
group repo.Group
|
||||
token repo.GroupInvitation
|
||||
|
||||
// creatingGroup is true if the user is creating a new group.
|
||||
creatingGroup = false
|
||||
)
|
||||
|
||||
switch data.GroupToken {
|
||||
case "":
|
||||
isOwner = true
|
||||
creatingGroup = true
|
||||
group, err = svc.repos.Groups.GroupCreate(ctx, "Home")
|
||||
if err != nil {
|
||||
log.Err(err).Msg("Failed to create group")
|
||||
@@ -81,7 +83,7 @@ func (svc *UserService) RegisterUser(ctx context.Context, data UserRegistration)
|
||||
Password: hashed,
|
||||
IsSuperuser: false,
|
||||
GroupID: group.ID,
|
||||
IsOwner: isOwner,
|
||||
IsOwner: creatingGroup,
|
||||
}
|
||||
|
||||
usr, err := svc.repos.Users.Create(ctx, usrCreate)
|
||||
@@ -89,21 +91,24 @@ func (svc *UserService) RegisterUser(ctx context.Context, data UserRegistration)
|
||||
return repo.UserOut{}, err
|
||||
}
|
||||
|
||||
for _, label := range defaultLabels() {
|
||||
_, err := svc.repos.Labels.Create(ctx, group.ID, label)
|
||||
if err != nil {
|
||||
return repo.UserOut{}, err
|
||||
// Create the default labels and locations for the group.
|
||||
if creatingGroup {
|
||||
for _, label := range defaultLabels() {
|
||||
_, err := svc.repos.Labels.Create(ctx, group.ID, label)
|
||||
if err != nil {
|
||||
return repo.UserOut{}, err
|
||||
}
|
||||
}
|
||||
|
||||
for _, location := range defaultLocations() {
|
||||
_, err := svc.repos.Locations.Create(ctx, group.ID, location)
|
||||
if err != nil {
|
||||
return repo.UserOut{}, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, location := range defaultLocations() {
|
||||
_, err := svc.repos.Locations.Create(ctx, group.ID, location)
|
||||
if err != nil {
|
||||
return repo.UserOut{}, err
|
||||
}
|
||||
}
|
||||
|
||||
// Decrement the invitation token if it was used
|
||||
// Decrement the invitation token if it was used.
|
||||
if token.ID != uuid.Nil {
|
||||
err = svc.repos.Groups.InvitationUpdate(ctx, token.ID, token.Uses-1)
|
||||
if err != nil {
|
||||
|
||||
@@ -144,19 +144,19 @@ func (a *Attachment) assignValues(columns []string, values []any) error {
|
||||
|
||||
// QueryItem queries the "item" edge of the Attachment entity.
|
||||
func (a *Attachment) QueryItem() *ItemQuery {
|
||||
return (&AttachmentClient{config: a.config}).QueryItem(a)
|
||||
return NewAttachmentClient(a.config).QueryItem(a)
|
||||
}
|
||||
|
||||
// QueryDocument queries the "document" edge of the Attachment entity.
|
||||
func (a *Attachment) QueryDocument() *DocumentQuery {
|
||||
return (&AttachmentClient{config: a.config}).QueryDocument(a)
|
||||
return NewAttachmentClient(a.config).QueryDocument(a)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this Attachment.
|
||||
// Note that you need to call Attachment.Unwrap() before calling this method if this Attachment
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (a *Attachment) Update() *AttachmentUpdateOne {
|
||||
return (&AttachmentClient{config: a.config}).UpdateOne(a)
|
||||
return NewAttachmentClient(a.config).UpdateOne(a)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the Attachment entity that was returned from a transaction after it was closed,
|
||||
|
||||
@@ -69,6 +69,12 @@ type AttachmentDeleteOne struct {
|
||||
ad *AttachmentDelete
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the AttachmentDelete builder.
|
||||
func (ado *AttachmentDeleteOne) Where(ps ...predicate.Attachment) *AttachmentDeleteOne {
|
||||
ado.ad.mutation.Where(ps...)
|
||||
return ado
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (ado *AttachmentDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := ado.ad.Exec(ctx)
|
||||
@@ -84,5 +90,7 @@ func (ado *AttachmentDeleteOne) Exec(ctx context.Context) error {
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (ado *AttachmentDeleteOne) ExecX(ctx context.Context) {
|
||||
ado.ad.ExecX(ctx)
|
||||
if err := ado.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,11 +20,8 @@ import (
|
||||
// AttachmentQuery is the builder for querying Attachment entities.
|
||||
type AttachmentQuery struct {
|
||||
config
|
||||
limit *int
|
||||
offset *int
|
||||
unique *bool
|
||||
ctx *QueryContext
|
||||
order []OrderFunc
|
||||
fields []string
|
||||
inters []Interceptor
|
||||
predicates []predicate.Attachment
|
||||
withItem *ItemQuery
|
||||
@@ -43,20 +40,20 @@ func (aq *AttachmentQuery) Where(ps ...predicate.Attachment) *AttachmentQuery {
|
||||
|
||||
// Limit the number of records to be returned by this query.
|
||||
func (aq *AttachmentQuery) Limit(limit int) *AttachmentQuery {
|
||||
aq.limit = &limit
|
||||
aq.ctx.Limit = &limit
|
||||
return aq
|
||||
}
|
||||
|
||||
// Offset to start from.
|
||||
func (aq *AttachmentQuery) Offset(offset int) *AttachmentQuery {
|
||||
aq.offset = &offset
|
||||
aq.ctx.Offset = &offset
|
||||
return aq
|
||||
}
|
||||
|
||||
// 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 (aq *AttachmentQuery) Unique(unique bool) *AttachmentQuery {
|
||||
aq.unique = &unique
|
||||
aq.ctx.Unique = &unique
|
||||
return aq
|
||||
}
|
||||
|
||||
@@ -113,7 +110,7 @@ func (aq *AttachmentQuery) QueryDocument() *DocumentQuery {
|
||||
// First returns the first Attachment entity from the query.
|
||||
// Returns a *NotFoundError when no Attachment was found.
|
||||
func (aq *AttachmentQuery) First(ctx context.Context) (*Attachment, error) {
|
||||
nodes, err := aq.Limit(1).All(newQueryContext(ctx, TypeAttachment, "First"))
|
||||
nodes, err := aq.Limit(1).All(setContextOp(ctx, aq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -136,7 +133,7 @@ func (aq *AttachmentQuery) FirstX(ctx context.Context) *Attachment {
|
||||
// Returns a *NotFoundError when no Attachment ID was found.
|
||||
func (aq *AttachmentQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = aq.Limit(1).IDs(newQueryContext(ctx, TypeAttachment, "FirstID")); err != nil {
|
||||
if ids, err = aq.Limit(1).IDs(setContextOp(ctx, aq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -159,7 +156,7 @@ func (aq *AttachmentQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one Attachment entity is found.
|
||||
// Returns a *NotFoundError when no Attachment entities are found.
|
||||
func (aq *AttachmentQuery) Only(ctx context.Context) (*Attachment, error) {
|
||||
nodes, err := aq.Limit(2).All(newQueryContext(ctx, TypeAttachment, "Only"))
|
||||
nodes, err := aq.Limit(2).All(setContextOp(ctx, aq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -187,7 +184,7 @@ func (aq *AttachmentQuery) OnlyX(ctx context.Context) *Attachment {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (aq *AttachmentQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = aq.Limit(2).IDs(newQueryContext(ctx, TypeAttachment, "OnlyID")); err != nil {
|
||||
if ids, err = aq.Limit(2).IDs(setContextOp(ctx, aq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -212,7 +209,7 @@ func (aq *AttachmentQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of Attachments.
|
||||
func (aq *AttachmentQuery) All(ctx context.Context) ([]*Attachment, error) {
|
||||
ctx = newQueryContext(ctx, TypeAttachment, "All")
|
||||
ctx = setContextOp(ctx, aq.ctx, "All")
|
||||
if err := aq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -232,7 +229,7 @@ func (aq *AttachmentQuery) AllX(ctx context.Context) []*Attachment {
|
||||
// IDs executes the query and returns a list of Attachment IDs.
|
||||
func (aq *AttachmentQuery) IDs(ctx context.Context) ([]uuid.UUID, error) {
|
||||
var ids []uuid.UUID
|
||||
ctx = newQueryContext(ctx, TypeAttachment, "IDs")
|
||||
ctx = setContextOp(ctx, aq.ctx, "IDs")
|
||||
if err := aq.Select(attachment.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -250,7 +247,7 @@ func (aq *AttachmentQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (aq *AttachmentQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = newQueryContext(ctx, TypeAttachment, "Count")
|
||||
ctx = setContextOp(ctx, aq.ctx, "Count")
|
||||
if err := aq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -268,7 +265,7 @@ func (aq *AttachmentQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (aq *AttachmentQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = newQueryContext(ctx, TypeAttachment, "Exist")
|
||||
ctx = setContextOp(ctx, aq.ctx, "Exist")
|
||||
switch _, err := aq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -296,17 +293,15 @@ func (aq *AttachmentQuery) Clone() *AttachmentQuery {
|
||||
}
|
||||
return &AttachmentQuery{
|
||||
config: aq.config,
|
||||
limit: aq.limit,
|
||||
offset: aq.offset,
|
||||
ctx: aq.ctx.Clone(),
|
||||
order: append([]OrderFunc{}, aq.order...),
|
||||
inters: append([]Interceptor{}, aq.inters...),
|
||||
predicates: append([]predicate.Attachment{}, aq.predicates...),
|
||||
withItem: aq.withItem.Clone(),
|
||||
withDocument: aq.withDocument.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: aq.sql.Clone(),
|
||||
path: aq.path,
|
||||
unique: aq.unique,
|
||||
sql: aq.sql.Clone(),
|
||||
path: aq.path,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,9 +342,9 @@ func (aq *AttachmentQuery) WithDocument(opts ...func(*DocumentQuery)) *Attachmen
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (aq *AttachmentQuery) GroupBy(field string, fields ...string) *AttachmentGroupBy {
|
||||
aq.fields = append([]string{field}, fields...)
|
||||
aq.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &AttachmentGroupBy{build: aq}
|
||||
grbuild.flds = &aq.fields
|
||||
grbuild.flds = &aq.ctx.Fields
|
||||
grbuild.label = attachment.Label
|
||||
grbuild.scan = grbuild.Scan
|
||||
return grbuild
|
||||
@@ -368,10 +363,10 @@ func (aq *AttachmentQuery) GroupBy(field string, fields ...string) *AttachmentGr
|
||||
// Select(attachment.FieldCreatedAt).
|
||||
// Scan(ctx, &v)
|
||||
func (aq *AttachmentQuery) Select(fields ...string) *AttachmentSelect {
|
||||
aq.fields = append(aq.fields, fields...)
|
||||
aq.ctx.Fields = append(aq.ctx.Fields, fields...)
|
||||
sbuild := &AttachmentSelect{AttachmentQuery: aq}
|
||||
sbuild.label = attachment.Label
|
||||
sbuild.flds, sbuild.scan = &aq.fields, sbuild.Scan
|
||||
sbuild.flds, sbuild.scan = &aq.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
@@ -391,7 +386,7 @@ func (aq *AttachmentQuery) prepareQuery(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range aq.fields {
|
||||
for _, f := range aq.ctx.Fields {
|
||||
if !attachment.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
@@ -468,6 +463,9 @@ func (aq *AttachmentQuery) loadItem(ctx context.Context, query *ItemQuery, nodes
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
query.Where(item.IDIn(ids...))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
@@ -497,6 +495,9 @@ func (aq *AttachmentQuery) loadDocument(ctx context.Context, query *DocumentQuer
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
query.Where(document.IDIn(ids...))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
@@ -516,9 +517,9 @@ func (aq *AttachmentQuery) loadDocument(ctx context.Context, query *DocumentQuer
|
||||
|
||||
func (aq *AttachmentQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := aq.querySpec()
|
||||
_spec.Node.Columns = aq.fields
|
||||
if len(aq.fields) > 0 {
|
||||
_spec.Unique = aq.unique != nil && *aq.unique
|
||||
_spec.Node.Columns = aq.ctx.Fields
|
||||
if len(aq.ctx.Fields) > 0 {
|
||||
_spec.Unique = aq.ctx.Unique != nil && *aq.ctx.Unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, aq.driver, _spec)
|
||||
}
|
||||
@@ -536,10 +537,10 @@ func (aq *AttachmentQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
From: aq.sql,
|
||||
Unique: true,
|
||||
}
|
||||
if unique := aq.unique; unique != nil {
|
||||
if unique := aq.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
}
|
||||
if fields := aq.fields; len(fields) > 0 {
|
||||
if fields := aq.ctx.Fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, attachment.FieldID)
|
||||
for i := range fields {
|
||||
@@ -555,10 +556,10 @@ func (aq *AttachmentQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := aq.limit; limit != nil {
|
||||
if limit := aq.ctx.Limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := aq.offset; offset != nil {
|
||||
if offset := aq.ctx.Offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := aq.order; len(ps) > 0 {
|
||||
@@ -574,7 +575,7 @@ func (aq *AttachmentQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
func (aq *AttachmentQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(aq.driver.Dialect())
|
||||
t1 := builder.Table(attachment.Table)
|
||||
columns := aq.fields
|
||||
columns := aq.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = attachment.Columns
|
||||
}
|
||||
@@ -583,7 +584,7 @@ func (aq *AttachmentQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
selector = aq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if aq.unique != nil && *aq.unique {
|
||||
if aq.ctx.Unique != nil && *aq.ctx.Unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, p := range aq.predicates {
|
||||
@@ -592,12 +593,12 @@ func (aq *AttachmentQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
for _, p := range aq.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := aq.offset; offset != nil {
|
||||
if offset := aq.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 := aq.limit; limit != nil {
|
||||
if limit := aq.ctx.Limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
@@ -617,7 +618,7 @@ func (agb *AttachmentGroupBy) Aggregate(fns ...AggregateFunc) *AttachmentGroupBy
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (agb *AttachmentGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeAttachment, "GroupBy")
|
||||
ctx = setContextOp(ctx, agb.build.ctx, "GroupBy")
|
||||
if err := agb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -665,7 +666,7 @@ func (as *AttachmentSelect) Aggregate(fns ...AggregateFunc) *AttachmentSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (as *AttachmentSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeAttachment, "Select")
|
||||
ctx = setContextOp(ctx, as.ctx, "Select")
|
||||
if err := as.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -99,14 +99,14 @@ func (ar *AuthRoles) assignValues(columns []string, values []any) error {
|
||||
|
||||
// QueryToken queries the "token" edge of the AuthRoles entity.
|
||||
func (ar *AuthRoles) QueryToken() *AuthTokensQuery {
|
||||
return (&AuthRolesClient{config: ar.config}).QueryToken(ar)
|
||||
return NewAuthRolesClient(ar.config).QueryToken(ar)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this AuthRoles.
|
||||
// Note that you need to call AuthRoles.Unwrap() before calling this method if this AuthRoles
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (ar *AuthRoles) Update() *AuthRolesUpdateOne {
|
||||
return (&AuthRolesClient{config: ar.config}).UpdateOne(ar)
|
||||
return NewAuthRolesClient(ar.config).UpdateOne(ar)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the AuthRoles entity that was returned from a transaction after it was closed,
|
||||
|
||||
@@ -69,6 +69,12 @@ type AuthRolesDeleteOne struct {
|
||||
ard *AuthRolesDelete
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the AuthRolesDelete builder.
|
||||
func (ardo *AuthRolesDeleteOne) Where(ps ...predicate.AuthRoles) *AuthRolesDeleteOne {
|
||||
ardo.ard.mutation.Where(ps...)
|
||||
return ardo
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (ardo *AuthRolesDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := ardo.ard.Exec(ctx)
|
||||
@@ -84,5 +90,7 @@ func (ardo *AuthRolesDeleteOne) Exec(ctx context.Context) error {
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (ardo *AuthRolesDeleteOne) ExecX(ctx context.Context) {
|
||||
ardo.ard.ExecX(ctx)
|
||||
if err := ardo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,11 +19,8 @@ import (
|
||||
// AuthRolesQuery is the builder for querying AuthRoles entities.
|
||||
type AuthRolesQuery struct {
|
||||
config
|
||||
limit *int
|
||||
offset *int
|
||||
unique *bool
|
||||
ctx *QueryContext
|
||||
order []OrderFunc
|
||||
fields []string
|
||||
inters []Interceptor
|
||||
predicates []predicate.AuthRoles
|
||||
withToken *AuthTokensQuery
|
||||
@@ -41,20 +38,20 @@ func (arq *AuthRolesQuery) Where(ps ...predicate.AuthRoles) *AuthRolesQuery {
|
||||
|
||||
// Limit the number of records to be returned by this query.
|
||||
func (arq *AuthRolesQuery) Limit(limit int) *AuthRolesQuery {
|
||||
arq.limit = &limit
|
||||
arq.ctx.Limit = &limit
|
||||
return arq
|
||||
}
|
||||
|
||||
// Offset to start from.
|
||||
func (arq *AuthRolesQuery) Offset(offset int) *AuthRolesQuery {
|
||||
arq.offset = &offset
|
||||
arq.ctx.Offset = &offset
|
||||
return arq
|
||||
}
|
||||
|
||||
// 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 (arq *AuthRolesQuery) Unique(unique bool) *AuthRolesQuery {
|
||||
arq.unique = &unique
|
||||
arq.ctx.Unique = &unique
|
||||
return arq
|
||||
}
|
||||
|
||||
@@ -89,7 +86,7 @@ func (arq *AuthRolesQuery) QueryToken() *AuthTokensQuery {
|
||||
// First returns the first AuthRoles entity from the query.
|
||||
// Returns a *NotFoundError when no AuthRoles was found.
|
||||
func (arq *AuthRolesQuery) First(ctx context.Context) (*AuthRoles, error) {
|
||||
nodes, err := arq.Limit(1).All(newQueryContext(ctx, TypeAuthRoles, "First"))
|
||||
nodes, err := arq.Limit(1).All(setContextOp(ctx, arq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -112,7 +109,7 @@ func (arq *AuthRolesQuery) FirstX(ctx context.Context) *AuthRoles {
|
||||
// Returns a *NotFoundError when no AuthRoles ID was found.
|
||||
func (arq *AuthRolesQuery) FirstID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = arq.Limit(1).IDs(newQueryContext(ctx, TypeAuthRoles, "FirstID")); err != nil {
|
||||
if ids, err = arq.Limit(1).IDs(setContextOp(ctx, arq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -135,7 +132,7 @@ func (arq *AuthRolesQuery) FirstIDX(ctx context.Context) int {
|
||||
// Returns a *NotSingularError when more than one AuthRoles entity is found.
|
||||
// Returns a *NotFoundError when no AuthRoles entities are found.
|
||||
func (arq *AuthRolesQuery) Only(ctx context.Context) (*AuthRoles, error) {
|
||||
nodes, err := arq.Limit(2).All(newQueryContext(ctx, TypeAuthRoles, "Only"))
|
||||
nodes, err := arq.Limit(2).All(setContextOp(ctx, arq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -163,7 +160,7 @@ func (arq *AuthRolesQuery) OnlyX(ctx context.Context) *AuthRoles {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (arq *AuthRolesQuery) OnlyID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = arq.Limit(2).IDs(newQueryContext(ctx, TypeAuthRoles, "OnlyID")); err != nil {
|
||||
if ids, err = arq.Limit(2).IDs(setContextOp(ctx, arq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -188,7 +185,7 @@ func (arq *AuthRolesQuery) OnlyIDX(ctx context.Context) int {
|
||||
|
||||
// All executes the query and returns a list of AuthRolesSlice.
|
||||
func (arq *AuthRolesQuery) All(ctx context.Context) ([]*AuthRoles, error) {
|
||||
ctx = newQueryContext(ctx, TypeAuthRoles, "All")
|
||||
ctx = setContextOp(ctx, arq.ctx, "All")
|
||||
if err := arq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -208,7 +205,7 @@ func (arq *AuthRolesQuery) AllX(ctx context.Context) []*AuthRoles {
|
||||
// IDs executes the query and returns a list of AuthRoles IDs.
|
||||
func (arq *AuthRolesQuery) IDs(ctx context.Context) ([]int, error) {
|
||||
var ids []int
|
||||
ctx = newQueryContext(ctx, TypeAuthRoles, "IDs")
|
||||
ctx = setContextOp(ctx, arq.ctx, "IDs")
|
||||
if err := arq.Select(authroles.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -226,7 +223,7 @@ func (arq *AuthRolesQuery) IDsX(ctx context.Context) []int {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (arq *AuthRolesQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = newQueryContext(ctx, TypeAuthRoles, "Count")
|
||||
ctx = setContextOp(ctx, arq.ctx, "Count")
|
||||
if err := arq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -244,7 +241,7 @@ func (arq *AuthRolesQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (arq *AuthRolesQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = newQueryContext(ctx, TypeAuthRoles, "Exist")
|
||||
ctx = setContextOp(ctx, arq.ctx, "Exist")
|
||||
switch _, err := arq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -272,16 +269,14 @@ func (arq *AuthRolesQuery) Clone() *AuthRolesQuery {
|
||||
}
|
||||
return &AuthRolesQuery{
|
||||
config: arq.config,
|
||||
limit: arq.limit,
|
||||
offset: arq.offset,
|
||||
ctx: arq.ctx.Clone(),
|
||||
order: append([]OrderFunc{}, arq.order...),
|
||||
inters: append([]Interceptor{}, arq.inters...),
|
||||
predicates: append([]predicate.AuthRoles{}, arq.predicates...),
|
||||
withToken: arq.withToken.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: arq.sql.Clone(),
|
||||
path: arq.path,
|
||||
unique: arq.unique,
|
||||
sql: arq.sql.Clone(),
|
||||
path: arq.path,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,9 +306,9 @@ func (arq *AuthRolesQuery) WithToken(opts ...func(*AuthTokensQuery)) *AuthRolesQ
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (arq *AuthRolesQuery) GroupBy(field string, fields ...string) *AuthRolesGroupBy {
|
||||
arq.fields = append([]string{field}, fields...)
|
||||
arq.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &AuthRolesGroupBy{build: arq}
|
||||
grbuild.flds = &arq.fields
|
||||
grbuild.flds = &arq.ctx.Fields
|
||||
grbuild.label = authroles.Label
|
||||
grbuild.scan = grbuild.Scan
|
||||
return grbuild
|
||||
@@ -332,10 +327,10 @@ func (arq *AuthRolesQuery) GroupBy(field string, fields ...string) *AuthRolesGro
|
||||
// Select(authroles.FieldRole).
|
||||
// Scan(ctx, &v)
|
||||
func (arq *AuthRolesQuery) Select(fields ...string) *AuthRolesSelect {
|
||||
arq.fields = append(arq.fields, fields...)
|
||||
arq.ctx.Fields = append(arq.ctx.Fields, fields...)
|
||||
sbuild := &AuthRolesSelect{AuthRolesQuery: arq}
|
||||
sbuild.label = authroles.Label
|
||||
sbuild.flds, sbuild.scan = &arq.fields, sbuild.Scan
|
||||
sbuild.flds, sbuild.scan = &arq.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
@@ -355,7 +350,7 @@ func (arq *AuthRolesQuery) prepareQuery(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range arq.fields {
|
||||
for _, f := range arq.ctx.Fields {
|
||||
if !authroles.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
@@ -425,6 +420,9 @@ func (arq *AuthRolesQuery) loadToken(ctx context.Context, query *AuthTokensQuery
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
query.Where(authtokens.IDIn(ids...))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
@@ -444,9 +442,9 @@ func (arq *AuthRolesQuery) loadToken(ctx context.Context, query *AuthTokensQuery
|
||||
|
||||
func (arq *AuthRolesQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := arq.querySpec()
|
||||
_spec.Node.Columns = arq.fields
|
||||
if len(arq.fields) > 0 {
|
||||
_spec.Unique = arq.unique != nil && *arq.unique
|
||||
_spec.Node.Columns = arq.ctx.Fields
|
||||
if len(arq.ctx.Fields) > 0 {
|
||||
_spec.Unique = arq.ctx.Unique != nil && *arq.ctx.Unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, arq.driver, _spec)
|
||||
}
|
||||
@@ -464,10 +462,10 @@ func (arq *AuthRolesQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
From: arq.sql,
|
||||
Unique: true,
|
||||
}
|
||||
if unique := arq.unique; unique != nil {
|
||||
if unique := arq.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
}
|
||||
if fields := arq.fields; len(fields) > 0 {
|
||||
if fields := arq.ctx.Fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, authroles.FieldID)
|
||||
for i := range fields {
|
||||
@@ -483,10 +481,10 @@ func (arq *AuthRolesQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := arq.limit; limit != nil {
|
||||
if limit := arq.ctx.Limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := arq.offset; offset != nil {
|
||||
if offset := arq.ctx.Offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := arq.order; len(ps) > 0 {
|
||||
@@ -502,7 +500,7 @@ func (arq *AuthRolesQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
func (arq *AuthRolesQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(arq.driver.Dialect())
|
||||
t1 := builder.Table(authroles.Table)
|
||||
columns := arq.fields
|
||||
columns := arq.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = authroles.Columns
|
||||
}
|
||||
@@ -511,7 +509,7 @@ func (arq *AuthRolesQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
selector = arq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if arq.unique != nil && *arq.unique {
|
||||
if arq.ctx.Unique != nil && *arq.ctx.Unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, p := range arq.predicates {
|
||||
@@ -520,12 +518,12 @@ func (arq *AuthRolesQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
for _, p := range arq.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := arq.offset; offset != nil {
|
||||
if offset := arq.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 := arq.limit; limit != nil {
|
||||
if limit := arq.ctx.Limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
@@ -545,7 +543,7 @@ func (argb *AuthRolesGroupBy) Aggregate(fns ...AggregateFunc) *AuthRolesGroupBy
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (argb *AuthRolesGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeAuthRoles, "GroupBy")
|
||||
ctx = setContextOp(ctx, argb.build.ctx, "GroupBy")
|
||||
if err := argb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -593,7 +591,7 @@ func (ars *AuthRolesSelect) Aggregate(fns ...AggregateFunc) *AuthRolesSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ars *AuthRolesSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeAuthRoles, "Select")
|
||||
ctx = setContextOp(ctx, ars.ctx, "Select")
|
||||
if err := ars.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -142,19 +142,19 @@ func (at *AuthTokens) assignValues(columns []string, values []any) error {
|
||||
|
||||
// QueryUser queries the "user" edge of the AuthTokens entity.
|
||||
func (at *AuthTokens) QueryUser() *UserQuery {
|
||||
return (&AuthTokensClient{config: at.config}).QueryUser(at)
|
||||
return NewAuthTokensClient(at.config).QueryUser(at)
|
||||
}
|
||||
|
||||
// QueryRoles queries the "roles" edge of the AuthTokens entity.
|
||||
func (at *AuthTokens) QueryRoles() *AuthRolesQuery {
|
||||
return (&AuthTokensClient{config: at.config}).QueryRoles(at)
|
||||
return NewAuthTokensClient(at.config).QueryRoles(at)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this AuthTokens.
|
||||
// Note that you need to call AuthTokens.Unwrap() before calling this method if this AuthTokens
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (at *AuthTokens) Update() *AuthTokensUpdateOne {
|
||||
return (&AuthTokensClient{config: at.config}).UpdateOne(at)
|
||||
return NewAuthTokensClient(at.config).UpdateOne(at)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the AuthTokens entity that was returned from a transaction after it was closed,
|
||||
|
||||
@@ -69,6 +69,12 @@ type AuthTokensDeleteOne struct {
|
||||
atd *AuthTokensDelete
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the AuthTokensDelete builder.
|
||||
func (atdo *AuthTokensDeleteOne) Where(ps ...predicate.AuthTokens) *AuthTokensDeleteOne {
|
||||
atdo.atd.mutation.Where(ps...)
|
||||
return atdo
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (atdo *AuthTokensDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := atdo.atd.Exec(ctx)
|
||||
@@ -84,5 +90,7 @@ func (atdo *AuthTokensDeleteOne) Exec(ctx context.Context) error {
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (atdo *AuthTokensDeleteOne) ExecX(ctx context.Context) {
|
||||
atdo.atd.ExecX(ctx)
|
||||
if err := atdo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,11 +21,8 @@ import (
|
||||
// AuthTokensQuery is the builder for querying AuthTokens entities.
|
||||
type AuthTokensQuery struct {
|
||||
config
|
||||
limit *int
|
||||
offset *int
|
||||
unique *bool
|
||||
ctx *QueryContext
|
||||
order []OrderFunc
|
||||
fields []string
|
||||
inters []Interceptor
|
||||
predicates []predicate.AuthTokens
|
||||
withUser *UserQuery
|
||||
@@ -44,20 +41,20 @@ func (atq *AuthTokensQuery) Where(ps ...predicate.AuthTokens) *AuthTokensQuery {
|
||||
|
||||
// Limit the number of records to be returned by this query.
|
||||
func (atq *AuthTokensQuery) Limit(limit int) *AuthTokensQuery {
|
||||
atq.limit = &limit
|
||||
atq.ctx.Limit = &limit
|
||||
return atq
|
||||
}
|
||||
|
||||
// Offset to start from.
|
||||
func (atq *AuthTokensQuery) Offset(offset int) *AuthTokensQuery {
|
||||
atq.offset = &offset
|
||||
atq.ctx.Offset = &offset
|
||||
return atq
|
||||
}
|
||||
|
||||
// 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 (atq *AuthTokensQuery) Unique(unique bool) *AuthTokensQuery {
|
||||
atq.unique = &unique
|
||||
atq.ctx.Unique = &unique
|
||||
return atq
|
||||
}
|
||||
|
||||
@@ -114,7 +111,7 @@ func (atq *AuthTokensQuery) QueryRoles() *AuthRolesQuery {
|
||||
// First returns the first AuthTokens entity from the query.
|
||||
// Returns a *NotFoundError when no AuthTokens was found.
|
||||
func (atq *AuthTokensQuery) First(ctx context.Context) (*AuthTokens, error) {
|
||||
nodes, err := atq.Limit(1).All(newQueryContext(ctx, TypeAuthTokens, "First"))
|
||||
nodes, err := atq.Limit(1).All(setContextOp(ctx, atq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -137,7 +134,7 @@ func (atq *AuthTokensQuery) FirstX(ctx context.Context) *AuthTokens {
|
||||
// Returns a *NotFoundError when no AuthTokens ID was found.
|
||||
func (atq *AuthTokensQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = atq.Limit(1).IDs(newQueryContext(ctx, TypeAuthTokens, "FirstID")); err != nil {
|
||||
if ids, err = atq.Limit(1).IDs(setContextOp(ctx, atq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -160,7 +157,7 @@ func (atq *AuthTokensQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one AuthTokens entity is found.
|
||||
// Returns a *NotFoundError when no AuthTokens entities are found.
|
||||
func (atq *AuthTokensQuery) Only(ctx context.Context) (*AuthTokens, error) {
|
||||
nodes, err := atq.Limit(2).All(newQueryContext(ctx, TypeAuthTokens, "Only"))
|
||||
nodes, err := atq.Limit(2).All(setContextOp(ctx, atq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -188,7 +185,7 @@ func (atq *AuthTokensQuery) OnlyX(ctx context.Context) *AuthTokens {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (atq *AuthTokensQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = atq.Limit(2).IDs(newQueryContext(ctx, TypeAuthTokens, "OnlyID")); err != nil {
|
||||
if ids, err = atq.Limit(2).IDs(setContextOp(ctx, atq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -213,7 +210,7 @@ func (atq *AuthTokensQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of AuthTokensSlice.
|
||||
func (atq *AuthTokensQuery) All(ctx context.Context) ([]*AuthTokens, error) {
|
||||
ctx = newQueryContext(ctx, TypeAuthTokens, "All")
|
||||
ctx = setContextOp(ctx, atq.ctx, "All")
|
||||
if err := atq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -233,7 +230,7 @@ func (atq *AuthTokensQuery) AllX(ctx context.Context) []*AuthTokens {
|
||||
// IDs executes the query and returns a list of AuthTokens IDs.
|
||||
func (atq *AuthTokensQuery) IDs(ctx context.Context) ([]uuid.UUID, error) {
|
||||
var ids []uuid.UUID
|
||||
ctx = newQueryContext(ctx, TypeAuthTokens, "IDs")
|
||||
ctx = setContextOp(ctx, atq.ctx, "IDs")
|
||||
if err := atq.Select(authtokens.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -251,7 +248,7 @@ func (atq *AuthTokensQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (atq *AuthTokensQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = newQueryContext(ctx, TypeAuthTokens, "Count")
|
||||
ctx = setContextOp(ctx, atq.ctx, "Count")
|
||||
if err := atq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -269,7 +266,7 @@ func (atq *AuthTokensQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (atq *AuthTokensQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = newQueryContext(ctx, TypeAuthTokens, "Exist")
|
||||
ctx = setContextOp(ctx, atq.ctx, "Exist")
|
||||
switch _, err := atq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -297,17 +294,15 @@ func (atq *AuthTokensQuery) Clone() *AuthTokensQuery {
|
||||
}
|
||||
return &AuthTokensQuery{
|
||||
config: atq.config,
|
||||
limit: atq.limit,
|
||||
offset: atq.offset,
|
||||
ctx: atq.ctx.Clone(),
|
||||
order: append([]OrderFunc{}, atq.order...),
|
||||
inters: append([]Interceptor{}, atq.inters...),
|
||||
predicates: append([]predicate.AuthTokens{}, atq.predicates...),
|
||||
withUser: atq.withUser.Clone(),
|
||||
withRoles: atq.withRoles.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: atq.sql.Clone(),
|
||||
path: atq.path,
|
||||
unique: atq.unique,
|
||||
sql: atq.sql.Clone(),
|
||||
path: atq.path,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,9 +343,9 @@ func (atq *AuthTokensQuery) WithRoles(opts ...func(*AuthRolesQuery)) *AuthTokens
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (atq *AuthTokensQuery) GroupBy(field string, fields ...string) *AuthTokensGroupBy {
|
||||
atq.fields = append([]string{field}, fields...)
|
||||
atq.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &AuthTokensGroupBy{build: atq}
|
||||
grbuild.flds = &atq.fields
|
||||
grbuild.flds = &atq.ctx.Fields
|
||||
grbuild.label = authtokens.Label
|
||||
grbuild.scan = grbuild.Scan
|
||||
return grbuild
|
||||
@@ -369,10 +364,10 @@ func (atq *AuthTokensQuery) GroupBy(field string, fields ...string) *AuthTokensG
|
||||
// Select(authtokens.FieldCreatedAt).
|
||||
// Scan(ctx, &v)
|
||||
func (atq *AuthTokensQuery) Select(fields ...string) *AuthTokensSelect {
|
||||
atq.fields = append(atq.fields, fields...)
|
||||
atq.ctx.Fields = append(atq.ctx.Fields, fields...)
|
||||
sbuild := &AuthTokensSelect{AuthTokensQuery: atq}
|
||||
sbuild.label = authtokens.Label
|
||||
sbuild.flds, sbuild.scan = &atq.fields, sbuild.Scan
|
||||
sbuild.flds, sbuild.scan = &atq.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
@@ -392,7 +387,7 @@ func (atq *AuthTokensQuery) prepareQuery(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range atq.fields {
|
||||
for _, f := range atq.ctx.Fields {
|
||||
if !authtokens.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
@@ -469,6 +464,9 @@ func (atq *AuthTokensQuery) loadUser(ctx context.Context, query *UserQuery, node
|
||||
}
|
||||
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 {
|
||||
@@ -516,9 +514,9 @@ func (atq *AuthTokensQuery) loadRoles(ctx context.Context, query *AuthRolesQuery
|
||||
|
||||
func (atq *AuthTokensQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := atq.querySpec()
|
||||
_spec.Node.Columns = atq.fields
|
||||
if len(atq.fields) > 0 {
|
||||
_spec.Unique = atq.unique != nil && *atq.unique
|
||||
_spec.Node.Columns = atq.ctx.Fields
|
||||
if len(atq.ctx.Fields) > 0 {
|
||||
_spec.Unique = atq.ctx.Unique != nil && *atq.ctx.Unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, atq.driver, _spec)
|
||||
}
|
||||
@@ -536,10 +534,10 @@ func (atq *AuthTokensQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
From: atq.sql,
|
||||
Unique: true,
|
||||
}
|
||||
if unique := atq.unique; unique != nil {
|
||||
if unique := atq.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
}
|
||||
if fields := atq.fields; len(fields) > 0 {
|
||||
if fields := atq.ctx.Fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, authtokens.FieldID)
|
||||
for i := range fields {
|
||||
@@ -555,10 +553,10 @@ func (atq *AuthTokensQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := atq.limit; limit != nil {
|
||||
if limit := atq.ctx.Limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := atq.offset; offset != nil {
|
||||
if offset := atq.ctx.Offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := atq.order; len(ps) > 0 {
|
||||
@@ -574,7 +572,7 @@ func (atq *AuthTokensQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
func (atq *AuthTokensQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(atq.driver.Dialect())
|
||||
t1 := builder.Table(authtokens.Table)
|
||||
columns := atq.fields
|
||||
columns := atq.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = authtokens.Columns
|
||||
}
|
||||
@@ -583,7 +581,7 @@ func (atq *AuthTokensQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
selector = atq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if atq.unique != nil && *atq.unique {
|
||||
if atq.ctx.Unique != nil && *atq.ctx.Unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, p := range atq.predicates {
|
||||
@@ -592,12 +590,12 @@ func (atq *AuthTokensQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
for _, p := range atq.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := atq.offset; offset != nil {
|
||||
if offset := atq.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 := atq.limit; limit != nil {
|
||||
if limit := atq.ctx.Limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
@@ -617,7 +615,7 @@ func (atgb *AuthTokensGroupBy) Aggregate(fns ...AggregateFunc) *AuthTokensGroupB
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (atgb *AuthTokensGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeAuthTokens, "GroupBy")
|
||||
ctx = setContextOp(ctx, atgb.build.ctx, "GroupBy")
|
||||
if err := atgb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -665,7 +663,7 @@ func (ats *AuthTokensSelect) Aggregate(fns ...AggregateFunc) *AuthTokensSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ats *AuthTokensSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeAuthTokens, "Select")
|
||||
ctx = setContextOp(ctx, ats.ctx, "Select")
|
||||
if err := ats.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -324,6 +324,7 @@ func (c *AttachmentClient) DeleteOneID(id uuid.UUID) *AttachmentDeleteOne {
|
||||
func (c *AttachmentClient) Query() *AttachmentQuery {
|
||||
return &AttachmentQuery{
|
||||
config: c.config,
|
||||
ctx: &QueryContext{Type: TypeAttachment},
|
||||
inters: c.Interceptors(),
|
||||
}
|
||||
}
|
||||
@@ -473,6 +474,7 @@ func (c *AuthRolesClient) DeleteOneID(id int) *AuthRolesDeleteOne {
|
||||
func (c *AuthRolesClient) Query() *AuthRolesQuery {
|
||||
return &AuthRolesQuery{
|
||||
config: c.config,
|
||||
ctx: &QueryContext{Type: TypeAuthRoles},
|
||||
inters: c.Interceptors(),
|
||||
}
|
||||
}
|
||||
@@ -606,6 +608,7 @@ func (c *AuthTokensClient) DeleteOneID(id uuid.UUID) *AuthTokensDeleteOne {
|
||||
func (c *AuthTokensClient) Query() *AuthTokensQuery {
|
||||
return &AuthTokensQuery{
|
||||
config: c.config,
|
||||
ctx: &QueryContext{Type: TypeAuthTokens},
|
||||
inters: c.Interceptors(),
|
||||
}
|
||||
}
|
||||
@@ -755,6 +758,7 @@ func (c *DocumentClient) DeleteOneID(id uuid.UUID) *DocumentDeleteOne {
|
||||
func (c *DocumentClient) Query() *DocumentQuery {
|
||||
return &DocumentQuery{
|
||||
config: c.config,
|
||||
ctx: &QueryContext{Type: TypeDocument},
|
||||
inters: c.Interceptors(),
|
||||
}
|
||||
}
|
||||
@@ -904,6 +908,7 @@ func (c *GroupClient) DeleteOneID(id uuid.UUID) *GroupDeleteOne {
|
||||
func (c *GroupClient) Query() *GroupQuery {
|
||||
return &GroupQuery{
|
||||
config: c.config,
|
||||
ctx: &QueryContext{Type: TypeGroup},
|
||||
inters: c.Interceptors(),
|
||||
}
|
||||
}
|
||||
@@ -1117,6 +1122,7 @@ func (c *GroupInvitationTokenClient) DeleteOneID(id uuid.UUID) *GroupInvitationT
|
||||
func (c *GroupInvitationTokenClient) Query() *GroupInvitationTokenQuery {
|
||||
return &GroupInvitationTokenQuery{
|
||||
config: c.config,
|
||||
ctx: &QueryContext{Type: TypeGroupInvitationToken},
|
||||
inters: c.Interceptors(),
|
||||
}
|
||||
}
|
||||
@@ -1250,6 +1256,7 @@ func (c *ItemClient) DeleteOneID(id uuid.UUID) *ItemDeleteOne {
|
||||
func (c *ItemClient) Query() *ItemQuery {
|
||||
return &ItemQuery{
|
||||
config: c.config,
|
||||
ctx: &QueryContext{Type: TypeItem},
|
||||
inters: c.Interceptors(),
|
||||
}
|
||||
}
|
||||
@@ -1495,6 +1502,7 @@ func (c *ItemFieldClient) DeleteOneID(id uuid.UUID) *ItemFieldDeleteOne {
|
||||
func (c *ItemFieldClient) Query() *ItemFieldQuery {
|
||||
return &ItemFieldQuery{
|
||||
config: c.config,
|
||||
ctx: &QueryContext{Type: TypeItemField},
|
||||
inters: c.Interceptors(),
|
||||
}
|
||||
}
|
||||
@@ -1628,6 +1636,7 @@ func (c *LabelClient) DeleteOneID(id uuid.UUID) *LabelDeleteOne {
|
||||
func (c *LabelClient) Query() *LabelQuery {
|
||||
return &LabelQuery{
|
||||
config: c.config,
|
||||
ctx: &QueryContext{Type: TypeLabel},
|
||||
inters: c.Interceptors(),
|
||||
}
|
||||
}
|
||||
@@ -1777,6 +1786,7 @@ func (c *LocationClient) DeleteOneID(id uuid.UUID) *LocationDeleteOne {
|
||||
func (c *LocationClient) Query() *LocationQuery {
|
||||
return &LocationQuery{
|
||||
config: c.config,
|
||||
ctx: &QueryContext{Type: TypeLocation},
|
||||
inters: c.Interceptors(),
|
||||
}
|
||||
}
|
||||
@@ -1958,6 +1968,7 @@ func (c *MaintenanceEntryClient) DeleteOneID(id uuid.UUID) *MaintenanceEntryDele
|
||||
func (c *MaintenanceEntryClient) Query() *MaintenanceEntryQuery {
|
||||
return &MaintenanceEntryQuery{
|
||||
config: c.config,
|
||||
ctx: &QueryContext{Type: TypeMaintenanceEntry},
|
||||
inters: c.Interceptors(),
|
||||
}
|
||||
}
|
||||
@@ -2091,6 +2102,7 @@ func (c *UserClient) DeleteOneID(id uuid.UUID) *UserDeleteOne {
|
||||
func (c *UserClient) Query() *UserQuery {
|
||||
return &UserQuery{
|
||||
config: c.config,
|
||||
ctx: &QueryContext{Type: TypeUser},
|
||||
inters: c.Interceptors(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,19 +137,19 @@ func (d *Document) assignValues(columns []string, values []any) error {
|
||||
|
||||
// QueryGroup queries the "group" edge of the Document entity.
|
||||
func (d *Document) QueryGroup() *GroupQuery {
|
||||
return (&DocumentClient{config: d.config}).QueryGroup(d)
|
||||
return NewDocumentClient(d.config).QueryGroup(d)
|
||||
}
|
||||
|
||||
// QueryAttachments queries the "attachments" edge of the Document entity.
|
||||
func (d *Document) QueryAttachments() *AttachmentQuery {
|
||||
return (&DocumentClient{config: d.config}).QueryAttachments(d)
|
||||
return NewDocumentClient(d.config).QueryAttachments(d)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this Document.
|
||||
// Note that you need to call Document.Unwrap() before calling this method if this Document
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (d *Document) Update() *DocumentUpdateOne {
|
||||
return (&DocumentClient{config: d.config}).UpdateOne(d)
|
||||
return NewDocumentClient(d.config).UpdateOne(d)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the Document entity that was returned from a transaction after it was closed,
|
||||
|
||||
@@ -69,6 +69,12 @@ type DocumentDeleteOne struct {
|
||||
dd *DocumentDelete
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the DocumentDelete builder.
|
||||
func (ddo *DocumentDeleteOne) Where(ps ...predicate.Document) *DocumentDeleteOne {
|
||||
ddo.dd.mutation.Where(ps...)
|
||||
return ddo
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (ddo *DocumentDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := ddo.dd.Exec(ctx)
|
||||
@@ -84,5 +90,7 @@ func (ddo *DocumentDeleteOne) Exec(ctx context.Context) error {
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (ddo *DocumentDeleteOne) ExecX(ctx context.Context) {
|
||||
ddo.dd.ExecX(ctx)
|
||||
if err := ddo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,11 +21,8 @@ import (
|
||||
// DocumentQuery is the builder for querying Document entities.
|
||||
type DocumentQuery struct {
|
||||
config
|
||||
limit *int
|
||||
offset *int
|
||||
unique *bool
|
||||
ctx *QueryContext
|
||||
order []OrderFunc
|
||||
fields []string
|
||||
inters []Interceptor
|
||||
predicates []predicate.Document
|
||||
withGroup *GroupQuery
|
||||
@@ -44,20 +41,20 @@ func (dq *DocumentQuery) Where(ps ...predicate.Document) *DocumentQuery {
|
||||
|
||||
// Limit the number of records to be returned by this query.
|
||||
func (dq *DocumentQuery) Limit(limit int) *DocumentQuery {
|
||||
dq.limit = &limit
|
||||
dq.ctx.Limit = &limit
|
||||
return dq
|
||||
}
|
||||
|
||||
// Offset to start from.
|
||||
func (dq *DocumentQuery) Offset(offset int) *DocumentQuery {
|
||||
dq.offset = &offset
|
||||
dq.ctx.Offset = &offset
|
||||
return dq
|
||||
}
|
||||
|
||||
// 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 (dq *DocumentQuery) Unique(unique bool) *DocumentQuery {
|
||||
dq.unique = &unique
|
||||
dq.ctx.Unique = &unique
|
||||
return dq
|
||||
}
|
||||
|
||||
@@ -114,7 +111,7 @@ func (dq *DocumentQuery) QueryAttachments() *AttachmentQuery {
|
||||
// First returns the first Document entity from the query.
|
||||
// Returns a *NotFoundError when no Document was found.
|
||||
func (dq *DocumentQuery) First(ctx context.Context) (*Document, error) {
|
||||
nodes, err := dq.Limit(1).All(newQueryContext(ctx, TypeDocument, "First"))
|
||||
nodes, err := dq.Limit(1).All(setContextOp(ctx, dq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -137,7 +134,7 @@ func (dq *DocumentQuery) FirstX(ctx context.Context) *Document {
|
||||
// Returns a *NotFoundError when no Document ID was found.
|
||||
func (dq *DocumentQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = dq.Limit(1).IDs(newQueryContext(ctx, TypeDocument, "FirstID")); err != nil {
|
||||
if ids, err = dq.Limit(1).IDs(setContextOp(ctx, dq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -160,7 +157,7 @@ func (dq *DocumentQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one Document entity is found.
|
||||
// Returns a *NotFoundError when no Document entities are found.
|
||||
func (dq *DocumentQuery) Only(ctx context.Context) (*Document, error) {
|
||||
nodes, err := dq.Limit(2).All(newQueryContext(ctx, TypeDocument, "Only"))
|
||||
nodes, err := dq.Limit(2).All(setContextOp(ctx, dq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -188,7 +185,7 @@ func (dq *DocumentQuery) OnlyX(ctx context.Context) *Document {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (dq *DocumentQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = dq.Limit(2).IDs(newQueryContext(ctx, TypeDocument, "OnlyID")); err != nil {
|
||||
if ids, err = dq.Limit(2).IDs(setContextOp(ctx, dq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -213,7 +210,7 @@ func (dq *DocumentQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of Documents.
|
||||
func (dq *DocumentQuery) All(ctx context.Context) ([]*Document, error) {
|
||||
ctx = newQueryContext(ctx, TypeDocument, "All")
|
||||
ctx = setContextOp(ctx, dq.ctx, "All")
|
||||
if err := dq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -233,7 +230,7 @@ func (dq *DocumentQuery) AllX(ctx context.Context) []*Document {
|
||||
// IDs executes the query and returns a list of Document IDs.
|
||||
func (dq *DocumentQuery) IDs(ctx context.Context) ([]uuid.UUID, error) {
|
||||
var ids []uuid.UUID
|
||||
ctx = newQueryContext(ctx, TypeDocument, "IDs")
|
||||
ctx = setContextOp(ctx, dq.ctx, "IDs")
|
||||
if err := dq.Select(document.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -251,7 +248,7 @@ func (dq *DocumentQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (dq *DocumentQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = newQueryContext(ctx, TypeDocument, "Count")
|
||||
ctx = setContextOp(ctx, dq.ctx, "Count")
|
||||
if err := dq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -269,7 +266,7 @@ func (dq *DocumentQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (dq *DocumentQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = newQueryContext(ctx, TypeDocument, "Exist")
|
||||
ctx = setContextOp(ctx, dq.ctx, "Exist")
|
||||
switch _, err := dq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -297,17 +294,15 @@ func (dq *DocumentQuery) Clone() *DocumentQuery {
|
||||
}
|
||||
return &DocumentQuery{
|
||||
config: dq.config,
|
||||
limit: dq.limit,
|
||||
offset: dq.offset,
|
||||
ctx: dq.ctx.Clone(),
|
||||
order: append([]OrderFunc{}, dq.order...),
|
||||
inters: append([]Interceptor{}, dq.inters...),
|
||||
predicates: append([]predicate.Document{}, dq.predicates...),
|
||||
withGroup: dq.withGroup.Clone(),
|
||||
withAttachments: dq.withAttachments.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: dq.sql.Clone(),
|
||||
path: dq.path,
|
||||
unique: dq.unique,
|
||||
sql: dq.sql.Clone(),
|
||||
path: dq.path,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,9 +343,9 @@ func (dq *DocumentQuery) WithAttachments(opts ...func(*AttachmentQuery)) *Docume
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (dq *DocumentQuery) GroupBy(field string, fields ...string) *DocumentGroupBy {
|
||||
dq.fields = append([]string{field}, fields...)
|
||||
dq.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &DocumentGroupBy{build: dq}
|
||||
grbuild.flds = &dq.fields
|
||||
grbuild.flds = &dq.ctx.Fields
|
||||
grbuild.label = document.Label
|
||||
grbuild.scan = grbuild.Scan
|
||||
return grbuild
|
||||
@@ -369,10 +364,10 @@ func (dq *DocumentQuery) GroupBy(field string, fields ...string) *DocumentGroupB
|
||||
// Select(document.FieldCreatedAt).
|
||||
// Scan(ctx, &v)
|
||||
func (dq *DocumentQuery) Select(fields ...string) *DocumentSelect {
|
||||
dq.fields = append(dq.fields, fields...)
|
||||
dq.ctx.Fields = append(dq.ctx.Fields, fields...)
|
||||
sbuild := &DocumentSelect{DocumentQuery: dq}
|
||||
sbuild.label = document.Label
|
||||
sbuild.flds, sbuild.scan = &dq.fields, sbuild.Scan
|
||||
sbuild.flds, sbuild.scan = &dq.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
@@ -392,7 +387,7 @@ func (dq *DocumentQuery) prepareQuery(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range dq.fields {
|
||||
for _, f := range dq.ctx.Fields {
|
||||
if !document.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
@@ -470,6 +465,9 @@ func (dq *DocumentQuery) loadGroup(ctx context.Context, query *GroupQuery, nodes
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
query.Where(group.IDIn(ids...))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
@@ -520,9 +518,9 @@ func (dq *DocumentQuery) loadAttachments(ctx context.Context, query *AttachmentQ
|
||||
|
||||
func (dq *DocumentQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := dq.querySpec()
|
||||
_spec.Node.Columns = dq.fields
|
||||
if len(dq.fields) > 0 {
|
||||
_spec.Unique = dq.unique != nil && *dq.unique
|
||||
_spec.Node.Columns = dq.ctx.Fields
|
||||
if len(dq.ctx.Fields) > 0 {
|
||||
_spec.Unique = dq.ctx.Unique != nil && *dq.ctx.Unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, dq.driver, _spec)
|
||||
}
|
||||
@@ -540,10 +538,10 @@ func (dq *DocumentQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
From: dq.sql,
|
||||
Unique: true,
|
||||
}
|
||||
if unique := dq.unique; unique != nil {
|
||||
if unique := dq.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
}
|
||||
if fields := dq.fields; len(fields) > 0 {
|
||||
if fields := dq.ctx.Fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, document.FieldID)
|
||||
for i := range fields {
|
||||
@@ -559,10 +557,10 @@ func (dq *DocumentQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := dq.limit; limit != nil {
|
||||
if limit := dq.ctx.Limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := dq.offset; offset != nil {
|
||||
if offset := dq.ctx.Offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := dq.order; len(ps) > 0 {
|
||||
@@ -578,7 +576,7 @@ func (dq *DocumentQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
func (dq *DocumentQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(dq.driver.Dialect())
|
||||
t1 := builder.Table(document.Table)
|
||||
columns := dq.fields
|
||||
columns := dq.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = document.Columns
|
||||
}
|
||||
@@ -587,7 +585,7 @@ func (dq *DocumentQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
selector = dq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if dq.unique != nil && *dq.unique {
|
||||
if dq.ctx.Unique != nil && *dq.ctx.Unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, p := range dq.predicates {
|
||||
@@ -596,12 +594,12 @@ func (dq *DocumentQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
for _, p := range dq.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := dq.offset; offset != nil {
|
||||
if offset := dq.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 := dq.limit; limit != nil {
|
||||
if limit := dq.ctx.Limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
@@ -621,7 +619,7 @@ func (dgb *DocumentGroupBy) Aggregate(fns ...AggregateFunc) *DocumentGroupBy {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (dgb *DocumentGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeDocument, "GroupBy")
|
||||
ctx = setContextOp(ctx, dgb.build.ctx, "GroupBy")
|
||||
if err := dgb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -669,7 +667,7 @@ func (ds *DocumentSelect) Aggregate(fns ...AggregateFunc) *DocumentSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ds *DocumentSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeDocument, "Select")
|
||||
ctx = setContextOp(ctx, ds.ctx, "Select")
|
||||
if err := ds.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ type (
|
||||
Hook = ent.Hook
|
||||
Value = ent.Value
|
||||
Query = ent.Query
|
||||
QueryContext = ent.QueryContext
|
||||
Querier = ent.Querier
|
||||
QuerierFunc = ent.QuerierFunc
|
||||
Interceptor = ent.Interceptor
|
||||
@@ -525,10 +526,11 @@ func withHooks[V Value, M any, PM interface {
|
||||
return nv, nil
|
||||
}
|
||||
|
||||
// newQueryContext returns a new context with the given QueryContext attached in case it does not exist.
|
||||
func newQueryContext(ctx context.Context, typ, op string) context.Context {
|
||||
// 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 {
|
||||
ctx = ent.NewQueryContext(ctx, &ent.QueryContext{Type: typ, Op: op})
|
||||
qc.Op = op
|
||||
ctx = ent.NewQueryContext(ctx, qc)
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
@@ -166,39 +166,39 @@ func (gr *Group) assignValues(columns []string, values []any) error {
|
||||
|
||||
// QueryUsers queries the "users" edge of the Group entity.
|
||||
func (gr *Group) QueryUsers() *UserQuery {
|
||||
return (&GroupClient{config: gr.config}).QueryUsers(gr)
|
||||
return NewGroupClient(gr.config).QueryUsers(gr)
|
||||
}
|
||||
|
||||
// QueryLocations queries the "locations" edge of the Group entity.
|
||||
func (gr *Group) QueryLocations() *LocationQuery {
|
||||
return (&GroupClient{config: gr.config}).QueryLocations(gr)
|
||||
return NewGroupClient(gr.config).QueryLocations(gr)
|
||||
}
|
||||
|
||||
// QueryItems queries the "items" edge of the Group entity.
|
||||
func (gr *Group) QueryItems() *ItemQuery {
|
||||
return (&GroupClient{config: gr.config}).QueryItems(gr)
|
||||
return NewGroupClient(gr.config).QueryItems(gr)
|
||||
}
|
||||
|
||||
// QueryLabels queries the "labels" edge of the Group entity.
|
||||
func (gr *Group) QueryLabels() *LabelQuery {
|
||||
return (&GroupClient{config: gr.config}).QueryLabels(gr)
|
||||
return NewGroupClient(gr.config).QueryLabels(gr)
|
||||
}
|
||||
|
||||
// QueryDocuments queries the "documents" edge of the Group entity.
|
||||
func (gr *Group) QueryDocuments() *DocumentQuery {
|
||||
return (&GroupClient{config: gr.config}).QueryDocuments(gr)
|
||||
return NewGroupClient(gr.config).QueryDocuments(gr)
|
||||
}
|
||||
|
||||
// QueryInvitationTokens queries the "invitation_tokens" edge of the Group entity.
|
||||
func (gr *Group) QueryInvitationTokens() *GroupInvitationTokenQuery {
|
||||
return (&GroupClient{config: gr.config}).QueryInvitationTokens(gr)
|
||||
return NewGroupClient(gr.config).QueryInvitationTokens(gr)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this Group.
|
||||
// Note that you need to call Group.Unwrap() before calling this method if this Group
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (gr *Group) Update() *GroupUpdateOne {
|
||||
return (&GroupClient{config: gr.config}).UpdateOne(gr)
|
||||
return NewGroupClient(gr.config).UpdateOne(gr)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the Group entity that was returned from a transaction after it was closed,
|
||||
|
||||
@@ -131,6 +131,7 @@ const (
|
||||
CurrencyDkk Currency = "dkk"
|
||||
CurrencyInr Currency = "inr"
|
||||
CurrencyRmb Currency = "rmb"
|
||||
CurrencyBgn Currency = "bgn"
|
||||
)
|
||||
|
||||
func (c Currency) String() string {
|
||||
@@ -140,7 +141,7 @@ func (c Currency) String() string {
|
||||
// CurrencyValidator is a validator for the "currency" field enum values. It is called by the builders before save.
|
||||
func CurrencyValidator(c Currency) error {
|
||||
switch c {
|
||||
case CurrencyUsd, CurrencyEur, CurrencyGbp, CurrencyJpy, CurrencyZar, CurrencyAud, CurrencyNok, CurrencySek, CurrencyDkk, CurrencyInr, CurrencyRmb:
|
||||
case CurrencyUsd, CurrencyEur, CurrencyGbp, CurrencyJpy, CurrencyZar, CurrencyAud, CurrencyNok, CurrencySek, CurrencyDkk, CurrencyInr, CurrencyRmb, CurrencyBgn:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("group: invalid enum value for currency field: %q", c)
|
||||
|
||||
@@ -69,6 +69,12 @@ type GroupDeleteOne struct {
|
||||
gd *GroupDelete
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the GroupDelete builder.
|
||||
func (gdo *GroupDeleteOne) Where(ps ...predicate.Group) *GroupDeleteOne {
|
||||
gdo.gd.mutation.Where(ps...)
|
||||
return gdo
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (gdo *GroupDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := gdo.gd.Exec(ctx)
|
||||
@@ -84,5 +90,7 @@ func (gdo *GroupDeleteOne) Exec(ctx context.Context) error {
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (gdo *GroupDeleteOne) ExecX(ctx context.Context) {
|
||||
gdo.gd.ExecX(ctx)
|
||||
if err := gdo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,11 +25,8 @@ import (
|
||||
// GroupQuery is the builder for querying Group entities.
|
||||
type GroupQuery struct {
|
||||
config
|
||||
limit *int
|
||||
offset *int
|
||||
unique *bool
|
||||
ctx *QueryContext
|
||||
order []OrderFunc
|
||||
fields []string
|
||||
inters []Interceptor
|
||||
predicates []predicate.Group
|
||||
withUsers *UserQuery
|
||||
@@ -51,20 +48,20 @@ func (gq *GroupQuery) Where(ps ...predicate.Group) *GroupQuery {
|
||||
|
||||
// Limit the number of records to be returned by this query.
|
||||
func (gq *GroupQuery) Limit(limit int) *GroupQuery {
|
||||
gq.limit = &limit
|
||||
gq.ctx.Limit = &limit
|
||||
return gq
|
||||
}
|
||||
|
||||
// Offset to start from.
|
||||
func (gq *GroupQuery) Offset(offset int) *GroupQuery {
|
||||
gq.offset = &offset
|
||||
gq.ctx.Offset = &offset
|
||||
return gq
|
||||
}
|
||||
|
||||
// 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 (gq *GroupQuery) Unique(unique bool) *GroupQuery {
|
||||
gq.unique = &unique
|
||||
gq.ctx.Unique = &unique
|
||||
return gq
|
||||
}
|
||||
|
||||
@@ -209,7 +206,7 @@ func (gq *GroupQuery) QueryInvitationTokens() *GroupInvitationTokenQuery {
|
||||
// First returns the first Group entity from the query.
|
||||
// Returns a *NotFoundError when no Group was found.
|
||||
func (gq *GroupQuery) First(ctx context.Context) (*Group, error) {
|
||||
nodes, err := gq.Limit(1).All(newQueryContext(ctx, TypeGroup, "First"))
|
||||
nodes, err := gq.Limit(1).All(setContextOp(ctx, gq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -232,7 +229,7 @@ func (gq *GroupQuery) FirstX(ctx context.Context) *Group {
|
||||
// Returns a *NotFoundError when no Group ID was found.
|
||||
func (gq *GroupQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = gq.Limit(1).IDs(newQueryContext(ctx, TypeGroup, "FirstID")); err != nil {
|
||||
if ids, err = gq.Limit(1).IDs(setContextOp(ctx, gq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -255,7 +252,7 @@ func (gq *GroupQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one Group entity is found.
|
||||
// Returns a *NotFoundError when no Group entities are found.
|
||||
func (gq *GroupQuery) Only(ctx context.Context) (*Group, error) {
|
||||
nodes, err := gq.Limit(2).All(newQueryContext(ctx, TypeGroup, "Only"))
|
||||
nodes, err := gq.Limit(2).All(setContextOp(ctx, gq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -283,7 +280,7 @@ func (gq *GroupQuery) OnlyX(ctx context.Context) *Group {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (gq *GroupQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = gq.Limit(2).IDs(newQueryContext(ctx, TypeGroup, "OnlyID")); err != nil {
|
||||
if ids, err = gq.Limit(2).IDs(setContextOp(ctx, gq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -308,7 +305,7 @@ func (gq *GroupQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of Groups.
|
||||
func (gq *GroupQuery) All(ctx context.Context) ([]*Group, error) {
|
||||
ctx = newQueryContext(ctx, TypeGroup, "All")
|
||||
ctx = setContextOp(ctx, gq.ctx, "All")
|
||||
if err := gq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -328,7 +325,7 @@ func (gq *GroupQuery) AllX(ctx context.Context) []*Group {
|
||||
// IDs executes the query and returns a list of Group IDs.
|
||||
func (gq *GroupQuery) IDs(ctx context.Context) ([]uuid.UUID, error) {
|
||||
var ids []uuid.UUID
|
||||
ctx = newQueryContext(ctx, TypeGroup, "IDs")
|
||||
ctx = setContextOp(ctx, gq.ctx, "IDs")
|
||||
if err := gq.Select(group.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -346,7 +343,7 @@ func (gq *GroupQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (gq *GroupQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = newQueryContext(ctx, TypeGroup, "Count")
|
||||
ctx = setContextOp(ctx, gq.ctx, "Count")
|
||||
if err := gq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -364,7 +361,7 @@ func (gq *GroupQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (gq *GroupQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = newQueryContext(ctx, TypeGroup, "Exist")
|
||||
ctx = setContextOp(ctx, gq.ctx, "Exist")
|
||||
switch _, err := gq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -392,8 +389,7 @@ func (gq *GroupQuery) Clone() *GroupQuery {
|
||||
}
|
||||
return &GroupQuery{
|
||||
config: gq.config,
|
||||
limit: gq.limit,
|
||||
offset: gq.offset,
|
||||
ctx: gq.ctx.Clone(),
|
||||
order: append([]OrderFunc{}, gq.order...),
|
||||
inters: append([]Interceptor{}, gq.inters...),
|
||||
predicates: append([]predicate.Group{}, gq.predicates...),
|
||||
@@ -404,9 +400,8 @@ func (gq *GroupQuery) Clone() *GroupQuery {
|
||||
withDocuments: gq.withDocuments.Clone(),
|
||||
withInvitationTokens: gq.withInvitationTokens.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: gq.sql.Clone(),
|
||||
path: gq.path,
|
||||
unique: gq.unique,
|
||||
sql: gq.sql.Clone(),
|
||||
path: gq.path,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -491,9 +486,9 @@ func (gq *GroupQuery) WithInvitationTokens(opts ...func(*GroupInvitationTokenQue
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (gq *GroupQuery) GroupBy(field string, fields ...string) *GroupGroupBy {
|
||||
gq.fields = append([]string{field}, fields...)
|
||||
gq.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &GroupGroupBy{build: gq}
|
||||
grbuild.flds = &gq.fields
|
||||
grbuild.flds = &gq.ctx.Fields
|
||||
grbuild.label = group.Label
|
||||
grbuild.scan = grbuild.Scan
|
||||
return grbuild
|
||||
@@ -512,10 +507,10 @@ func (gq *GroupQuery) GroupBy(field string, fields ...string) *GroupGroupBy {
|
||||
// Select(group.FieldCreatedAt).
|
||||
// Scan(ctx, &v)
|
||||
func (gq *GroupQuery) Select(fields ...string) *GroupSelect {
|
||||
gq.fields = append(gq.fields, fields...)
|
||||
gq.ctx.Fields = append(gq.ctx.Fields, fields...)
|
||||
sbuild := &GroupSelect{GroupQuery: gq}
|
||||
sbuild.label = group.Label
|
||||
sbuild.flds, sbuild.scan = &gq.fields, sbuild.Scan
|
||||
sbuild.flds, sbuild.scan = &gq.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
@@ -535,7 +530,7 @@ func (gq *GroupQuery) prepareQuery(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range gq.fields {
|
||||
for _, f := range gq.ctx.Fields {
|
||||
if !group.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
@@ -817,9 +812,9 @@ func (gq *GroupQuery) loadInvitationTokens(ctx context.Context, query *GroupInvi
|
||||
|
||||
func (gq *GroupQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := gq.querySpec()
|
||||
_spec.Node.Columns = gq.fields
|
||||
if len(gq.fields) > 0 {
|
||||
_spec.Unique = gq.unique != nil && *gq.unique
|
||||
_spec.Node.Columns = gq.ctx.Fields
|
||||
if len(gq.ctx.Fields) > 0 {
|
||||
_spec.Unique = gq.ctx.Unique != nil && *gq.ctx.Unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, gq.driver, _spec)
|
||||
}
|
||||
@@ -837,10 +832,10 @@ func (gq *GroupQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
From: gq.sql,
|
||||
Unique: true,
|
||||
}
|
||||
if unique := gq.unique; unique != nil {
|
||||
if unique := gq.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
}
|
||||
if fields := gq.fields; len(fields) > 0 {
|
||||
if fields := gq.ctx.Fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, group.FieldID)
|
||||
for i := range fields {
|
||||
@@ -856,10 +851,10 @@ func (gq *GroupQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := gq.limit; limit != nil {
|
||||
if limit := gq.ctx.Limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := gq.offset; offset != nil {
|
||||
if offset := gq.ctx.Offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := gq.order; len(ps) > 0 {
|
||||
@@ -875,7 +870,7 @@ func (gq *GroupQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
func (gq *GroupQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(gq.driver.Dialect())
|
||||
t1 := builder.Table(group.Table)
|
||||
columns := gq.fields
|
||||
columns := gq.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = group.Columns
|
||||
}
|
||||
@@ -884,7 +879,7 @@ func (gq *GroupQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
selector = gq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if gq.unique != nil && *gq.unique {
|
||||
if gq.ctx.Unique != nil && *gq.ctx.Unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, p := range gq.predicates {
|
||||
@@ -893,12 +888,12 @@ func (gq *GroupQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
for _, p := range gq.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := gq.offset; offset != nil {
|
||||
if offset := gq.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 := gq.limit; limit != nil {
|
||||
if limit := gq.ctx.Limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
@@ -918,7 +913,7 @@ func (ggb *GroupGroupBy) Aggregate(fns ...AggregateFunc) *GroupGroupBy {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ggb *GroupGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeGroup, "GroupBy")
|
||||
ctx = setContextOp(ctx, ggb.build.ctx, "GroupBy")
|
||||
if err := ggb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -966,7 +961,7 @@ func (gs *GroupSelect) Aggregate(fns ...AggregateFunc) *GroupSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (gs *GroupSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeGroup, "Select")
|
||||
ctx = setContextOp(ctx, gs.ctx, "Select")
|
||||
if err := gs.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -136,14 +136,14 @@ func (git *GroupInvitationToken) assignValues(columns []string, values []any) er
|
||||
|
||||
// QueryGroup queries the "group" edge of the GroupInvitationToken entity.
|
||||
func (git *GroupInvitationToken) QueryGroup() *GroupQuery {
|
||||
return (&GroupInvitationTokenClient{config: git.config}).QueryGroup(git)
|
||||
return NewGroupInvitationTokenClient(git.config).QueryGroup(git)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this GroupInvitationToken.
|
||||
// Note that you need to call GroupInvitationToken.Unwrap() before calling this method if this GroupInvitationToken
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (git *GroupInvitationToken) Update() *GroupInvitationTokenUpdateOne {
|
||||
return (&GroupInvitationTokenClient{config: git.config}).UpdateOne(git)
|
||||
return NewGroupInvitationTokenClient(git.config).UpdateOne(git)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the GroupInvitationToken entity that was returned from a transaction after it was closed,
|
||||
|
||||
@@ -69,6 +69,12 @@ type GroupInvitationTokenDeleteOne struct {
|
||||
gitd *GroupInvitationTokenDelete
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the GroupInvitationTokenDelete builder.
|
||||
func (gitdo *GroupInvitationTokenDeleteOne) Where(ps ...predicate.GroupInvitationToken) *GroupInvitationTokenDeleteOne {
|
||||
gitdo.gitd.mutation.Where(ps...)
|
||||
return gitdo
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (gitdo *GroupInvitationTokenDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := gitdo.gitd.Exec(ctx)
|
||||
@@ -84,5 +90,7 @@ func (gitdo *GroupInvitationTokenDeleteOne) Exec(ctx context.Context) error {
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (gitdo *GroupInvitationTokenDeleteOne) ExecX(ctx context.Context) {
|
||||
gitdo.gitd.ExecX(ctx)
|
||||
if err := gitdo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,11 +19,8 @@ import (
|
||||
// GroupInvitationTokenQuery is the builder for querying GroupInvitationToken entities.
|
||||
type GroupInvitationTokenQuery struct {
|
||||
config
|
||||
limit *int
|
||||
offset *int
|
||||
unique *bool
|
||||
ctx *QueryContext
|
||||
order []OrderFunc
|
||||
fields []string
|
||||
inters []Interceptor
|
||||
predicates []predicate.GroupInvitationToken
|
||||
withGroup *GroupQuery
|
||||
@@ -41,20 +38,20 @@ func (gitq *GroupInvitationTokenQuery) Where(ps ...predicate.GroupInvitationToke
|
||||
|
||||
// Limit the number of records to be returned by this query.
|
||||
func (gitq *GroupInvitationTokenQuery) Limit(limit int) *GroupInvitationTokenQuery {
|
||||
gitq.limit = &limit
|
||||
gitq.ctx.Limit = &limit
|
||||
return gitq
|
||||
}
|
||||
|
||||
// Offset to start from.
|
||||
func (gitq *GroupInvitationTokenQuery) Offset(offset int) *GroupInvitationTokenQuery {
|
||||
gitq.offset = &offset
|
||||
gitq.ctx.Offset = &offset
|
||||
return gitq
|
||||
}
|
||||
|
||||
// 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 (gitq *GroupInvitationTokenQuery) Unique(unique bool) *GroupInvitationTokenQuery {
|
||||
gitq.unique = &unique
|
||||
gitq.ctx.Unique = &unique
|
||||
return gitq
|
||||
}
|
||||
|
||||
@@ -89,7 +86,7 @@ func (gitq *GroupInvitationTokenQuery) QueryGroup() *GroupQuery {
|
||||
// First returns the first GroupInvitationToken entity from the query.
|
||||
// Returns a *NotFoundError when no GroupInvitationToken was found.
|
||||
func (gitq *GroupInvitationTokenQuery) First(ctx context.Context) (*GroupInvitationToken, error) {
|
||||
nodes, err := gitq.Limit(1).All(newQueryContext(ctx, TypeGroupInvitationToken, "First"))
|
||||
nodes, err := gitq.Limit(1).All(setContextOp(ctx, gitq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -112,7 +109,7 @@ func (gitq *GroupInvitationTokenQuery) FirstX(ctx context.Context) *GroupInvitat
|
||||
// Returns a *NotFoundError when no GroupInvitationToken ID was found.
|
||||
func (gitq *GroupInvitationTokenQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = gitq.Limit(1).IDs(newQueryContext(ctx, TypeGroupInvitationToken, "FirstID")); err != nil {
|
||||
if ids, err = gitq.Limit(1).IDs(setContextOp(ctx, gitq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -135,7 +132,7 @@ func (gitq *GroupInvitationTokenQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one GroupInvitationToken entity is found.
|
||||
// Returns a *NotFoundError when no GroupInvitationToken entities are found.
|
||||
func (gitq *GroupInvitationTokenQuery) Only(ctx context.Context) (*GroupInvitationToken, error) {
|
||||
nodes, err := gitq.Limit(2).All(newQueryContext(ctx, TypeGroupInvitationToken, "Only"))
|
||||
nodes, err := gitq.Limit(2).All(setContextOp(ctx, gitq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -163,7 +160,7 @@ func (gitq *GroupInvitationTokenQuery) OnlyX(ctx context.Context) *GroupInvitati
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (gitq *GroupInvitationTokenQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = gitq.Limit(2).IDs(newQueryContext(ctx, TypeGroupInvitationToken, "OnlyID")); err != nil {
|
||||
if ids, err = gitq.Limit(2).IDs(setContextOp(ctx, gitq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -188,7 +185,7 @@ func (gitq *GroupInvitationTokenQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of GroupInvitationTokens.
|
||||
func (gitq *GroupInvitationTokenQuery) All(ctx context.Context) ([]*GroupInvitationToken, error) {
|
||||
ctx = newQueryContext(ctx, TypeGroupInvitationToken, "All")
|
||||
ctx = setContextOp(ctx, gitq.ctx, "All")
|
||||
if err := gitq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -208,7 +205,7 @@ func (gitq *GroupInvitationTokenQuery) AllX(ctx context.Context) []*GroupInvitat
|
||||
// IDs executes the query and returns a list of GroupInvitationToken IDs.
|
||||
func (gitq *GroupInvitationTokenQuery) IDs(ctx context.Context) ([]uuid.UUID, error) {
|
||||
var ids []uuid.UUID
|
||||
ctx = newQueryContext(ctx, TypeGroupInvitationToken, "IDs")
|
||||
ctx = setContextOp(ctx, gitq.ctx, "IDs")
|
||||
if err := gitq.Select(groupinvitationtoken.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -226,7 +223,7 @@ func (gitq *GroupInvitationTokenQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (gitq *GroupInvitationTokenQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = newQueryContext(ctx, TypeGroupInvitationToken, "Count")
|
||||
ctx = setContextOp(ctx, gitq.ctx, "Count")
|
||||
if err := gitq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -244,7 +241,7 @@ func (gitq *GroupInvitationTokenQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (gitq *GroupInvitationTokenQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = newQueryContext(ctx, TypeGroupInvitationToken, "Exist")
|
||||
ctx = setContextOp(ctx, gitq.ctx, "Exist")
|
||||
switch _, err := gitq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -272,16 +269,14 @@ func (gitq *GroupInvitationTokenQuery) Clone() *GroupInvitationTokenQuery {
|
||||
}
|
||||
return &GroupInvitationTokenQuery{
|
||||
config: gitq.config,
|
||||
limit: gitq.limit,
|
||||
offset: gitq.offset,
|
||||
ctx: gitq.ctx.Clone(),
|
||||
order: append([]OrderFunc{}, gitq.order...),
|
||||
inters: append([]Interceptor{}, gitq.inters...),
|
||||
predicates: append([]predicate.GroupInvitationToken{}, gitq.predicates...),
|
||||
withGroup: gitq.withGroup.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: gitq.sql.Clone(),
|
||||
path: gitq.path,
|
||||
unique: gitq.unique,
|
||||
sql: gitq.sql.Clone(),
|
||||
path: gitq.path,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,9 +306,9 @@ func (gitq *GroupInvitationTokenQuery) WithGroup(opts ...func(*GroupQuery)) *Gro
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (gitq *GroupInvitationTokenQuery) GroupBy(field string, fields ...string) *GroupInvitationTokenGroupBy {
|
||||
gitq.fields = append([]string{field}, fields...)
|
||||
gitq.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &GroupInvitationTokenGroupBy{build: gitq}
|
||||
grbuild.flds = &gitq.fields
|
||||
grbuild.flds = &gitq.ctx.Fields
|
||||
grbuild.label = groupinvitationtoken.Label
|
||||
grbuild.scan = grbuild.Scan
|
||||
return grbuild
|
||||
@@ -332,10 +327,10 @@ func (gitq *GroupInvitationTokenQuery) GroupBy(field string, fields ...string) *
|
||||
// Select(groupinvitationtoken.FieldCreatedAt).
|
||||
// Scan(ctx, &v)
|
||||
func (gitq *GroupInvitationTokenQuery) Select(fields ...string) *GroupInvitationTokenSelect {
|
||||
gitq.fields = append(gitq.fields, fields...)
|
||||
gitq.ctx.Fields = append(gitq.ctx.Fields, fields...)
|
||||
sbuild := &GroupInvitationTokenSelect{GroupInvitationTokenQuery: gitq}
|
||||
sbuild.label = groupinvitationtoken.Label
|
||||
sbuild.flds, sbuild.scan = &gitq.fields, sbuild.Scan
|
||||
sbuild.flds, sbuild.scan = &gitq.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
@@ -355,7 +350,7 @@ func (gitq *GroupInvitationTokenQuery) prepareQuery(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range gitq.fields {
|
||||
for _, f := range gitq.ctx.Fields {
|
||||
if !groupinvitationtoken.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
@@ -425,6 +420,9 @@ func (gitq *GroupInvitationTokenQuery) loadGroup(ctx context.Context, query *Gro
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
query.Where(group.IDIn(ids...))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
@@ -444,9 +442,9 @@ func (gitq *GroupInvitationTokenQuery) loadGroup(ctx context.Context, query *Gro
|
||||
|
||||
func (gitq *GroupInvitationTokenQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := gitq.querySpec()
|
||||
_spec.Node.Columns = gitq.fields
|
||||
if len(gitq.fields) > 0 {
|
||||
_spec.Unique = gitq.unique != nil && *gitq.unique
|
||||
_spec.Node.Columns = gitq.ctx.Fields
|
||||
if len(gitq.ctx.Fields) > 0 {
|
||||
_spec.Unique = gitq.ctx.Unique != nil && *gitq.ctx.Unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, gitq.driver, _spec)
|
||||
}
|
||||
@@ -464,10 +462,10 @@ func (gitq *GroupInvitationTokenQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
From: gitq.sql,
|
||||
Unique: true,
|
||||
}
|
||||
if unique := gitq.unique; unique != nil {
|
||||
if unique := gitq.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
}
|
||||
if fields := gitq.fields; len(fields) > 0 {
|
||||
if fields := gitq.ctx.Fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, groupinvitationtoken.FieldID)
|
||||
for i := range fields {
|
||||
@@ -483,10 +481,10 @@ func (gitq *GroupInvitationTokenQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := gitq.limit; limit != nil {
|
||||
if limit := gitq.ctx.Limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := gitq.offset; offset != nil {
|
||||
if offset := gitq.ctx.Offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := gitq.order; len(ps) > 0 {
|
||||
@@ -502,7 +500,7 @@ func (gitq *GroupInvitationTokenQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
func (gitq *GroupInvitationTokenQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(gitq.driver.Dialect())
|
||||
t1 := builder.Table(groupinvitationtoken.Table)
|
||||
columns := gitq.fields
|
||||
columns := gitq.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = groupinvitationtoken.Columns
|
||||
}
|
||||
@@ -511,7 +509,7 @@ func (gitq *GroupInvitationTokenQuery) sqlQuery(ctx context.Context) *sql.Select
|
||||
selector = gitq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if gitq.unique != nil && *gitq.unique {
|
||||
if gitq.ctx.Unique != nil && *gitq.ctx.Unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, p := range gitq.predicates {
|
||||
@@ -520,12 +518,12 @@ func (gitq *GroupInvitationTokenQuery) sqlQuery(ctx context.Context) *sql.Select
|
||||
for _, p := range gitq.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := gitq.offset; offset != nil {
|
||||
if offset := gitq.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 := gitq.limit; limit != nil {
|
||||
if limit := gitq.ctx.Limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
@@ -545,7 +543,7 @@ func (gitgb *GroupInvitationTokenGroupBy) Aggregate(fns ...AggregateFunc) *Group
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (gitgb *GroupInvitationTokenGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeGroupInvitationToken, "GroupBy")
|
||||
ctx = setContextOp(ctx, gitgb.build.ctx, "GroupBy")
|
||||
if err := gitgb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -593,7 +591,7 @@ func (gits *GroupInvitationTokenSelect) Aggregate(fns ...AggregateFunc) *GroupIn
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (gits *GroupInvitationTokenSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeGroupInvitationToken, "Select")
|
||||
ctx = setContextOp(ctx, gits.ctx, "Select")
|
||||
if err := gits.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -390,49 +390,49 @@ func (i *Item) assignValues(columns []string, values []any) error {
|
||||
|
||||
// QueryParent queries the "parent" edge of the Item entity.
|
||||
func (i *Item) QueryParent() *ItemQuery {
|
||||
return (&ItemClient{config: i.config}).QueryParent(i)
|
||||
return NewItemClient(i.config).QueryParent(i)
|
||||
}
|
||||
|
||||
// QueryChildren queries the "children" edge of the Item entity.
|
||||
func (i *Item) QueryChildren() *ItemQuery {
|
||||
return (&ItemClient{config: i.config}).QueryChildren(i)
|
||||
return NewItemClient(i.config).QueryChildren(i)
|
||||
}
|
||||
|
||||
// QueryGroup queries the "group" edge of the Item entity.
|
||||
func (i *Item) QueryGroup() *GroupQuery {
|
||||
return (&ItemClient{config: i.config}).QueryGroup(i)
|
||||
return NewItemClient(i.config).QueryGroup(i)
|
||||
}
|
||||
|
||||
// QueryLabel queries the "label" edge of the Item entity.
|
||||
func (i *Item) QueryLabel() *LabelQuery {
|
||||
return (&ItemClient{config: i.config}).QueryLabel(i)
|
||||
return NewItemClient(i.config).QueryLabel(i)
|
||||
}
|
||||
|
||||
// QueryLocation queries the "location" edge of the Item entity.
|
||||
func (i *Item) QueryLocation() *LocationQuery {
|
||||
return (&ItemClient{config: i.config}).QueryLocation(i)
|
||||
return NewItemClient(i.config).QueryLocation(i)
|
||||
}
|
||||
|
||||
// QueryFields queries the "fields" edge of the Item entity.
|
||||
func (i *Item) QueryFields() *ItemFieldQuery {
|
||||
return (&ItemClient{config: i.config}).QueryFields(i)
|
||||
return NewItemClient(i.config).QueryFields(i)
|
||||
}
|
||||
|
||||
// QueryMaintenanceEntries queries the "maintenance_entries" edge of the Item entity.
|
||||
func (i *Item) QueryMaintenanceEntries() *MaintenanceEntryQuery {
|
||||
return (&ItemClient{config: i.config}).QueryMaintenanceEntries(i)
|
||||
return NewItemClient(i.config).QueryMaintenanceEntries(i)
|
||||
}
|
||||
|
||||
// QueryAttachments queries the "attachments" edge of the Item entity.
|
||||
func (i *Item) QueryAttachments() *AttachmentQuery {
|
||||
return (&ItemClient{config: i.config}).QueryAttachments(i)
|
||||
return NewItemClient(i.config).QueryAttachments(i)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this Item.
|
||||
// Note that you need to call Item.Unwrap() before calling this method if this Item
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (i *Item) Update() *ItemUpdateOne {
|
||||
return (&ItemClient{config: i.config}).UpdateOne(i)
|
||||
return NewItemClient(i.config).UpdateOne(i)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the Item entity that was returned from a transaction after it was closed,
|
||||
|
||||
@@ -69,6 +69,12 @@ type ItemDeleteOne struct {
|
||||
id *ItemDelete
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the ItemDelete builder.
|
||||
func (ido *ItemDeleteOne) Where(ps ...predicate.Item) *ItemDeleteOne {
|
||||
ido.id.mutation.Where(ps...)
|
||||
return ido
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (ido *ItemDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := ido.id.Exec(ctx)
|
||||
@@ -84,5 +90,7 @@ func (ido *ItemDeleteOne) Exec(ctx context.Context) error {
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (ido *ItemDeleteOne) ExecX(ctx context.Context) {
|
||||
ido.id.ExecX(ctx)
|
||||
if err := ido.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,11 +25,8 @@ import (
|
||||
// ItemQuery is the builder for querying Item entities.
|
||||
type ItemQuery struct {
|
||||
config
|
||||
limit *int
|
||||
offset *int
|
||||
unique *bool
|
||||
ctx *QueryContext
|
||||
order []OrderFunc
|
||||
fields []string
|
||||
inters []Interceptor
|
||||
predicates []predicate.Item
|
||||
withParent *ItemQuery
|
||||
@@ -54,20 +51,20 @@ func (iq *ItemQuery) Where(ps ...predicate.Item) *ItemQuery {
|
||||
|
||||
// Limit the number of records to be returned by this query.
|
||||
func (iq *ItemQuery) Limit(limit int) *ItemQuery {
|
||||
iq.limit = &limit
|
||||
iq.ctx.Limit = &limit
|
||||
return iq
|
||||
}
|
||||
|
||||
// Offset to start from.
|
||||
func (iq *ItemQuery) Offset(offset int) *ItemQuery {
|
||||
iq.offset = &offset
|
||||
iq.ctx.Offset = &offset
|
||||
return iq
|
||||
}
|
||||
|
||||
// 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 (iq *ItemQuery) Unique(unique bool) *ItemQuery {
|
||||
iq.unique = &unique
|
||||
iq.ctx.Unique = &unique
|
||||
return iq
|
||||
}
|
||||
|
||||
@@ -256,7 +253,7 @@ func (iq *ItemQuery) QueryAttachments() *AttachmentQuery {
|
||||
// First returns the first Item entity from the query.
|
||||
// Returns a *NotFoundError when no Item was found.
|
||||
func (iq *ItemQuery) First(ctx context.Context) (*Item, error) {
|
||||
nodes, err := iq.Limit(1).All(newQueryContext(ctx, TypeItem, "First"))
|
||||
nodes, err := iq.Limit(1).All(setContextOp(ctx, iq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -279,7 +276,7 @@ func (iq *ItemQuery) FirstX(ctx context.Context) *Item {
|
||||
// Returns a *NotFoundError when no Item ID was found.
|
||||
func (iq *ItemQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = iq.Limit(1).IDs(newQueryContext(ctx, TypeItem, "FirstID")); err != nil {
|
||||
if ids, err = iq.Limit(1).IDs(setContextOp(ctx, iq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -302,7 +299,7 @@ func (iq *ItemQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one Item entity is found.
|
||||
// Returns a *NotFoundError when no Item entities are found.
|
||||
func (iq *ItemQuery) Only(ctx context.Context) (*Item, error) {
|
||||
nodes, err := iq.Limit(2).All(newQueryContext(ctx, TypeItem, "Only"))
|
||||
nodes, err := iq.Limit(2).All(setContextOp(ctx, iq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -330,7 +327,7 @@ func (iq *ItemQuery) OnlyX(ctx context.Context) *Item {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (iq *ItemQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = iq.Limit(2).IDs(newQueryContext(ctx, TypeItem, "OnlyID")); err != nil {
|
||||
if ids, err = iq.Limit(2).IDs(setContextOp(ctx, iq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -355,7 +352,7 @@ func (iq *ItemQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of Items.
|
||||
func (iq *ItemQuery) All(ctx context.Context) ([]*Item, error) {
|
||||
ctx = newQueryContext(ctx, TypeItem, "All")
|
||||
ctx = setContextOp(ctx, iq.ctx, "All")
|
||||
if err := iq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -375,7 +372,7 @@ func (iq *ItemQuery) AllX(ctx context.Context) []*Item {
|
||||
// IDs executes the query and returns a list of Item IDs.
|
||||
func (iq *ItemQuery) IDs(ctx context.Context) ([]uuid.UUID, error) {
|
||||
var ids []uuid.UUID
|
||||
ctx = newQueryContext(ctx, TypeItem, "IDs")
|
||||
ctx = setContextOp(ctx, iq.ctx, "IDs")
|
||||
if err := iq.Select(item.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -393,7 +390,7 @@ func (iq *ItemQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (iq *ItemQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = newQueryContext(ctx, TypeItem, "Count")
|
||||
ctx = setContextOp(ctx, iq.ctx, "Count")
|
||||
if err := iq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -411,7 +408,7 @@ func (iq *ItemQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (iq *ItemQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = newQueryContext(ctx, TypeItem, "Exist")
|
||||
ctx = setContextOp(ctx, iq.ctx, "Exist")
|
||||
switch _, err := iq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -439,8 +436,7 @@ func (iq *ItemQuery) Clone() *ItemQuery {
|
||||
}
|
||||
return &ItemQuery{
|
||||
config: iq.config,
|
||||
limit: iq.limit,
|
||||
offset: iq.offset,
|
||||
ctx: iq.ctx.Clone(),
|
||||
order: append([]OrderFunc{}, iq.order...),
|
||||
inters: append([]Interceptor{}, iq.inters...),
|
||||
predicates: append([]predicate.Item{}, iq.predicates...),
|
||||
@@ -453,9 +449,8 @@ func (iq *ItemQuery) Clone() *ItemQuery {
|
||||
withMaintenanceEntries: iq.withMaintenanceEntries.Clone(),
|
||||
withAttachments: iq.withAttachments.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: iq.sql.Clone(),
|
||||
path: iq.path,
|
||||
unique: iq.unique,
|
||||
sql: iq.sql.Clone(),
|
||||
path: iq.path,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,9 +557,9 @@ func (iq *ItemQuery) WithAttachments(opts ...func(*AttachmentQuery)) *ItemQuery
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (iq *ItemQuery) GroupBy(field string, fields ...string) *ItemGroupBy {
|
||||
iq.fields = append([]string{field}, fields...)
|
||||
iq.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &ItemGroupBy{build: iq}
|
||||
grbuild.flds = &iq.fields
|
||||
grbuild.flds = &iq.ctx.Fields
|
||||
grbuild.label = item.Label
|
||||
grbuild.scan = grbuild.Scan
|
||||
return grbuild
|
||||
@@ -583,10 +578,10 @@ func (iq *ItemQuery) GroupBy(field string, fields ...string) *ItemGroupBy {
|
||||
// Select(item.FieldCreatedAt).
|
||||
// Scan(ctx, &v)
|
||||
func (iq *ItemQuery) Select(fields ...string) *ItemSelect {
|
||||
iq.fields = append(iq.fields, fields...)
|
||||
iq.ctx.Fields = append(iq.ctx.Fields, fields...)
|
||||
sbuild := &ItemSelect{ItemQuery: iq}
|
||||
sbuild.label = item.Label
|
||||
sbuild.flds, sbuild.scan = &iq.fields, sbuild.Scan
|
||||
sbuild.flds, sbuild.scan = &iq.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
@@ -606,7 +601,7 @@ func (iq *ItemQuery) prepareQuery(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range iq.fields {
|
||||
for _, f := range iq.ctx.Fields {
|
||||
if !item.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
@@ -730,6 +725,9 @@ func (iq *ItemQuery) loadParent(ctx context.Context, query *ItemQuery, nodes []*
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
query.Where(item.IDIn(ids...))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
@@ -790,6 +788,9 @@ func (iq *ItemQuery) loadGroup(ctx context.Context, query *GroupQuery, nodes []*
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
query.Where(group.IDIn(ids...))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
@@ -829,27 +830,30 @@ func (iq *ItemQuery) loadLabel(ctx context.Context, query *LabelQuery, nodes []*
|
||||
if err := query.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
neighbors, err := query.sqlAll(ctx, func(_ context.Context, spec *sqlgraph.QuerySpec) {
|
||||
assign := spec.Assign
|
||||
values := spec.ScanValues
|
||||
spec.ScanValues = func(columns []string) ([]any, error) {
|
||||
values, err := values(columns[1:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
qr := QuerierFunc(func(ctx context.Context, q Query) (Value, error) {
|
||||
return query.sqlAll(ctx, func(_ context.Context, spec *sqlgraph.QuerySpec) {
|
||||
assign := spec.Assign
|
||||
values := spec.ScanValues
|
||||
spec.ScanValues = func(columns []string) ([]any, error) {
|
||||
values, err := values(columns[1:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return append([]any{new(uuid.UUID)}, values...), nil
|
||||
}
|
||||
return append([]any{new(uuid.UUID)}, values...), nil
|
||||
}
|
||||
spec.Assign = func(columns []string, values []any) error {
|
||||
outValue := *values[0].(*uuid.UUID)
|
||||
inValue := *values[1].(*uuid.UUID)
|
||||
if nids[inValue] == nil {
|
||||
nids[inValue] = map[*Item]struct{}{byID[outValue]: {}}
|
||||
return assign(columns[1:], values[1:])
|
||||
spec.Assign = func(columns []string, values []any) error {
|
||||
outValue := *values[0].(*uuid.UUID)
|
||||
inValue := *values[1].(*uuid.UUID)
|
||||
if nids[inValue] == nil {
|
||||
nids[inValue] = map[*Item]struct{}{byID[outValue]: {}}
|
||||
return assign(columns[1:], values[1:])
|
||||
}
|
||||
nids[inValue][byID[outValue]] = struct{}{}
|
||||
return nil
|
||||
}
|
||||
nids[inValue][byID[outValue]] = struct{}{}
|
||||
return nil
|
||||
}
|
||||
})
|
||||
})
|
||||
neighbors, err := withInterceptors[[]*Label](ctx, query, qr, query.inters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -877,6 +881,9 @@ func (iq *ItemQuery) loadLocation(ctx context.Context, query *LocationQuery, nod
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
query.Where(location.IDIn(ids...))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
@@ -985,9 +992,9 @@ func (iq *ItemQuery) loadAttachments(ctx context.Context, query *AttachmentQuery
|
||||
|
||||
func (iq *ItemQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := iq.querySpec()
|
||||
_spec.Node.Columns = iq.fields
|
||||
if len(iq.fields) > 0 {
|
||||
_spec.Unique = iq.unique != nil && *iq.unique
|
||||
_spec.Node.Columns = iq.ctx.Fields
|
||||
if len(iq.ctx.Fields) > 0 {
|
||||
_spec.Unique = iq.ctx.Unique != nil && *iq.ctx.Unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, iq.driver, _spec)
|
||||
}
|
||||
@@ -1005,10 +1012,10 @@ func (iq *ItemQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
From: iq.sql,
|
||||
Unique: true,
|
||||
}
|
||||
if unique := iq.unique; unique != nil {
|
||||
if unique := iq.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
}
|
||||
if fields := iq.fields; len(fields) > 0 {
|
||||
if fields := iq.ctx.Fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, item.FieldID)
|
||||
for i := range fields {
|
||||
@@ -1024,10 +1031,10 @@ func (iq *ItemQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := iq.limit; limit != nil {
|
||||
if limit := iq.ctx.Limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := iq.offset; offset != nil {
|
||||
if offset := iq.ctx.Offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := iq.order; len(ps) > 0 {
|
||||
@@ -1043,7 +1050,7 @@ func (iq *ItemQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
func (iq *ItemQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(iq.driver.Dialect())
|
||||
t1 := builder.Table(item.Table)
|
||||
columns := iq.fields
|
||||
columns := iq.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = item.Columns
|
||||
}
|
||||
@@ -1052,7 +1059,7 @@ func (iq *ItemQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
selector = iq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if iq.unique != nil && *iq.unique {
|
||||
if iq.ctx.Unique != nil && *iq.ctx.Unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, p := range iq.predicates {
|
||||
@@ -1061,12 +1068,12 @@ func (iq *ItemQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
for _, p := range iq.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := iq.offset; offset != nil {
|
||||
if offset := iq.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 := iq.limit; limit != nil {
|
||||
if limit := iq.ctx.Limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
@@ -1086,7 +1093,7 @@ func (igb *ItemGroupBy) Aggregate(fns ...AggregateFunc) *ItemGroupBy {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (igb *ItemGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeItem, "GroupBy")
|
||||
ctx = setContextOp(ctx, igb.build.ctx, "GroupBy")
|
||||
if err := igb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1134,7 +1141,7 @@ func (is *ItemSelect) Aggregate(fns ...AggregateFunc) *ItemSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (is *ItemSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeItem, "Select")
|
||||
ctx = setContextOp(ctx, is.ctx, "Select")
|
||||
if err := is.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -170,14 +170,14 @@ func (_if *ItemField) assignValues(columns []string, values []any) error {
|
||||
|
||||
// QueryItem queries the "item" edge of the ItemField entity.
|
||||
func (_if *ItemField) QueryItem() *ItemQuery {
|
||||
return (&ItemFieldClient{config: _if.config}).QueryItem(_if)
|
||||
return NewItemFieldClient(_if.config).QueryItem(_if)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this ItemField.
|
||||
// Note that you need to call ItemField.Unwrap() before calling this method if this ItemField
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (_if *ItemField) Update() *ItemFieldUpdateOne {
|
||||
return (&ItemFieldClient{config: _if.config}).UpdateOne(_if)
|
||||
return NewItemFieldClient(_if.config).UpdateOne(_if)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the ItemField entity that was returned from a transaction after it was closed,
|
||||
|
||||
@@ -69,6 +69,12 @@ type ItemFieldDeleteOne struct {
|
||||
ifd *ItemFieldDelete
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the ItemFieldDelete builder.
|
||||
func (ifdo *ItemFieldDeleteOne) Where(ps ...predicate.ItemField) *ItemFieldDeleteOne {
|
||||
ifdo.ifd.mutation.Where(ps...)
|
||||
return ifdo
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (ifdo *ItemFieldDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := ifdo.ifd.Exec(ctx)
|
||||
@@ -84,5 +90,7 @@ func (ifdo *ItemFieldDeleteOne) Exec(ctx context.Context) error {
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (ifdo *ItemFieldDeleteOne) ExecX(ctx context.Context) {
|
||||
ifdo.ifd.ExecX(ctx)
|
||||
if err := ifdo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,11 +19,8 @@ import (
|
||||
// ItemFieldQuery is the builder for querying ItemField entities.
|
||||
type ItemFieldQuery struct {
|
||||
config
|
||||
limit *int
|
||||
offset *int
|
||||
unique *bool
|
||||
ctx *QueryContext
|
||||
order []OrderFunc
|
||||
fields []string
|
||||
inters []Interceptor
|
||||
predicates []predicate.ItemField
|
||||
withItem *ItemQuery
|
||||
@@ -41,20 +38,20 @@ func (ifq *ItemFieldQuery) Where(ps ...predicate.ItemField) *ItemFieldQuery {
|
||||
|
||||
// Limit the number of records to be returned by this query.
|
||||
func (ifq *ItemFieldQuery) Limit(limit int) *ItemFieldQuery {
|
||||
ifq.limit = &limit
|
||||
ifq.ctx.Limit = &limit
|
||||
return ifq
|
||||
}
|
||||
|
||||
// Offset to start from.
|
||||
func (ifq *ItemFieldQuery) Offset(offset int) *ItemFieldQuery {
|
||||
ifq.offset = &offset
|
||||
ifq.ctx.Offset = &offset
|
||||
return ifq
|
||||
}
|
||||
|
||||
// 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 (ifq *ItemFieldQuery) Unique(unique bool) *ItemFieldQuery {
|
||||
ifq.unique = &unique
|
||||
ifq.ctx.Unique = &unique
|
||||
return ifq
|
||||
}
|
||||
|
||||
@@ -89,7 +86,7 @@ func (ifq *ItemFieldQuery) QueryItem() *ItemQuery {
|
||||
// First returns the first ItemField entity from the query.
|
||||
// Returns a *NotFoundError when no ItemField was found.
|
||||
func (ifq *ItemFieldQuery) First(ctx context.Context) (*ItemField, error) {
|
||||
nodes, err := ifq.Limit(1).All(newQueryContext(ctx, TypeItemField, "First"))
|
||||
nodes, err := ifq.Limit(1).All(setContextOp(ctx, ifq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -112,7 +109,7 @@ func (ifq *ItemFieldQuery) FirstX(ctx context.Context) *ItemField {
|
||||
// Returns a *NotFoundError when no ItemField ID was found.
|
||||
func (ifq *ItemFieldQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = ifq.Limit(1).IDs(newQueryContext(ctx, TypeItemField, "FirstID")); err != nil {
|
||||
if ids, err = ifq.Limit(1).IDs(setContextOp(ctx, ifq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -135,7 +132,7 @@ func (ifq *ItemFieldQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one ItemField entity is found.
|
||||
// Returns a *NotFoundError when no ItemField entities are found.
|
||||
func (ifq *ItemFieldQuery) Only(ctx context.Context) (*ItemField, error) {
|
||||
nodes, err := ifq.Limit(2).All(newQueryContext(ctx, TypeItemField, "Only"))
|
||||
nodes, err := ifq.Limit(2).All(setContextOp(ctx, ifq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -163,7 +160,7 @@ func (ifq *ItemFieldQuery) OnlyX(ctx context.Context) *ItemField {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (ifq *ItemFieldQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = ifq.Limit(2).IDs(newQueryContext(ctx, TypeItemField, "OnlyID")); err != nil {
|
||||
if ids, err = ifq.Limit(2).IDs(setContextOp(ctx, ifq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -188,7 +185,7 @@ func (ifq *ItemFieldQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of ItemFields.
|
||||
func (ifq *ItemFieldQuery) All(ctx context.Context) ([]*ItemField, error) {
|
||||
ctx = newQueryContext(ctx, TypeItemField, "All")
|
||||
ctx = setContextOp(ctx, ifq.ctx, "All")
|
||||
if err := ifq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -208,7 +205,7 @@ func (ifq *ItemFieldQuery) AllX(ctx context.Context) []*ItemField {
|
||||
// IDs executes the query and returns a list of ItemField IDs.
|
||||
func (ifq *ItemFieldQuery) IDs(ctx context.Context) ([]uuid.UUID, error) {
|
||||
var ids []uuid.UUID
|
||||
ctx = newQueryContext(ctx, TypeItemField, "IDs")
|
||||
ctx = setContextOp(ctx, ifq.ctx, "IDs")
|
||||
if err := ifq.Select(itemfield.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -226,7 +223,7 @@ func (ifq *ItemFieldQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (ifq *ItemFieldQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = newQueryContext(ctx, TypeItemField, "Count")
|
||||
ctx = setContextOp(ctx, ifq.ctx, "Count")
|
||||
if err := ifq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -244,7 +241,7 @@ func (ifq *ItemFieldQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (ifq *ItemFieldQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = newQueryContext(ctx, TypeItemField, "Exist")
|
||||
ctx = setContextOp(ctx, ifq.ctx, "Exist")
|
||||
switch _, err := ifq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -272,16 +269,14 @@ func (ifq *ItemFieldQuery) Clone() *ItemFieldQuery {
|
||||
}
|
||||
return &ItemFieldQuery{
|
||||
config: ifq.config,
|
||||
limit: ifq.limit,
|
||||
offset: ifq.offset,
|
||||
ctx: ifq.ctx.Clone(),
|
||||
order: append([]OrderFunc{}, ifq.order...),
|
||||
inters: append([]Interceptor{}, ifq.inters...),
|
||||
predicates: append([]predicate.ItemField{}, ifq.predicates...),
|
||||
withItem: ifq.withItem.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: ifq.sql.Clone(),
|
||||
path: ifq.path,
|
||||
unique: ifq.unique,
|
||||
sql: ifq.sql.Clone(),
|
||||
path: ifq.path,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,9 +306,9 @@ func (ifq *ItemFieldQuery) WithItem(opts ...func(*ItemQuery)) *ItemFieldQuery {
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (ifq *ItemFieldQuery) GroupBy(field string, fields ...string) *ItemFieldGroupBy {
|
||||
ifq.fields = append([]string{field}, fields...)
|
||||
ifq.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &ItemFieldGroupBy{build: ifq}
|
||||
grbuild.flds = &ifq.fields
|
||||
grbuild.flds = &ifq.ctx.Fields
|
||||
grbuild.label = itemfield.Label
|
||||
grbuild.scan = grbuild.Scan
|
||||
return grbuild
|
||||
@@ -332,10 +327,10 @@ func (ifq *ItemFieldQuery) GroupBy(field string, fields ...string) *ItemFieldGro
|
||||
// Select(itemfield.FieldCreatedAt).
|
||||
// Scan(ctx, &v)
|
||||
func (ifq *ItemFieldQuery) Select(fields ...string) *ItemFieldSelect {
|
||||
ifq.fields = append(ifq.fields, fields...)
|
||||
ifq.ctx.Fields = append(ifq.ctx.Fields, fields...)
|
||||
sbuild := &ItemFieldSelect{ItemFieldQuery: ifq}
|
||||
sbuild.label = itemfield.Label
|
||||
sbuild.flds, sbuild.scan = &ifq.fields, sbuild.Scan
|
||||
sbuild.flds, sbuild.scan = &ifq.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
@@ -355,7 +350,7 @@ func (ifq *ItemFieldQuery) prepareQuery(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range ifq.fields {
|
||||
for _, f := range ifq.ctx.Fields {
|
||||
if !itemfield.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
@@ -425,6 +420,9 @@ func (ifq *ItemFieldQuery) loadItem(ctx context.Context, query *ItemQuery, nodes
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
query.Where(item.IDIn(ids...))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
@@ -444,9 +442,9 @@ func (ifq *ItemFieldQuery) loadItem(ctx context.Context, query *ItemQuery, nodes
|
||||
|
||||
func (ifq *ItemFieldQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := ifq.querySpec()
|
||||
_spec.Node.Columns = ifq.fields
|
||||
if len(ifq.fields) > 0 {
|
||||
_spec.Unique = ifq.unique != nil && *ifq.unique
|
||||
_spec.Node.Columns = ifq.ctx.Fields
|
||||
if len(ifq.ctx.Fields) > 0 {
|
||||
_spec.Unique = ifq.ctx.Unique != nil && *ifq.ctx.Unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, ifq.driver, _spec)
|
||||
}
|
||||
@@ -464,10 +462,10 @@ func (ifq *ItemFieldQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
From: ifq.sql,
|
||||
Unique: true,
|
||||
}
|
||||
if unique := ifq.unique; unique != nil {
|
||||
if unique := ifq.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
}
|
||||
if fields := ifq.fields; len(fields) > 0 {
|
||||
if fields := ifq.ctx.Fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, itemfield.FieldID)
|
||||
for i := range fields {
|
||||
@@ -483,10 +481,10 @@ func (ifq *ItemFieldQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := ifq.limit; limit != nil {
|
||||
if limit := ifq.ctx.Limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := ifq.offset; offset != nil {
|
||||
if offset := ifq.ctx.Offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := ifq.order; len(ps) > 0 {
|
||||
@@ -502,7 +500,7 @@ func (ifq *ItemFieldQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
func (ifq *ItemFieldQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(ifq.driver.Dialect())
|
||||
t1 := builder.Table(itemfield.Table)
|
||||
columns := ifq.fields
|
||||
columns := ifq.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = itemfield.Columns
|
||||
}
|
||||
@@ -511,7 +509,7 @@ func (ifq *ItemFieldQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
selector = ifq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if ifq.unique != nil && *ifq.unique {
|
||||
if ifq.ctx.Unique != nil && *ifq.ctx.Unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, p := range ifq.predicates {
|
||||
@@ -520,12 +518,12 @@ func (ifq *ItemFieldQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
for _, p := range ifq.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := ifq.offset; offset != nil {
|
||||
if offset := ifq.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 := ifq.limit; limit != nil {
|
||||
if limit := ifq.ctx.Limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
@@ -545,7 +543,7 @@ func (ifgb *ItemFieldGroupBy) Aggregate(fns ...AggregateFunc) *ItemFieldGroupBy
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ifgb *ItemFieldGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeItemField, "GroupBy")
|
||||
ctx = setContextOp(ctx, ifgb.build.ctx, "GroupBy")
|
||||
if err := ifgb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -593,7 +591,7 @@ func (ifs *ItemFieldSelect) Aggregate(fns ...AggregateFunc) *ItemFieldSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ifs *ItemFieldSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeItemField, "Select")
|
||||
ctx = setContextOp(ctx, ifs.ctx, "Select")
|
||||
if err := ifs.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -145,19 +145,19 @@ func (l *Label) assignValues(columns []string, values []any) error {
|
||||
|
||||
// QueryGroup queries the "group" edge of the Label entity.
|
||||
func (l *Label) QueryGroup() *GroupQuery {
|
||||
return (&LabelClient{config: l.config}).QueryGroup(l)
|
||||
return NewLabelClient(l.config).QueryGroup(l)
|
||||
}
|
||||
|
||||
// QueryItems queries the "items" edge of the Label entity.
|
||||
func (l *Label) QueryItems() *ItemQuery {
|
||||
return (&LabelClient{config: l.config}).QueryItems(l)
|
||||
return NewLabelClient(l.config).QueryItems(l)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this Label.
|
||||
// Note that you need to call Label.Unwrap() before calling this method if this Label
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (l *Label) Update() *LabelUpdateOne {
|
||||
return (&LabelClient{config: l.config}).UpdateOne(l)
|
||||
return NewLabelClient(l.config).UpdateOne(l)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the Label entity that was returned from a transaction after it was closed,
|
||||
|
||||
@@ -69,6 +69,12 @@ type LabelDeleteOne struct {
|
||||
ld *LabelDelete
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the LabelDelete builder.
|
||||
func (ldo *LabelDeleteOne) Where(ps ...predicate.Label) *LabelDeleteOne {
|
||||
ldo.ld.mutation.Where(ps...)
|
||||
return ldo
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (ldo *LabelDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := ldo.ld.Exec(ctx)
|
||||
@@ -84,5 +90,7 @@ func (ldo *LabelDeleteOne) Exec(ctx context.Context) error {
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (ldo *LabelDeleteOne) ExecX(ctx context.Context) {
|
||||
ldo.ld.ExecX(ctx)
|
||||
if err := ldo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,11 +21,8 @@ import (
|
||||
// LabelQuery is the builder for querying Label entities.
|
||||
type LabelQuery struct {
|
||||
config
|
||||
limit *int
|
||||
offset *int
|
||||
unique *bool
|
||||
ctx *QueryContext
|
||||
order []OrderFunc
|
||||
fields []string
|
||||
inters []Interceptor
|
||||
predicates []predicate.Label
|
||||
withGroup *GroupQuery
|
||||
@@ -44,20 +41,20 @@ func (lq *LabelQuery) Where(ps ...predicate.Label) *LabelQuery {
|
||||
|
||||
// Limit the number of records to be returned by this query.
|
||||
func (lq *LabelQuery) Limit(limit int) *LabelQuery {
|
||||
lq.limit = &limit
|
||||
lq.ctx.Limit = &limit
|
||||
return lq
|
||||
}
|
||||
|
||||
// Offset to start from.
|
||||
func (lq *LabelQuery) Offset(offset int) *LabelQuery {
|
||||
lq.offset = &offset
|
||||
lq.ctx.Offset = &offset
|
||||
return lq
|
||||
}
|
||||
|
||||
// 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 (lq *LabelQuery) Unique(unique bool) *LabelQuery {
|
||||
lq.unique = &unique
|
||||
lq.ctx.Unique = &unique
|
||||
return lq
|
||||
}
|
||||
|
||||
@@ -114,7 +111,7 @@ func (lq *LabelQuery) QueryItems() *ItemQuery {
|
||||
// First returns the first Label entity from the query.
|
||||
// Returns a *NotFoundError when no Label was found.
|
||||
func (lq *LabelQuery) First(ctx context.Context) (*Label, error) {
|
||||
nodes, err := lq.Limit(1).All(newQueryContext(ctx, TypeLabel, "First"))
|
||||
nodes, err := lq.Limit(1).All(setContextOp(ctx, lq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -137,7 +134,7 @@ func (lq *LabelQuery) FirstX(ctx context.Context) *Label {
|
||||
// Returns a *NotFoundError when no Label ID was found.
|
||||
func (lq *LabelQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = lq.Limit(1).IDs(newQueryContext(ctx, TypeLabel, "FirstID")); err != nil {
|
||||
if ids, err = lq.Limit(1).IDs(setContextOp(ctx, lq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -160,7 +157,7 @@ func (lq *LabelQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one Label entity is found.
|
||||
// Returns a *NotFoundError when no Label entities are found.
|
||||
func (lq *LabelQuery) Only(ctx context.Context) (*Label, error) {
|
||||
nodes, err := lq.Limit(2).All(newQueryContext(ctx, TypeLabel, "Only"))
|
||||
nodes, err := lq.Limit(2).All(setContextOp(ctx, lq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -188,7 +185,7 @@ func (lq *LabelQuery) OnlyX(ctx context.Context) *Label {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (lq *LabelQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = lq.Limit(2).IDs(newQueryContext(ctx, TypeLabel, "OnlyID")); err != nil {
|
||||
if ids, err = lq.Limit(2).IDs(setContextOp(ctx, lq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -213,7 +210,7 @@ func (lq *LabelQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of Labels.
|
||||
func (lq *LabelQuery) All(ctx context.Context) ([]*Label, error) {
|
||||
ctx = newQueryContext(ctx, TypeLabel, "All")
|
||||
ctx = setContextOp(ctx, lq.ctx, "All")
|
||||
if err := lq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -233,7 +230,7 @@ func (lq *LabelQuery) AllX(ctx context.Context) []*Label {
|
||||
// IDs executes the query and returns a list of Label IDs.
|
||||
func (lq *LabelQuery) IDs(ctx context.Context) ([]uuid.UUID, error) {
|
||||
var ids []uuid.UUID
|
||||
ctx = newQueryContext(ctx, TypeLabel, "IDs")
|
||||
ctx = setContextOp(ctx, lq.ctx, "IDs")
|
||||
if err := lq.Select(label.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -251,7 +248,7 @@ func (lq *LabelQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (lq *LabelQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = newQueryContext(ctx, TypeLabel, "Count")
|
||||
ctx = setContextOp(ctx, lq.ctx, "Count")
|
||||
if err := lq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -269,7 +266,7 @@ func (lq *LabelQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (lq *LabelQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = newQueryContext(ctx, TypeLabel, "Exist")
|
||||
ctx = setContextOp(ctx, lq.ctx, "Exist")
|
||||
switch _, err := lq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -297,17 +294,15 @@ func (lq *LabelQuery) Clone() *LabelQuery {
|
||||
}
|
||||
return &LabelQuery{
|
||||
config: lq.config,
|
||||
limit: lq.limit,
|
||||
offset: lq.offset,
|
||||
ctx: lq.ctx.Clone(),
|
||||
order: append([]OrderFunc{}, lq.order...),
|
||||
inters: append([]Interceptor{}, lq.inters...),
|
||||
predicates: append([]predicate.Label{}, lq.predicates...),
|
||||
withGroup: lq.withGroup.Clone(),
|
||||
withItems: lq.withItems.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: lq.sql.Clone(),
|
||||
path: lq.path,
|
||||
unique: lq.unique,
|
||||
sql: lq.sql.Clone(),
|
||||
path: lq.path,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,9 +343,9 @@ func (lq *LabelQuery) WithItems(opts ...func(*ItemQuery)) *LabelQuery {
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (lq *LabelQuery) GroupBy(field string, fields ...string) *LabelGroupBy {
|
||||
lq.fields = append([]string{field}, fields...)
|
||||
lq.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &LabelGroupBy{build: lq}
|
||||
grbuild.flds = &lq.fields
|
||||
grbuild.flds = &lq.ctx.Fields
|
||||
grbuild.label = label.Label
|
||||
grbuild.scan = grbuild.Scan
|
||||
return grbuild
|
||||
@@ -369,10 +364,10 @@ func (lq *LabelQuery) GroupBy(field string, fields ...string) *LabelGroupBy {
|
||||
// Select(label.FieldCreatedAt).
|
||||
// Scan(ctx, &v)
|
||||
func (lq *LabelQuery) Select(fields ...string) *LabelSelect {
|
||||
lq.fields = append(lq.fields, fields...)
|
||||
lq.ctx.Fields = append(lq.ctx.Fields, fields...)
|
||||
sbuild := &LabelSelect{LabelQuery: lq}
|
||||
sbuild.label = label.Label
|
||||
sbuild.flds, sbuild.scan = &lq.fields, sbuild.Scan
|
||||
sbuild.flds, sbuild.scan = &lq.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
@@ -392,7 +387,7 @@ func (lq *LabelQuery) prepareQuery(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range lq.fields {
|
||||
for _, f := range lq.ctx.Fields {
|
||||
if !label.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
@@ -470,6 +465,9 @@ func (lq *LabelQuery) loadGroup(ctx context.Context, query *GroupQuery, nodes []
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
query.Where(group.IDIn(ids...))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
@@ -509,27 +507,30 @@ func (lq *LabelQuery) loadItems(ctx context.Context, query *ItemQuery, nodes []*
|
||||
if err := query.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
neighbors, err := query.sqlAll(ctx, func(_ context.Context, spec *sqlgraph.QuerySpec) {
|
||||
assign := spec.Assign
|
||||
values := spec.ScanValues
|
||||
spec.ScanValues = func(columns []string) ([]any, error) {
|
||||
values, err := values(columns[1:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
qr := QuerierFunc(func(ctx context.Context, q Query) (Value, error) {
|
||||
return query.sqlAll(ctx, func(_ context.Context, spec *sqlgraph.QuerySpec) {
|
||||
assign := spec.Assign
|
||||
values := spec.ScanValues
|
||||
spec.ScanValues = func(columns []string) ([]any, error) {
|
||||
values, err := values(columns[1:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return append([]any{new(uuid.UUID)}, values...), nil
|
||||
}
|
||||
return append([]any{new(uuid.UUID)}, values...), nil
|
||||
}
|
||||
spec.Assign = func(columns []string, values []any) error {
|
||||
outValue := *values[0].(*uuid.UUID)
|
||||
inValue := *values[1].(*uuid.UUID)
|
||||
if nids[inValue] == nil {
|
||||
nids[inValue] = map[*Label]struct{}{byID[outValue]: {}}
|
||||
return assign(columns[1:], values[1:])
|
||||
spec.Assign = func(columns []string, values []any) error {
|
||||
outValue := *values[0].(*uuid.UUID)
|
||||
inValue := *values[1].(*uuid.UUID)
|
||||
if nids[inValue] == nil {
|
||||
nids[inValue] = map[*Label]struct{}{byID[outValue]: {}}
|
||||
return assign(columns[1:], values[1:])
|
||||
}
|
||||
nids[inValue][byID[outValue]] = struct{}{}
|
||||
return nil
|
||||
}
|
||||
nids[inValue][byID[outValue]] = struct{}{}
|
||||
return nil
|
||||
}
|
||||
})
|
||||
})
|
||||
neighbors, err := withInterceptors[[]*Item](ctx, query, qr, query.inters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -547,9 +548,9 @@ func (lq *LabelQuery) loadItems(ctx context.Context, query *ItemQuery, nodes []*
|
||||
|
||||
func (lq *LabelQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := lq.querySpec()
|
||||
_spec.Node.Columns = lq.fields
|
||||
if len(lq.fields) > 0 {
|
||||
_spec.Unique = lq.unique != nil && *lq.unique
|
||||
_spec.Node.Columns = lq.ctx.Fields
|
||||
if len(lq.ctx.Fields) > 0 {
|
||||
_spec.Unique = lq.ctx.Unique != nil && *lq.ctx.Unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, lq.driver, _spec)
|
||||
}
|
||||
@@ -567,10 +568,10 @@ func (lq *LabelQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
From: lq.sql,
|
||||
Unique: true,
|
||||
}
|
||||
if unique := lq.unique; unique != nil {
|
||||
if unique := lq.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
}
|
||||
if fields := lq.fields; len(fields) > 0 {
|
||||
if fields := lq.ctx.Fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, label.FieldID)
|
||||
for i := range fields {
|
||||
@@ -586,10 +587,10 @@ func (lq *LabelQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := lq.limit; limit != nil {
|
||||
if limit := lq.ctx.Limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := lq.offset; offset != nil {
|
||||
if offset := lq.ctx.Offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := lq.order; len(ps) > 0 {
|
||||
@@ -605,7 +606,7 @@ func (lq *LabelQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
func (lq *LabelQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(lq.driver.Dialect())
|
||||
t1 := builder.Table(label.Table)
|
||||
columns := lq.fields
|
||||
columns := lq.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = label.Columns
|
||||
}
|
||||
@@ -614,7 +615,7 @@ func (lq *LabelQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
selector = lq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if lq.unique != nil && *lq.unique {
|
||||
if lq.ctx.Unique != nil && *lq.ctx.Unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, p := range lq.predicates {
|
||||
@@ -623,12 +624,12 @@ func (lq *LabelQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
for _, p := range lq.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := lq.offset; offset != nil {
|
||||
if offset := lq.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 := lq.limit; limit != nil {
|
||||
if limit := lq.ctx.Limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
@@ -648,7 +649,7 @@ func (lgb *LabelGroupBy) Aggregate(fns ...AggregateFunc) *LabelGroupBy {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (lgb *LabelGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeLabel, "GroupBy")
|
||||
ctx = setContextOp(ctx, lgb.build.ctx, "GroupBy")
|
||||
if err := lgb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -696,7 +697,7 @@ func (ls *LabelSelect) Aggregate(fns ...AggregateFunc) *LabelSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ls *LabelSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeLabel, "Select")
|
||||
ctx = setContextOp(ctx, ls.ctx, "Select")
|
||||
if err := ls.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -173,29 +173,29 @@ func (l *Location) assignValues(columns []string, values []any) error {
|
||||
|
||||
// QueryParent queries the "parent" edge of the Location entity.
|
||||
func (l *Location) QueryParent() *LocationQuery {
|
||||
return (&LocationClient{config: l.config}).QueryParent(l)
|
||||
return NewLocationClient(l.config).QueryParent(l)
|
||||
}
|
||||
|
||||
// QueryChildren queries the "children" edge of the Location entity.
|
||||
func (l *Location) QueryChildren() *LocationQuery {
|
||||
return (&LocationClient{config: l.config}).QueryChildren(l)
|
||||
return NewLocationClient(l.config).QueryChildren(l)
|
||||
}
|
||||
|
||||
// QueryGroup queries the "group" edge of the Location entity.
|
||||
func (l *Location) QueryGroup() *GroupQuery {
|
||||
return (&LocationClient{config: l.config}).QueryGroup(l)
|
||||
return NewLocationClient(l.config).QueryGroup(l)
|
||||
}
|
||||
|
||||
// QueryItems queries the "items" edge of the Location entity.
|
||||
func (l *Location) QueryItems() *ItemQuery {
|
||||
return (&LocationClient{config: l.config}).QueryItems(l)
|
||||
return NewLocationClient(l.config).QueryItems(l)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this Location.
|
||||
// Note that you need to call Location.Unwrap() before calling this method if this Location
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (l *Location) Update() *LocationUpdateOne {
|
||||
return (&LocationClient{config: l.config}).UpdateOne(l)
|
||||
return NewLocationClient(l.config).UpdateOne(l)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the Location entity that was returned from a transaction after it was closed,
|
||||
|
||||
@@ -69,6 +69,12 @@ type LocationDeleteOne struct {
|
||||
ld *LocationDelete
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the LocationDelete builder.
|
||||
func (ldo *LocationDeleteOne) Where(ps ...predicate.Location) *LocationDeleteOne {
|
||||
ldo.ld.mutation.Where(ps...)
|
||||
return ldo
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (ldo *LocationDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := ldo.ld.Exec(ctx)
|
||||
@@ -84,5 +90,7 @@ func (ldo *LocationDeleteOne) Exec(ctx context.Context) error {
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (ldo *LocationDeleteOne) ExecX(ctx context.Context) {
|
||||
ldo.ld.ExecX(ctx)
|
||||
if err := ldo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,11 +21,8 @@ import (
|
||||
// LocationQuery is the builder for querying Location entities.
|
||||
type LocationQuery struct {
|
||||
config
|
||||
limit *int
|
||||
offset *int
|
||||
unique *bool
|
||||
ctx *QueryContext
|
||||
order []OrderFunc
|
||||
fields []string
|
||||
inters []Interceptor
|
||||
predicates []predicate.Location
|
||||
withParent *LocationQuery
|
||||
@@ -46,20 +43,20 @@ func (lq *LocationQuery) Where(ps ...predicate.Location) *LocationQuery {
|
||||
|
||||
// Limit the number of records to be returned by this query.
|
||||
func (lq *LocationQuery) Limit(limit int) *LocationQuery {
|
||||
lq.limit = &limit
|
||||
lq.ctx.Limit = &limit
|
||||
return lq
|
||||
}
|
||||
|
||||
// Offset to start from.
|
||||
func (lq *LocationQuery) Offset(offset int) *LocationQuery {
|
||||
lq.offset = &offset
|
||||
lq.ctx.Offset = &offset
|
||||
return lq
|
||||
}
|
||||
|
||||
// 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 (lq *LocationQuery) Unique(unique bool) *LocationQuery {
|
||||
lq.unique = &unique
|
||||
lq.ctx.Unique = &unique
|
||||
return lq
|
||||
}
|
||||
|
||||
@@ -160,7 +157,7 @@ func (lq *LocationQuery) QueryItems() *ItemQuery {
|
||||
// First returns the first Location entity from the query.
|
||||
// Returns a *NotFoundError when no Location was found.
|
||||
func (lq *LocationQuery) First(ctx context.Context) (*Location, error) {
|
||||
nodes, err := lq.Limit(1).All(newQueryContext(ctx, TypeLocation, "First"))
|
||||
nodes, err := lq.Limit(1).All(setContextOp(ctx, lq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -183,7 +180,7 @@ func (lq *LocationQuery) FirstX(ctx context.Context) *Location {
|
||||
// Returns a *NotFoundError when no Location ID was found.
|
||||
func (lq *LocationQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = lq.Limit(1).IDs(newQueryContext(ctx, TypeLocation, "FirstID")); err != nil {
|
||||
if ids, err = lq.Limit(1).IDs(setContextOp(ctx, lq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -206,7 +203,7 @@ func (lq *LocationQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one Location entity is found.
|
||||
// Returns a *NotFoundError when no Location entities are found.
|
||||
func (lq *LocationQuery) Only(ctx context.Context) (*Location, error) {
|
||||
nodes, err := lq.Limit(2).All(newQueryContext(ctx, TypeLocation, "Only"))
|
||||
nodes, err := lq.Limit(2).All(setContextOp(ctx, lq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -234,7 +231,7 @@ func (lq *LocationQuery) OnlyX(ctx context.Context) *Location {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (lq *LocationQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = lq.Limit(2).IDs(newQueryContext(ctx, TypeLocation, "OnlyID")); err != nil {
|
||||
if ids, err = lq.Limit(2).IDs(setContextOp(ctx, lq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -259,7 +256,7 @@ func (lq *LocationQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of Locations.
|
||||
func (lq *LocationQuery) All(ctx context.Context) ([]*Location, error) {
|
||||
ctx = newQueryContext(ctx, TypeLocation, "All")
|
||||
ctx = setContextOp(ctx, lq.ctx, "All")
|
||||
if err := lq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -279,7 +276,7 @@ func (lq *LocationQuery) AllX(ctx context.Context) []*Location {
|
||||
// IDs executes the query and returns a list of Location IDs.
|
||||
func (lq *LocationQuery) IDs(ctx context.Context) ([]uuid.UUID, error) {
|
||||
var ids []uuid.UUID
|
||||
ctx = newQueryContext(ctx, TypeLocation, "IDs")
|
||||
ctx = setContextOp(ctx, lq.ctx, "IDs")
|
||||
if err := lq.Select(location.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -297,7 +294,7 @@ func (lq *LocationQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (lq *LocationQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = newQueryContext(ctx, TypeLocation, "Count")
|
||||
ctx = setContextOp(ctx, lq.ctx, "Count")
|
||||
if err := lq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -315,7 +312,7 @@ func (lq *LocationQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (lq *LocationQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = newQueryContext(ctx, TypeLocation, "Exist")
|
||||
ctx = setContextOp(ctx, lq.ctx, "Exist")
|
||||
switch _, err := lq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -343,8 +340,7 @@ func (lq *LocationQuery) Clone() *LocationQuery {
|
||||
}
|
||||
return &LocationQuery{
|
||||
config: lq.config,
|
||||
limit: lq.limit,
|
||||
offset: lq.offset,
|
||||
ctx: lq.ctx.Clone(),
|
||||
order: append([]OrderFunc{}, lq.order...),
|
||||
inters: append([]Interceptor{}, lq.inters...),
|
||||
predicates: append([]predicate.Location{}, lq.predicates...),
|
||||
@@ -353,9 +349,8 @@ func (lq *LocationQuery) Clone() *LocationQuery {
|
||||
withGroup: lq.withGroup.Clone(),
|
||||
withItems: lq.withItems.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: lq.sql.Clone(),
|
||||
path: lq.path,
|
||||
unique: lq.unique,
|
||||
sql: lq.sql.Clone(),
|
||||
path: lq.path,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -418,9 +413,9 @@ func (lq *LocationQuery) WithItems(opts ...func(*ItemQuery)) *LocationQuery {
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (lq *LocationQuery) GroupBy(field string, fields ...string) *LocationGroupBy {
|
||||
lq.fields = append([]string{field}, fields...)
|
||||
lq.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &LocationGroupBy{build: lq}
|
||||
grbuild.flds = &lq.fields
|
||||
grbuild.flds = &lq.ctx.Fields
|
||||
grbuild.label = location.Label
|
||||
grbuild.scan = grbuild.Scan
|
||||
return grbuild
|
||||
@@ -439,10 +434,10 @@ func (lq *LocationQuery) GroupBy(field string, fields ...string) *LocationGroupB
|
||||
// Select(location.FieldCreatedAt).
|
||||
// Scan(ctx, &v)
|
||||
func (lq *LocationQuery) Select(fields ...string) *LocationSelect {
|
||||
lq.fields = append(lq.fields, fields...)
|
||||
lq.ctx.Fields = append(lq.ctx.Fields, fields...)
|
||||
sbuild := &LocationSelect{LocationQuery: lq}
|
||||
sbuild.label = location.Label
|
||||
sbuild.flds, sbuild.scan = &lq.fields, sbuild.Scan
|
||||
sbuild.flds, sbuild.scan = &lq.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
@@ -462,7 +457,7 @@ func (lq *LocationQuery) prepareQuery(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range lq.fields {
|
||||
for _, f := range lq.ctx.Fields {
|
||||
if !location.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
@@ -555,6 +550,9 @@ func (lq *LocationQuery) loadParent(ctx context.Context, query *LocationQuery, n
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
query.Where(location.IDIn(ids...))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
@@ -615,6 +613,9 @@ func (lq *LocationQuery) loadGroup(ctx context.Context, query *GroupQuery, nodes
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
query.Where(group.IDIn(ids...))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
@@ -665,9 +666,9 @@ func (lq *LocationQuery) loadItems(ctx context.Context, query *ItemQuery, nodes
|
||||
|
||||
func (lq *LocationQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := lq.querySpec()
|
||||
_spec.Node.Columns = lq.fields
|
||||
if len(lq.fields) > 0 {
|
||||
_spec.Unique = lq.unique != nil && *lq.unique
|
||||
_spec.Node.Columns = lq.ctx.Fields
|
||||
if len(lq.ctx.Fields) > 0 {
|
||||
_spec.Unique = lq.ctx.Unique != nil && *lq.ctx.Unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, lq.driver, _spec)
|
||||
}
|
||||
@@ -685,10 +686,10 @@ func (lq *LocationQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
From: lq.sql,
|
||||
Unique: true,
|
||||
}
|
||||
if unique := lq.unique; unique != nil {
|
||||
if unique := lq.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
}
|
||||
if fields := lq.fields; len(fields) > 0 {
|
||||
if fields := lq.ctx.Fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, location.FieldID)
|
||||
for i := range fields {
|
||||
@@ -704,10 +705,10 @@ func (lq *LocationQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := lq.limit; limit != nil {
|
||||
if limit := lq.ctx.Limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := lq.offset; offset != nil {
|
||||
if offset := lq.ctx.Offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := lq.order; len(ps) > 0 {
|
||||
@@ -723,7 +724,7 @@ func (lq *LocationQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
func (lq *LocationQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(lq.driver.Dialect())
|
||||
t1 := builder.Table(location.Table)
|
||||
columns := lq.fields
|
||||
columns := lq.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = location.Columns
|
||||
}
|
||||
@@ -732,7 +733,7 @@ func (lq *LocationQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
selector = lq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if lq.unique != nil && *lq.unique {
|
||||
if lq.ctx.Unique != nil && *lq.ctx.Unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, p := range lq.predicates {
|
||||
@@ -741,12 +742,12 @@ func (lq *LocationQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
for _, p := range lq.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := lq.offset; offset != nil {
|
||||
if offset := lq.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 := lq.limit; limit != nil {
|
||||
if limit := lq.ctx.Limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
@@ -766,7 +767,7 @@ func (lgb *LocationGroupBy) Aggregate(fns ...AggregateFunc) *LocationGroupBy {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (lgb *LocationGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeLocation, "GroupBy")
|
||||
ctx = setContextOp(ctx, lgb.build.ctx, "GroupBy")
|
||||
if err := lgb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -814,7 +815,7 @@ func (ls *LocationSelect) Aggregate(fns ...AggregateFunc) *LocationSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ls *LocationSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeLocation, "Select")
|
||||
ctx = setContextOp(ctx, ls.ctx, "Select")
|
||||
if err := ls.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -142,14 +142,14 @@ func (me *MaintenanceEntry) assignValues(columns []string, values []any) error {
|
||||
|
||||
// QueryItem queries the "item" edge of the MaintenanceEntry entity.
|
||||
func (me *MaintenanceEntry) QueryItem() *ItemQuery {
|
||||
return (&MaintenanceEntryClient{config: me.config}).QueryItem(me)
|
||||
return NewMaintenanceEntryClient(me.config).QueryItem(me)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this MaintenanceEntry.
|
||||
// Note that you need to call MaintenanceEntry.Unwrap() before calling this method if this MaintenanceEntry
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (me *MaintenanceEntry) Update() *MaintenanceEntryUpdateOne {
|
||||
return (&MaintenanceEntryClient{config: me.config}).UpdateOne(me)
|
||||
return NewMaintenanceEntryClient(me.config).UpdateOne(me)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the MaintenanceEntry entity that was returned from a transaction after it was closed,
|
||||
|
||||
@@ -69,6 +69,12 @@ type MaintenanceEntryDeleteOne struct {
|
||||
med *MaintenanceEntryDelete
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the MaintenanceEntryDelete builder.
|
||||
func (medo *MaintenanceEntryDeleteOne) Where(ps ...predicate.MaintenanceEntry) *MaintenanceEntryDeleteOne {
|
||||
medo.med.mutation.Where(ps...)
|
||||
return medo
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (medo *MaintenanceEntryDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := medo.med.Exec(ctx)
|
||||
@@ -84,5 +90,7 @@ func (medo *MaintenanceEntryDeleteOne) Exec(ctx context.Context) error {
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (medo *MaintenanceEntryDeleteOne) ExecX(ctx context.Context) {
|
||||
medo.med.ExecX(ctx)
|
||||
if err := medo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,11 +19,8 @@ import (
|
||||
// MaintenanceEntryQuery is the builder for querying MaintenanceEntry entities.
|
||||
type MaintenanceEntryQuery struct {
|
||||
config
|
||||
limit *int
|
||||
offset *int
|
||||
unique *bool
|
||||
ctx *QueryContext
|
||||
order []OrderFunc
|
||||
fields []string
|
||||
inters []Interceptor
|
||||
predicates []predicate.MaintenanceEntry
|
||||
withItem *ItemQuery
|
||||
@@ -40,20 +37,20 @@ func (meq *MaintenanceEntryQuery) Where(ps ...predicate.MaintenanceEntry) *Maint
|
||||
|
||||
// Limit the number of records to be returned by this query.
|
||||
func (meq *MaintenanceEntryQuery) Limit(limit int) *MaintenanceEntryQuery {
|
||||
meq.limit = &limit
|
||||
meq.ctx.Limit = &limit
|
||||
return meq
|
||||
}
|
||||
|
||||
// Offset to start from.
|
||||
func (meq *MaintenanceEntryQuery) Offset(offset int) *MaintenanceEntryQuery {
|
||||
meq.offset = &offset
|
||||
meq.ctx.Offset = &offset
|
||||
return meq
|
||||
}
|
||||
|
||||
// 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 (meq *MaintenanceEntryQuery) Unique(unique bool) *MaintenanceEntryQuery {
|
||||
meq.unique = &unique
|
||||
meq.ctx.Unique = &unique
|
||||
return meq
|
||||
}
|
||||
|
||||
@@ -88,7 +85,7 @@ func (meq *MaintenanceEntryQuery) QueryItem() *ItemQuery {
|
||||
// First returns the first MaintenanceEntry entity from the query.
|
||||
// Returns a *NotFoundError when no MaintenanceEntry was found.
|
||||
func (meq *MaintenanceEntryQuery) First(ctx context.Context) (*MaintenanceEntry, error) {
|
||||
nodes, err := meq.Limit(1).All(newQueryContext(ctx, TypeMaintenanceEntry, "First"))
|
||||
nodes, err := meq.Limit(1).All(setContextOp(ctx, meq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -111,7 +108,7 @@ func (meq *MaintenanceEntryQuery) FirstX(ctx context.Context) *MaintenanceEntry
|
||||
// Returns a *NotFoundError when no MaintenanceEntry ID was found.
|
||||
func (meq *MaintenanceEntryQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = meq.Limit(1).IDs(newQueryContext(ctx, TypeMaintenanceEntry, "FirstID")); err != nil {
|
||||
if ids, err = meq.Limit(1).IDs(setContextOp(ctx, meq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -134,7 +131,7 @@ func (meq *MaintenanceEntryQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// Returns a *NotSingularError when more than one MaintenanceEntry entity is found.
|
||||
// Returns a *NotFoundError when no MaintenanceEntry entities are found.
|
||||
func (meq *MaintenanceEntryQuery) Only(ctx context.Context) (*MaintenanceEntry, error) {
|
||||
nodes, err := meq.Limit(2).All(newQueryContext(ctx, TypeMaintenanceEntry, "Only"))
|
||||
nodes, err := meq.Limit(2).All(setContextOp(ctx, meq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -162,7 +159,7 @@ func (meq *MaintenanceEntryQuery) OnlyX(ctx context.Context) *MaintenanceEntry {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (meq *MaintenanceEntryQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = meq.Limit(2).IDs(newQueryContext(ctx, TypeMaintenanceEntry, "OnlyID")); err != nil {
|
||||
if ids, err = meq.Limit(2).IDs(setContextOp(ctx, meq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -187,7 +184,7 @@ func (meq *MaintenanceEntryQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of MaintenanceEntries.
|
||||
func (meq *MaintenanceEntryQuery) All(ctx context.Context) ([]*MaintenanceEntry, error) {
|
||||
ctx = newQueryContext(ctx, TypeMaintenanceEntry, "All")
|
||||
ctx = setContextOp(ctx, meq.ctx, "All")
|
||||
if err := meq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -207,7 +204,7 @@ func (meq *MaintenanceEntryQuery) AllX(ctx context.Context) []*MaintenanceEntry
|
||||
// IDs executes the query and returns a list of MaintenanceEntry IDs.
|
||||
func (meq *MaintenanceEntryQuery) IDs(ctx context.Context) ([]uuid.UUID, error) {
|
||||
var ids []uuid.UUID
|
||||
ctx = newQueryContext(ctx, TypeMaintenanceEntry, "IDs")
|
||||
ctx = setContextOp(ctx, meq.ctx, "IDs")
|
||||
if err := meq.Select(maintenanceentry.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -225,7 +222,7 @@ func (meq *MaintenanceEntryQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (meq *MaintenanceEntryQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = newQueryContext(ctx, TypeMaintenanceEntry, "Count")
|
||||
ctx = setContextOp(ctx, meq.ctx, "Count")
|
||||
if err := meq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -243,7 +240,7 @@ func (meq *MaintenanceEntryQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (meq *MaintenanceEntryQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = newQueryContext(ctx, TypeMaintenanceEntry, "Exist")
|
||||
ctx = setContextOp(ctx, meq.ctx, "Exist")
|
||||
switch _, err := meq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -271,16 +268,14 @@ func (meq *MaintenanceEntryQuery) Clone() *MaintenanceEntryQuery {
|
||||
}
|
||||
return &MaintenanceEntryQuery{
|
||||
config: meq.config,
|
||||
limit: meq.limit,
|
||||
offset: meq.offset,
|
||||
ctx: meq.ctx.Clone(),
|
||||
order: append([]OrderFunc{}, meq.order...),
|
||||
inters: append([]Interceptor{}, meq.inters...),
|
||||
predicates: append([]predicate.MaintenanceEntry{}, meq.predicates...),
|
||||
withItem: meq.withItem.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: meq.sql.Clone(),
|
||||
path: meq.path,
|
||||
unique: meq.unique,
|
||||
sql: meq.sql.Clone(),
|
||||
path: meq.path,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,9 +305,9 @@ func (meq *MaintenanceEntryQuery) WithItem(opts ...func(*ItemQuery)) *Maintenanc
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (meq *MaintenanceEntryQuery) GroupBy(field string, fields ...string) *MaintenanceEntryGroupBy {
|
||||
meq.fields = append([]string{field}, fields...)
|
||||
meq.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &MaintenanceEntryGroupBy{build: meq}
|
||||
grbuild.flds = &meq.fields
|
||||
grbuild.flds = &meq.ctx.Fields
|
||||
grbuild.label = maintenanceentry.Label
|
||||
grbuild.scan = grbuild.Scan
|
||||
return grbuild
|
||||
@@ -331,10 +326,10 @@ func (meq *MaintenanceEntryQuery) GroupBy(field string, fields ...string) *Maint
|
||||
// Select(maintenanceentry.FieldCreatedAt).
|
||||
// Scan(ctx, &v)
|
||||
func (meq *MaintenanceEntryQuery) Select(fields ...string) *MaintenanceEntrySelect {
|
||||
meq.fields = append(meq.fields, fields...)
|
||||
meq.ctx.Fields = append(meq.ctx.Fields, fields...)
|
||||
sbuild := &MaintenanceEntrySelect{MaintenanceEntryQuery: meq}
|
||||
sbuild.label = maintenanceentry.Label
|
||||
sbuild.flds, sbuild.scan = &meq.fields, sbuild.Scan
|
||||
sbuild.flds, sbuild.scan = &meq.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
@@ -354,7 +349,7 @@ func (meq *MaintenanceEntryQuery) prepareQuery(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range meq.fields {
|
||||
for _, f := range meq.ctx.Fields {
|
||||
if !maintenanceentry.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
@@ -414,6 +409,9 @@ func (meq *MaintenanceEntryQuery) loadItem(ctx context.Context, query *ItemQuery
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
query.Where(item.IDIn(ids...))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
@@ -433,9 +431,9 @@ func (meq *MaintenanceEntryQuery) loadItem(ctx context.Context, query *ItemQuery
|
||||
|
||||
func (meq *MaintenanceEntryQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := meq.querySpec()
|
||||
_spec.Node.Columns = meq.fields
|
||||
if len(meq.fields) > 0 {
|
||||
_spec.Unique = meq.unique != nil && *meq.unique
|
||||
_spec.Node.Columns = meq.ctx.Fields
|
||||
if len(meq.ctx.Fields) > 0 {
|
||||
_spec.Unique = meq.ctx.Unique != nil && *meq.ctx.Unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, meq.driver, _spec)
|
||||
}
|
||||
@@ -453,10 +451,10 @@ func (meq *MaintenanceEntryQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
From: meq.sql,
|
||||
Unique: true,
|
||||
}
|
||||
if unique := meq.unique; unique != nil {
|
||||
if unique := meq.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
}
|
||||
if fields := meq.fields; len(fields) > 0 {
|
||||
if fields := meq.ctx.Fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, maintenanceentry.FieldID)
|
||||
for i := range fields {
|
||||
@@ -472,10 +470,10 @@ func (meq *MaintenanceEntryQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := meq.limit; limit != nil {
|
||||
if limit := meq.ctx.Limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := meq.offset; offset != nil {
|
||||
if offset := meq.ctx.Offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := meq.order; len(ps) > 0 {
|
||||
@@ -491,7 +489,7 @@ func (meq *MaintenanceEntryQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
func (meq *MaintenanceEntryQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(meq.driver.Dialect())
|
||||
t1 := builder.Table(maintenanceentry.Table)
|
||||
columns := meq.fields
|
||||
columns := meq.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = maintenanceentry.Columns
|
||||
}
|
||||
@@ -500,7 +498,7 @@ func (meq *MaintenanceEntryQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
selector = meq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if meq.unique != nil && *meq.unique {
|
||||
if meq.ctx.Unique != nil && *meq.ctx.Unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, p := range meq.predicates {
|
||||
@@ -509,12 +507,12 @@ func (meq *MaintenanceEntryQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
for _, p := range meq.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := meq.offset; offset != nil {
|
||||
if offset := meq.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 := meq.limit; limit != nil {
|
||||
if limit := meq.ctx.Limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
@@ -534,7 +532,7 @@ func (megb *MaintenanceEntryGroupBy) Aggregate(fns ...AggregateFunc) *Maintenanc
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (megb *MaintenanceEntryGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeMaintenanceEntry, "GroupBy")
|
||||
ctx = setContextOp(ctx, megb.build.ctx, "GroupBy")
|
||||
if err := megb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -582,7 +580,7 @@ func (mes *MaintenanceEntrySelect) Aggregate(fns ...AggregateFunc) *MaintenanceE
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (mes *MaintenanceEntrySelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeMaintenanceEntry, "Select")
|
||||
ctx = setContextOp(ctx, mes.ctx, "Select")
|
||||
if err := mes.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ var (
|
||||
{Name: "created_at", Type: field.TypeTime},
|
||||
{Name: "updated_at", Type: field.TypeTime},
|
||||
{Name: "name", Type: field.TypeString, Size: 255},
|
||||
{Name: "currency", Type: field.TypeEnum, Enums: []string{"usd", "eur", "gbp", "jpy", "zar", "aud", "nok", "sek", "dkk", "inr", "rmb"}, Default: "usd"},
|
||||
{Name: "currency", Type: field.TypeEnum, Enums: []string{"usd", "eur", "gbp", "jpy", "zar", "aud", "nok", "sek", "dkk", "inr", "rmb", "bgn"}, Default: "usd"},
|
||||
}
|
||||
// GroupsTable holds the schema information for the "groups" table.
|
||||
GroupsTable = &schema.Table{
|
||||
|
||||
@@ -5,6 +5,6 @@ package runtime
|
||||
// The schema-stitching logic is generated in github.com/hay-kot/homebox/backend/internal/data/ent/runtime.go
|
||||
|
||||
const (
|
||||
Version = "v0.11.5" // Version of ent codegen.
|
||||
Sum = "h1:V2qhG91C4PMQTa82Q4StoESMQ4dzkMNeStCzszxi0jQ=" // Sum of ent codegen.
|
||||
Version = "v0.11.7" // Version of ent codegen.
|
||||
Sum = "h1:V+wKFh0jhAbY/FoU+PPbdMOf2Ma5vh07R/IdF+N/nFg=" // Sum of ent codegen.
|
||||
)
|
||||
|
||||
@@ -27,7 +27,7 @@ func (Group) Fields() []ent.Field {
|
||||
NotEmpty(),
|
||||
field.Enum("currency").
|
||||
Default("usd").
|
||||
Values("usd", "eur", "gbp", "jpy", "zar", "aud", "nok", "sek", "dkk", "inr", "rmb"),
|
||||
Values("usd", "eur", "gbp", "jpy", "zar", "aud", "nok", "sek", "dkk", "inr", "rmb", "bgn"),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -179,19 +179,19 @@ func (u *User) assignValues(columns []string, values []any) error {
|
||||
|
||||
// QueryGroup queries the "group" edge of the User entity.
|
||||
func (u *User) QueryGroup() *GroupQuery {
|
||||
return (&UserClient{config: u.config}).QueryGroup(u)
|
||||
return NewUserClient(u.config).QueryGroup(u)
|
||||
}
|
||||
|
||||
// QueryAuthTokens queries the "auth_tokens" edge of the User entity.
|
||||
func (u *User) QueryAuthTokens() *AuthTokensQuery {
|
||||
return (&UserClient{config: u.config}).QueryAuthTokens(u)
|
||||
return NewUserClient(u.config).QueryAuthTokens(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 (&UserClient{config: u.config}).UpdateOne(u)
|
||||
return NewUserClient(u.config).UpdateOne(u)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the User entity that was returned from a transaction after it was closed,
|
||||
|
||||
@@ -69,6 +69,12 @@ 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)
|
||||
@@ -84,5 +90,7 @@ func (udo *UserDeleteOne) Exec(ctx context.Context) error {
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (udo *UserDeleteOne) ExecX(ctx context.Context) {
|
||||
udo.ud.ExecX(ctx)
|
||||
if err := udo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,11 +21,8 @@ import (
|
||||
// UserQuery is the builder for querying User entities.
|
||||
type UserQuery struct {
|
||||
config
|
||||
limit *int
|
||||
offset *int
|
||||
unique *bool
|
||||
ctx *QueryContext
|
||||
order []OrderFunc
|
||||
fields []string
|
||||
inters []Interceptor
|
||||
predicates []predicate.User
|
||||
withGroup *GroupQuery
|
||||
@@ -44,20 +41,20 @@ func (uq *UserQuery) Where(ps ...predicate.User) *UserQuery {
|
||||
|
||||
// Limit the number of records to be returned by this query.
|
||||
func (uq *UserQuery) Limit(limit int) *UserQuery {
|
||||
uq.limit = &limit
|
||||
uq.ctx.Limit = &limit
|
||||
return uq
|
||||
}
|
||||
|
||||
// Offset to start from.
|
||||
func (uq *UserQuery) Offset(offset int) *UserQuery {
|
||||
uq.offset = &offset
|
||||
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.unique = &unique
|
||||
uq.ctx.Unique = &unique
|
||||
return uq
|
||||
}
|
||||
|
||||
@@ -114,7 +111,7 @@ func (uq *UserQuery) QueryAuthTokens() *AuthTokensQuery {
|
||||
// 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(newQueryContext(ctx, TypeUser, "First"))
|
||||
nodes, err := uq.Limit(1).All(setContextOp(ctx, uq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -137,7 +134,7 @@ func (uq *UserQuery) FirstX(ctx context.Context) *User {
|
||||
// Returns a *NotFoundError when no User ID was found.
|
||||
func (uq *UserQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = uq.Limit(1).IDs(newQueryContext(ctx, TypeUser, "FirstID")); err != nil {
|
||||
if ids, err = uq.Limit(1).IDs(setContextOp(ctx, uq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -160,7 +157,7 @@ func (uq *UserQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
// 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(newQueryContext(ctx, TypeUser, "Only"))
|
||||
nodes, err := uq.Limit(2).All(setContextOp(ctx, uq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -188,7 +185,7 @@ func (uq *UserQuery) OnlyX(ctx context.Context) *User {
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (uq *UserQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = uq.Limit(2).IDs(newQueryContext(ctx, TypeUser, "OnlyID")); err != nil {
|
||||
if ids, err = uq.Limit(2).IDs(setContextOp(ctx, uq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -213,7 +210,7 @@ func (uq *UserQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
|
||||
// All executes the query and returns a list of Users.
|
||||
func (uq *UserQuery) All(ctx context.Context) ([]*User, error) {
|
||||
ctx = newQueryContext(ctx, TypeUser, "All")
|
||||
ctx = setContextOp(ctx, uq.ctx, "All")
|
||||
if err := uq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -233,7 +230,7 @@ func (uq *UserQuery) AllX(ctx context.Context) []*User {
|
||||
// IDs executes the query and returns a list of User IDs.
|
||||
func (uq *UserQuery) IDs(ctx context.Context) ([]uuid.UUID, error) {
|
||||
var ids []uuid.UUID
|
||||
ctx = newQueryContext(ctx, TypeUser, "IDs")
|
||||
ctx = setContextOp(ctx, uq.ctx, "IDs")
|
||||
if err := uq.Select(user.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -251,7 +248,7 @@ func (uq *UserQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (uq *UserQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = newQueryContext(ctx, TypeUser, "Count")
|
||||
ctx = setContextOp(ctx, uq.ctx, "Count")
|
||||
if err := uq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -269,7 +266,7 @@ func (uq *UserQuery) CountX(ctx context.Context) int {
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (uq *UserQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = newQueryContext(ctx, TypeUser, "Exist")
|
||||
ctx = setContextOp(ctx, uq.ctx, "Exist")
|
||||
switch _, err := uq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
@@ -297,17 +294,15 @@ func (uq *UserQuery) Clone() *UserQuery {
|
||||
}
|
||||
return &UserQuery{
|
||||
config: uq.config,
|
||||
limit: uq.limit,
|
||||
offset: uq.offset,
|
||||
ctx: uq.ctx.Clone(),
|
||||
order: append([]OrderFunc{}, uq.order...),
|
||||
inters: append([]Interceptor{}, uq.inters...),
|
||||
predicates: append([]predicate.User{}, uq.predicates...),
|
||||
withGroup: uq.withGroup.Clone(),
|
||||
withAuthTokens: uq.withAuthTokens.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: uq.sql.Clone(),
|
||||
path: uq.path,
|
||||
unique: uq.unique,
|
||||
sql: uq.sql.Clone(),
|
||||
path: uq.path,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,9 +343,9 @@ func (uq *UserQuery) WithAuthTokens(opts ...func(*AuthTokensQuery)) *UserQuery {
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (uq *UserQuery) GroupBy(field string, fields ...string) *UserGroupBy {
|
||||
uq.fields = append([]string{field}, fields...)
|
||||
uq.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &UserGroupBy{build: uq}
|
||||
grbuild.flds = &uq.fields
|
||||
grbuild.flds = &uq.ctx.Fields
|
||||
grbuild.label = user.Label
|
||||
grbuild.scan = grbuild.Scan
|
||||
return grbuild
|
||||
@@ -369,10 +364,10 @@ func (uq *UserQuery) GroupBy(field string, fields ...string) *UserGroupBy {
|
||||
// Select(user.FieldCreatedAt).
|
||||
// Scan(ctx, &v)
|
||||
func (uq *UserQuery) Select(fields ...string) *UserSelect {
|
||||
uq.fields = append(uq.fields, fields...)
|
||||
uq.ctx.Fields = append(uq.ctx.Fields, fields...)
|
||||
sbuild := &UserSelect{UserQuery: uq}
|
||||
sbuild.label = user.Label
|
||||
sbuild.flds, sbuild.scan = &uq.fields, sbuild.Scan
|
||||
sbuild.flds, sbuild.scan = &uq.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
@@ -392,7 +387,7 @@ func (uq *UserQuery) prepareQuery(ctx context.Context) error {
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range uq.fields {
|
||||
for _, f := range uq.ctx.Fields {
|
||||
if !user.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
@@ -470,6 +465,9 @@ func (uq *UserQuery) loadGroup(ctx context.Context, query *GroupQuery, nodes []*
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
query.Where(group.IDIn(ids...))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
@@ -520,9 +518,9 @@ func (uq *UserQuery) loadAuthTokens(ctx context.Context, query *AuthTokensQuery,
|
||||
|
||||
func (uq *UserQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := uq.querySpec()
|
||||
_spec.Node.Columns = uq.fields
|
||||
if len(uq.fields) > 0 {
|
||||
_spec.Unique = uq.unique != nil && *uq.unique
|
||||
_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)
|
||||
}
|
||||
@@ -540,10 +538,10 @@ func (uq *UserQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
From: uq.sql,
|
||||
Unique: true,
|
||||
}
|
||||
if unique := uq.unique; unique != nil {
|
||||
if unique := uq.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
}
|
||||
if fields := uq.fields; len(fields) > 0 {
|
||||
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 {
|
||||
@@ -559,10 +557,10 @@ func (uq *UserQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := uq.limit; limit != nil {
|
||||
if limit := uq.ctx.Limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := uq.offset; offset != nil {
|
||||
if offset := uq.ctx.Offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := uq.order; len(ps) > 0 {
|
||||
@@ -578,7 +576,7 @@ func (uq *UserQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
func (uq *UserQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(uq.driver.Dialect())
|
||||
t1 := builder.Table(user.Table)
|
||||
columns := uq.fields
|
||||
columns := uq.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = user.Columns
|
||||
}
|
||||
@@ -587,7 +585,7 @@ func (uq *UserQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
selector = uq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if uq.unique != nil && *uq.unique {
|
||||
if uq.ctx.Unique != nil && *uq.ctx.Unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, p := range uq.predicates {
|
||||
@@ -596,12 +594,12 @@ func (uq *UserQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
for _, p := range uq.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := uq.offset; offset != nil {
|
||||
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.limit; limit != nil {
|
||||
if limit := uq.ctx.Limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
@@ -621,7 +619,7 @@ func (ugb *UserGroupBy) Aggregate(fns ...AggregateFunc) *UserGroupBy {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ugb *UserGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeUser, "GroupBy")
|
||||
ctx = setContextOp(ctx, ugb.build.ctx, "GroupBy")
|
||||
if err := ugb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -669,7 +667,7 @@ func (us *UserSelect) Aggregate(fns ...AggregateFunc) *UserSelect {
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (us *UserSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = newQueryContext(ctx, TypeUser, "Select")
|
||||
ctx = setContextOp(ctx, us.ctx, "Select")
|
||||
if err := us.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -8,11 +8,34 @@ import (
|
||||
|
||||
type AssetID int
|
||||
|
||||
func (aid AssetID) Nil() bool {
|
||||
return aid.Int() <= 0
|
||||
}
|
||||
|
||||
func (aid AssetID) Int() int {
|
||||
return int(aid)
|
||||
}
|
||||
|
||||
func ParseAssetIDBytes(d []byte) (AID AssetID, ok bool) {
|
||||
d = bytes.Replace(d, []byte(`"`), []byte(``), -1)
|
||||
d = bytes.Replace(d, []byte(`-`), []byte(``), -1)
|
||||
|
||||
aidInt, err := strconv.Atoi(string(d))
|
||||
if err != nil {
|
||||
return AssetID(-1), false
|
||||
}
|
||||
|
||||
return AssetID(aidInt), true
|
||||
}
|
||||
|
||||
func ParseAssetID(s string) (AID AssetID, ok bool) {
|
||||
return ParseAssetIDBytes([]byte(s))
|
||||
}
|
||||
|
||||
func (aid AssetID) MarshalJSON() ([]byte, error) {
|
||||
aidStr := fmt.Sprintf("%06d", aid)
|
||||
aidStr = fmt.Sprintf("%s-%s", aidStr[:3], aidStr[3:])
|
||||
return []byte(fmt.Sprintf(`"%s"`, aidStr)), nil
|
||||
|
||||
}
|
||||
|
||||
func (aid *AssetID) UnmarshalJSON(d []byte) error {
|
||||
@@ -26,5 +49,4 @@ func (aid *AssetID) UnmarshalJSON(d []byte) error {
|
||||
|
||||
*aid = AssetID(aidInt)
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
@@ -19,14 +20,21 @@ type ItemsRepository struct {
|
||||
}
|
||||
|
||||
type (
|
||||
FieldQuery struct {
|
||||
Name string
|
||||
Value string
|
||||
}
|
||||
|
||||
ItemQuery struct {
|
||||
Page int
|
||||
PageSize int
|
||||
Search string `json:"search"`
|
||||
AssetID AssetID `json:"assetId"`
|
||||
LocationIDs []uuid.UUID `json:"locationIds"`
|
||||
LabelIDs []uuid.UUID `json:"labelIds"`
|
||||
SortBy string `json:"sortBy"`
|
||||
IncludeArchived bool `json:"includeArchived"`
|
||||
Fields []FieldQuery
|
||||
}
|
||||
|
||||
ItemField struct {
|
||||
@@ -177,7 +185,8 @@ func mapItemSummary(item *ent.Item) ItemSummary {
|
||||
}
|
||||
|
||||
var (
|
||||
mapItemOutErr = mapTErrFunc(mapItemOut)
|
||||
mapItemOutErr = mapTErrFunc(mapItemOut)
|
||||
mapItemsOutErr = mapTEachErrFunc(mapItemOut)
|
||||
)
|
||||
|
||||
func mapFields(fields []*ent.ItemField) []ItemField {
|
||||
@@ -300,22 +309,6 @@ func (e *ItemsRepository) QueryByGroup(ctx context.Context, gid uuid.UUID, q Ite
|
||||
qb = qb.Where(item.Archived(false))
|
||||
}
|
||||
|
||||
if len(q.LabelIDs) > 0 {
|
||||
labels := make([]predicate.Item, 0, len(q.LabelIDs))
|
||||
for _, l := range q.LabelIDs {
|
||||
labels = append(labels, item.HasLabelWith(label.ID(l)))
|
||||
}
|
||||
qb = qb.Where(item.Or(labels...))
|
||||
}
|
||||
|
||||
if len(q.LocationIDs) > 0 {
|
||||
locations := make([]predicate.Item, 0, len(q.LocationIDs))
|
||||
for _, l := range q.LocationIDs {
|
||||
locations = append(locations, item.HasLocationWith(location.ID(l)))
|
||||
}
|
||||
qb = qb.Where(item.Or(locations...))
|
||||
}
|
||||
|
||||
if q.Search != "" {
|
||||
qb.Where(
|
||||
item.Or(
|
||||
@@ -326,7 +319,58 @@ func (e *ItemsRepository) QueryByGroup(ctx context.Context, gid uuid.UUID, q Ite
|
||||
)
|
||||
}
|
||||
|
||||
if !q.AssetID.Nil() {
|
||||
qb = qb.Where(item.AssetID(q.AssetID.Int()))
|
||||
}
|
||||
|
||||
// Filters within this block define a AND relationship where each subset
|
||||
// of filters is OR'd together.
|
||||
//
|
||||
// The goal is to allow matches like where the item has
|
||||
// - one of the selected labels AND
|
||||
// - one of the selected locations AND
|
||||
// - one of the selected fields key/value matches
|
||||
var andPredicates []predicate.Item
|
||||
{
|
||||
if len(q.LabelIDs) > 0 {
|
||||
labelPredicates := make([]predicate.Item, 0, len(q.LabelIDs))
|
||||
for _, l := range q.LabelIDs {
|
||||
labelPredicates = append(labelPredicates, item.HasLabelWith(label.ID(l)))
|
||||
}
|
||||
|
||||
andPredicates = append(andPredicates, item.Or(labelPredicates...))
|
||||
}
|
||||
|
||||
if len(q.LocationIDs) > 0 {
|
||||
locationPredicates := make([]predicate.Item, 0, len(q.LocationIDs))
|
||||
for _, l := range q.LocationIDs {
|
||||
locationPredicates = append(locationPredicates, item.HasLocationWith(location.ID(l)))
|
||||
}
|
||||
|
||||
andPredicates = append(andPredicates, item.Or(locationPredicates...))
|
||||
}
|
||||
|
||||
if len(q.Fields) > 0 {
|
||||
fieldPredicates := make([]predicate.Item, 0, len(q.Fields))
|
||||
for _, f := range q.Fields {
|
||||
fieldPredicates = append(fieldPredicates, item.HasFieldsWith(
|
||||
itemfield.And(
|
||||
itemfield.Name(f.Name),
|
||||
itemfield.TextValue(f.Value),
|
||||
),
|
||||
))
|
||||
}
|
||||
|
||||
andPredicates = append(andPredicates, item.Or(fieldPredicates...))
|
||||
}
|
||||
}
|
||||
|
||||
if len(andPredicates) > 0 {
|
||||
qb = qb.Where(item.And(andPredicates...))
|
||||
}
|
||||
|
||||
count, err := qb.Count(ctx)
|
||||
|
||||
if err != nil {
|
||||
return PaginationResult[ItemSummary]{}, err
|
||||
}
|
||||
@@ -356,7 +400,6 @@ func (e *ItemsRepository) QueryByGroup(ctx context.Context, gid uuid.UUID, q Ite
|
||||
|
||||
}
|
||||
|
||||
|
||||
// QueryByAssetID returns items by asset ID. If the item does not exist, an error is returned.
|
||||
func (e *ItemsRepository) QueryByAssetID(ctx context.Context, gid uuid.UUID, assetID AssetID, page int, pageSize int) (PaginationResult[ItemSummary], error) {
|
||||
qb := e.db.Item.Query().Where(
|
||||
@@ -372,7 +415,7 @@ func (e *ItemsRepository) QueryByAssetID(ctx context.Context, gid uuid.UUID, ass
|
||||
pageSize = -1
|
||||
}
|
||||
|
||||
items, err := mapItemsSummaryErr(
|
||||
items, err := mapItemsSummaryErr(
|
||||
qb.Order(ent.Asc(item.FieldName)).
|
||||
WithLabel().
|
||||
WithLocation().
|
||||
@@ -392,8 +435,8 @@ func (e *ItemsRepository) QueryByAssetID(ctx context.Context, gid uuid.UUID, ass
|
||||
}
|
||||
|
||||
// GetAll returns all the items in the database with the Labels and Locations eager loaded.
|
||||
func (e *ItemsRepository) GetAll(ctx context.Context, gid uuid.UUID) ([]ItemSummary, error) {
|
||||
return mapItemsSummaryErr(e.db.Item.Query().
|
||||
func (e *ItemsRepository) GetAll(ctx context.Context, gid uuid.UUID) ([]ItemOut, error) {
|
||||
return mapItemsOutErr(e.db.Item.Query().
|
||||
Where(item.HasGroupWith(group.ID(gid))).
|
||||
WithLabel().
|
||||
WithLocation().
|
||||
@@ -474,8 +517,8 @@ func (e *ItemsRepository) DeleteByGroup(ctx context.Context, gid, id uuid.UUID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (e *ItemsRepository) UpdateByGroup(ctx context.Context, gid uuid.UUID, data ItemUpdate) (ItemOut, error) {
|
||||
q := e.db.Item.Update().Where(item.ID(data.ID), item.HasGroupWith(group.ID(gid))).
|
||||
func (e *ItemsRepository) UpdateByGroup(ctx context.Context, GID uuid.UUID, data ItemUpdate) (ItemOut, error) {
|
||||
q := e.db.Item.Update().Where(item.ID(data.ID), item.HasGroupWith(group.ID(GID))).
|
||||
SetName(data.Name).
|
||||
SetDescription(data.Description).
|
||||
SetLocationID(data.LocationID).
|
||||
@@ -588,3 +631,115 @@ func (e *ItemsRepository) UpdateByGroup(ctx context.Context, gid uuid.UUID, data
|
||||
|
||||
return e.GetOne(ctx, data.ID)
|
||||
}
|
||||
|
||||
func (e *ItemsRepository) GetAllCustomFieldValues(ctx context.Context, GID uuid.UUID, name string) ([]string, error) {
|
||||
type st struct {
|
||||
Value string `json:"text_value"`
|
||||
}
|
||||
|
||||
var values []st
|
||||
|
||||
err := e.db.Item.Query().
|
||||
Where(
|
||||
item.HasGroupWith(group.ID(GID)),
|
||||
).
|
||||
QueryFields().
|
||||
Where(
|
||||
itemfield.Name(name),
|
||||
).
|
||||
Unique(true).
|
||||
Select(itemfield.FieldTextValue).
|
||||
Scan(ctx, &values)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get field values: %w", err)
|
||||
}
|
||||
|
||||
valueStrings := make([]string, len(values))
|
||||
for i, f := range values {
|
||||
valueStrings[i] = f.Value
|
||||
}
|
||||
|
||||
return valueStrings, nil
|
||||
}
|
||||
|
||||
func (e *ItemsRepository) GetAllCustomFieldNames(ctx context.Context, GID uuid.UUID) ([]string, error) {
|
||||
type st struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
var fields []st
|
||||
|
||||
err := e.db.Item.Query().
|
||||
Where(
|
||||
item.HasGroupWith(group.ID(GID)),
|
||||
).
|
||||
QueryFields().
|
||||
Unique(true).
|
||||
Select(itemfield.FieldName).
|
||||
Scan(ctx, &fields)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get custom fields: %w", err)
|
||||
}
|
||||
|
||||
fieldNames := make([]string, len(fields))
|
||||
for i, f := range fields {
|
||||
fieldNames[i] = f.Name
|
||||
}
|
||||
|
||||
return fieldNames, nil
|
||||
}
|
||||
|
||||
// ZeroOutTimeFields is a helper function that can be invoked via the UI by a group member which will
|
||||
// set all date fields to the beginning of the day.
|
||||
//
|
||||
// This is designed to resolve a long-time bug that has since been fixed with the time selector on the
|
||||
// frontend. This function is intended to be used as a one-time fix for existing databases and may be
|
||||
// removed in the future.
|
||||
func (e *ItemsRepository) ZeroOutTimeFields(ctx context.Context, GID uuid.UUID) (int, error) {
|
||||
q := e.db.Item.Query().Where(
|
||||
item.HasGroupWith(group.ID(GID)),
|
||||
item.Or(
|
||||
item.PurchaseTimeNotNil(),
|
||||
item.SoldTimeNotNil(),
|
||||
item.WarrantyExpiresNotNil(),
|
||||
),
|
||||
)
|
||||
|
||||
items, err := q.All(ctx)
|
||||
if err != nil {
|
||||
return -1, fmt.Errorf("ZeroOutTimeFields() -> failed to get items: %w", err)
|
||||
}
|
||||
|
||||
toDateOnly := func(t time.Time) time.Time {
|
||||
return time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
|
||||
}
|
||||
|
||||
updated := 0
|
||||
|
||||
for _, i := range items {
|
||||
updateQ := e.db.Item.Update().Where(item.ID(i.ID))
|
||||
|
||||
if !i.PurchaseTime.IsZero() {
|
||||
updateQ.SetPurchaseTime(toDateOnly(i.PurchaseTime))
|
||||
}
|
||||
|
||||
if !i.SoldTime.IsZero() {
|
||||
updateQ.SetSoldTime(toDateOnly(i.SoldTime))
|
||||
}
|
||||
|
||||
if !i.WarrantyExpires.IsZero() {
|
||||
updateQ.SetWarrantyExpires(toDateOnly(i.WarrantyExpires))
|
||||
}
|
||||
|
||||
_, err = updateQ.Save(ctx)
|
||||
if err != nil {
|
||||
return updated, fmt.Errorf("ZeroOutTimeFields() -> failed to update item: %w", err)
|
||||
}
|
||||
|
||||
updated++
|
||||
}
|
||||
|
||||
return updated, nil
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func itemFactory() ItemCreate {
|
||||
@@ -36,6 +37,8 @@ func useItems(t *testing.T, len int) []ItemOut {
|
||||
for _, item := range items {
|
||||
_ = tRepos.Items.Delete(context.Background(), item.ID)
|
||||
}
|
||||
|
||||
_ = tRepos.Locations.Delete(context.Background(), location.ID)
|
||||
})
|
||||
|
||||
return items
|
||||
@@ -271,3 +274,48 @@ func TestItemsRepository_Update(t *testing.T) {
|
||||
assert.Equal(t, updateData.WarrantyDetails, got.WarrantyDetails)
|
||||
assert.Equal(t, updateData.LifetimeWarranty, got.LifetimeWarranty)
|
||||
}
|
||||
|
||||
func TestItemRepository_GetAllCustomFields(t *testing.T) {
|
||||
const FIELDS_COUNT = 5
|
||||
|
||||
entity := useItems(t, 1)[0]
|
||||
|
||||
fields := make([]ItemField, FIELDS_COUNT)
|
||||
names := make([]string, FIELDS_COUNT)
|
||||
values := make([]string, FIELDS_COUNT)
|
||||
|
||||
for i := 0; i < FIELDS_COUNT; i++ {
|
||||
name := fk.Str(10)
|
||||
fields[i] = ItemField{
|
||||
Name: name,
|
||||
Type: "text",
|
||||
TextValue: fk.Str(10),
|
||||
}
|
||||
names[i] = name
|
||||
values[i] = fields[i].TextValue
|
||||
}
|
||||
|
||||
_, err := tRepos.Items.UpdateByGroup(context.Background(), tGroup.ID, ItemUpdate{
|
||||
ID: entity.ID,
|
||||
Name: entity.Name,
|
||||
LocationID: entity.Location.ID,
|
||||
Fields: fields,
|
||||
})
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
// Test getting all fields
|
||||
{
|
||||
results, err := tRepos.Items.GetAllCustomFieldNames(context.Background(), tGroup.ID)
|
||||
assert.NoError(t, err)
|
||||
assert.ElementsMatch(t, names, results)
|
||||
}
|
||||
|
||||
// Test getting all values from field
|
||||
{
|
||||
results, err := tRepos.Items.GetAllCustomFieldValues(context.Background(), tUser.GroupID, names[0])
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.ElementsMatch(t, values[:1], results)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,9 @@ type LocationRepository struct {
|
||||
|
||||
type (
|
||||
LocationCreate struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Name string `json:"name"`
|
||||
ParentID uuid.UUID `json:"parentId" extensions:"x-nullable"`
|
||||
Description string `json:"description"`
|
||||
}
|
||||
|
||||
LocationUpdate struct {
|
||||
@@ -152,7 +153,9 @@ func (r *LocationRepository) getOne(ctx context.Context, where ...predicate.Loca
|
||||
Where(where...).
|
||||
WithGroup().
|
||||
WithItems(func(iq *ent.ItemQuery) {
|
||||
iq.Where(item.Archived(false)).WithLabel()
|
||||
iq.Where(item.Archived(false)).
|
||||
Order(ent.Asc(item.FieldName)).
|
||||
WithLabel()
|
||||
}).
|
||||
WithParent().
|
||||
WithChildren().
|
||||
@@ -168,11 +171,16 @@ func (r *LocationRepository) GetOneByGroup(ctx context.Context, GID, ID uuid.UUI
|
||||
}
|
||||
|
||||
func (r *LocationRepository) Create(ctx context.Context, GID uuid.UUID, data LocationCreate) (LocationOut, error) {
|
||||
location, err := r.db.Location.Create().
|
||||
q := r.db.Location.Create().
|
||||
SetName(data.Name).
|
||||
SetDescription(data.Description).
|
||||
SetGroupID(GID).
|
||||
Save(ctx)
|
||||
SetGroupID(GID)
|
||||
|
||||
if data.ParentID != uuid.Nil {
|
||||
q.SetParentID(data.ParentID)
|
||||
}
|
||||
|
||||
location, err := q.Save(ctx)
|
||||
|
||||
if err != nil {
|
||||
return LocationOut{}, err
|
||||
@@ -218,3 +226,129 @@ func (r *LocationRepository) DeleteByGroup(ctx context.Context, GID, ID uuid.UUI
|
||||
_, err := r.db.Location.Delete().Where(location.ID(ID), location.HasGroupWith(group.ID(GID))).Exec(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
type TreeItem struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Children []*TreeItem `json:"children"`
|
||||
}
|
||||
|
||||
type FlatTreeItem struct {
|
||||
ID uuid.UUID
|
||||
Name string
|
||||
Type string
|
||||
ParentID uuid.UUID
|
||||
Level int
|
||||
}
|
||||
|
||||
type TreeQuery struct {
|
||||
WithItems bool `json:"withItems"`
|
||||
}
|
||||
|
||||
func (lr *LocationRepository) Tree(ctx context.Context, GID uuid.UUID, tq TreeQuery) ([]TreeItem, error) {
|
||||
query := `
|
||||
WITH recursive location_tree(id, NAME, location_children, level, node_type) AS
|
||||
(
|
||||
SELECT id,
|
||||
NAME,
|
||||
location_children,
|
||||
0 AS level,
|
||||
'location' AS node_type
|
||||
FROM locations
|
||||
WHERE location_children IS NULL
|
||||
AND group_locations = ?
|
||||
|
||||
UNION ALL
|
||||
SELECT c.id,
|
||||
c.NAME,
|
||||
c.location_children,
|
||||
level + 1,
|
||||
'location' AS node_type
|
||||
FROM locations c
|
||||
JOIN location_tree p
|
||||
ON c.location_children = p.id
|
||||
WHERE level < 10 -- prevent infinite loop & excessive recursion
|
||||
|
||||
{{ WITH_ITEMS }}
|
||||
)
|
||||
SELECT id,
|
||||
NAME,
|
||||
level,
|
||||
location_children,
|
||||
node_type
|
||||
FROM location_tree
|
||||
ORDER BY level,
|
||||
node_type DESC, -- sort locations before items
|
||||
lower(NAME)`
|
||||
|
||||
if tq.WithItems {
|
||||
itemQuery := `
|
||||
UNION ALL
|
||||
SELECT i.id,
|
||||
i.name,
|
||||
location_items as location_children,
|
||||
level + 1,
|
||||
'item' AS node_type
|
||||
FROM items i
|
||||
JOIN location_tree p
|
||||
ON i.location_items = p.id
|
||||
WHERE level < 10 -- prevent infinite loop & excessive recursion`
|
||||
query = strings.ReplaceAll(query, "{{ WITH_ITEMS }}", itemQuery)
|
||||
} else {
|
||||
query = strings.ReplaceAll(query, "{{ WITH_ITEMS }}", "")
|
||||
}
|
||||
|
||||
rows, err := lr.db.Sql().QueryContext(ctx, query, GID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var locations []FlatTreeItem
|
||||
for rows.Next() {
|
||||
var location FlatTreeItem
|
||||
if err := rows.Scan(&location.ID, &location.Name, &location.Level, &location.ParentID, &location.Type); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
locations = append(locations, location)
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ConvertLocationsToTree(locations), nil
|
||||
}
|
||||
|
||||
func ConvertLocationsToTree(locations []FlatTreeItem) []TreeItem {
|
||||
var locationMap = make(map[uuid.UUID]*TreeItem, len(locations))
|
||||
|
||||
var rootIds []uuid.UUID
|
||||
|
||||
for _, location := range locations {
|
||||
loc := &TreeItem{
|
||||
ID: location.ID,
|
||||
Name: location.Name,
|
||||
Type: location.Type,
|
||||
Children: []*TreeItem{},
|
||||
}
|
||||
|
||||
locationMap[location.ID] = loc
|
||||
if location.ParentID != uuid.Nil {
|
||||
parent, ok := locationMap[location.ParentID]
|
||||
if ok {
|
||||
parent.Children = append(parent.Children, loc)
|
||||
}
|
||||
} else {
|
||||
rootIds = append(rootIds, location.ID)
|
||||
}
|
||||
}
|
||||
|
||||
roots := make([]TreeItem, 0, len(rootIds))
|
||||
for _, id := range rootIds {
|
||||
roots = append(roots, *locationMap[id])
|
||||
}
|
||||
|
||||
return roots
|
||||
}
|
||||
|
||||
@@ -2,8 +2,11 @@ package repo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
@@ -14,6 +17,30 @@ func locationFactory() LocationCreate {
|
||||
}
|
||||
}
|
||||
|
||||
func useLocations(t *testing.T, len int) []LocationOut {
|
||||
t.Helper()
|
||||
|
||||
out := make([]LocationOut, len)
|
||||
|
||||
for i := 0; i < len; i++ {
|
||||
loc, err := tRepos.Locations.Create(context.Background(), tGroup.ID, locationFactory())
|
||||
assert.NoError(t, err)
|
||||
out[i] = loc
|
||||
}
|
||||
|
||||
t.Cleanup(func() {
|
||||
for _, loc := range out {
|
||||
err := tRepos.Locations.Delete(context.Background(), loc.ID)
|
||||
|
||||
if err != nil {
|
||||
assert.True(t, ent.IsNotFound(err))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
func TestLocationRepository_Get(t *testing.T) {
|
||||
loc, err := tRepos.Locations.Create(context.Background(), tGroup.ID, locationFactory())
|
||||
assert.NoError(t, err)
|
||||
@@ -29,13 +56,9 @@ func TestLocationRepository_Get(t *testing.T) {
|
||||
|
||||
func TestLocationRepositoryGetAllWithCount(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
result, err := tRepos.Locations.Create(ctx, tGroup.ID, LocationCreate{
|
||||
Name: fk.Str(10),
|
||||
Description: fk.Str(100),
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
result := useLocations(t, 1)[0]
|
||||
|
||||
_, err = tRepos.Items.Create(ctx, tGroup.ID, ItemCreate{
|
||||
_, err := tRepos.Items.Create(ctx, tGroup.ID, ItemCreate{
|
||||
Name: fk.Str(10),
|
||||
Description: fk.Str(100),
|
||||
LocationID: result.ID,
|
||||
@@ -55,8 +78,7 @@ func TestLocationRepositoryGetAllWithCount(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLocationRepository_Create(t *testing.T) {
|
||||
loc, err := tRepos.Locations.Create(context.Background(), tGroup.ID, locationFactory())
|
||||
assert.NoError(t, err)
|
||||
loc := useLocations(t, 1)[0]
|
||||
|
||||
// Get by ID
|
||||
foundLoc, err := tRepos.Locations.Get(context.Background(), loc.ID)
|
||||
@@ -68,8 +90,7 @@ func TestLocationRepository_Create(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLocationRepository_Update(t *testing.T) {
|
||||
loc, err := tRepos.Locations.Create(context.Background(), tGroup.ID, locationFactory())
|
||||
assert.NoError(t, err)
|
||||
loc := useLocations(t, 1)[0]
|
||||
|
||||
updateData := LocationUpdate{
|
||||
ID: loc.ID,
|
||||
@@ -92,12 +113,154 @@ func TestLocationRepository_Update(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLocationRepository_Delete(t *testing.T) {
|
||||
loc, err := tRepos.Locations.Create(context.Background(), tGroup.ID, locationFactory())
|
||||
assert.NoError(t, err)
|
||||
loc := useLocations(t, 1)[0]
|
||||
|
||||
err = tRepos.Locations.Delete(context.Background(), loc.ID)
|
||||
err := tRepos.Locations.Delete(context.Background(), loc.ID)
|
||||
assert.NoError(t, err)
|
||||
|
||||
_, err = tRepos.Locations.Get(context.Background(), loc.ID)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestItemRepository_TreeQuery(t *testing.T) {
|
||||
locs := useLocations(t, 3)
|
||||
|
||||
// Set relations
|
||||
_, err := tRepos.Locations.UpdateOneByGroup(context.Background(), tGroup.ID, locs[0].ID, LocationUpdate{
|
||||
ID: locs[0].ID,
|
||||
ParentID: locs[1].ID,
|
||||
Name: locs[0].Name,
|
||||
Description: locs[0].Description,
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
locations, err := tRepos.Locations.Tree(context.Background(), tGroup.ID, TreeQuery{WithItems: true})
|
||||
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, 2, len(locations))
|
||||
|
||||
// Check roots
|
||||
for _, loc := range locations {
|
||||
if loc.ID == locs[1].ID {
|
||||
assert.Equal(t, 1, len(loc.Children))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConvertLocationsToTree(t *testing.T) {
|
||||
uuid1, uuid2, uuid3, uuid4 := uuid.New(), uuid.New(), uuid.New(), uuid.New()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
locations []FlatTreeItem
|
||||
expected []TreeItem
|
||||
}{
|
||||
{
|
||||
name: "Convert locations to tree",
|
||||
locations: []FlatTreeItem{
|
||||
{
|
||||
ID: uuid1,
|
||||
Name: "Root1",
|
||||
ParentID: uuid.Nil,
|
||||
Level: 0,
|
||||
},
|
||||
{
|
||||
ID: uuid2,
|
||||
Name: "Child1",
|
||||
ParentID: uuid1,
|
||||
Level: 1,
|
||||
},
|
||||
{
|
||||
ID: uuid3,
|
||||
Name: "Child2",
|
||||
ParentID: uuid1,
|
||||
Level: 1,
|
||||
},
|
||||
},
|
||||
expected: []TreeItem{
|
||||
{
|
||||
ID: uuid1,
|
||||
Name: "Root1",
|
||||
Children: []*TreeItem{
|
||||
{
|
||||
ID: uuid2,
|
||||
Name: "Child1",
|
||||
Children: []*TreeItem{},
|
||||
},
|
||||
{
|
||||
ID: uuid3,
|
||||
Name: "Child2",
|
||||
Children: []*TreeItem{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Convert locations to tree with deeply nested children",
|
||||
locations: []FlatTreeItem{
|
||||
{
|
||||
ID: uuid1,
|
||||
Name: "Root1",
|
||||
ParentID: uuid.Nil,
|
||||
Level: 0,
|
||||
},
|
||||
{
|
||||
ID: uuid2,
|
||||
Name: "Child1",
|
||||
ParentID: uuid1,
|
||||
Level: 1,
|
||||
},
|
||||
{
|
||||
ID: uuid3,
|
||||
Name: "Child2",
|
||||
ParentID: uuid2,
|
||||
Level: 2,
|
||||
},
|
||||
{
|
||||
ID: uuid4,
|
||||
Name: "Child3",
|
||||
ParentID: uuid3,
|
||||
Level: 3,
|
||||
},
|
||||
},
|
||||
expected: []TreeItem{
|
||||
{
|
||||
ID: uuid1,
|
||||
Name: "Root1",
|
||||
Children: []*TreeItem{
|
||||
{
|
||||
ID: uuid2,
|
||||
Name: "Child1",
|
||||
Children: []*TreeItem{
|
||||
{
|
||||
ID: uuid3,
|
||||
Name: "Child2",
|
||||
Children: []*TreeItem{
|
||||
{
|
||||
ID: uuid4,
|
||||
Name: "Child3",
|
||||
Children: []*TreeItem{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
result := ConvertLocationsToTree(tc.locations)
|
||||
|
||||
// Compare JSON strings
|
||||
expected, _ := json.Marshal(tc.expected)
|
||||
got, _ := json.Marshal(result)
|
||||
assert.Equal(t, string(expected), string(got))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ func (e *UserRepository) GetOneId(ctx context.Context, id uuid.UUID) (UserOut, e
|
||||
|
||||
func (e *UserRepository) GetOneEmail(ctx context.Context, email string) (UserOut, error) {
|
||||
return mapUserOutErr(e.db.User.Query().
|
||||
Where(user.Email(email)).
|
||||
Where(user.EmailEqualFold(email)).
|
||||
WithGroup().
|
||||
Only(ctx),
|
||||
)
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/ardanlabs/conf/v2"
|
||||
"github.com/ardanlabs/conf/v3"
|
||||
|
||||
"os"
|
||||
)
|
||||
|
||||
@@ -34,8 +34,11 @@ Homebox is currently in early-active development and is currently in **beta** st
|
||||
- Purchased From Information
|
||||
- Item Identifications (Serial, Model, etc)
|
||||
- Categorized Attachments (Images, Manuals, General)
|
||||
- Arbitrary/Custom Fields - _Coming Soon!_
|
||||
- Csv Import for quickly creating and managing items - _Export Coming Soon!_
|
||||
- Arbitrary/Custom Fields
|
||||
- Csv Import for quickly creating and managing items
|
||||
- Custom Reporting
|
||||
- Bill of Materials Export
|
||||
- QR Code Label Generator
|
||||
- Organize _Items_ by creating _Labels_ and _Locations_ and assigning them to items.
|
||||
- Multi-Tenant Support - All users are placed inside of a group and can only see items that are apart of their group. Invite family members to your group, or share an instance among friends!
|
||||
|
||||
|
||||
@@ -41,3 +41,8 @@ Homebox has a built-in QR code generator that can be used to generate QR codes f
|
||||
|
||||
However, the API endpoint is available for generating QR codes on the fly for any item (or any other data) if you provide a valid API key in the query parameters. An example url would look like `/api/v1/qrcode?data=https://homebox.fly.dev/item/{uuid}&access_token={api_key}`. Currently the easiest way to get an API token is to use one from an existing URL of the QR Code in the API key, but this will be improved in the future.
|
||||
|
||||
:octicons-tag-24: 0.8.0
|
||||
|
||||
In version 0.8.0 We've added a custom label generation. On the tools page, there is now a link to the label-generator page where you can generate labels based on Asset ID for your inventory. These are still in early development, so please provide feedback. There's also more information on the implementation on the label generator page.
|
||||
|
||||
[Demo](https://homebox.fly.dev/reports/label-generator)
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<NuxtLayout>
|
||||
<Html lang="en" :data-theme="theme || 'homebox'" />
|
||||
<Link rel="icon" type="image/svg" href="/favicon.svg"></Link>
|
||||
<NuxtPage />
|
||||
</NuxtLayout>
|
||||
</template>
|
||||
|
||||
@@ -4,4 +4,23 @@
|
||||
|
||||
.btn {
|
||||
text-transform: none !important;
|
||||
}
|
||||
|
||||
/* transparent subtle scrollbar */
|
||||
::-webkit-scrollbar {
|
||||
width: 0.2em;
|
||||
background-color: #F5F5F5;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background-color: rgba(0,0,0,.2);
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0.3);
|
||||
background-color: #F5F5F5;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: #9B9B9B;
|
||||
}
|
||||
@@ -53,11 +53,16 @@
|
||||
);
|
||||
|
||||
function setFile(e: Event) {
|
||||
importCsv.value = e.target.files[0];
|
||||
const result = e.target as HTMLInputElement;
|
||||
if (!result.files || result.files.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
importCsv.value = result.files[0];
|
||||
}
|
||||
|
||||
function uploadCsv() {
|
||||
importRef.value.click();
|
||||
importRef.value?.click();
|
||||
}
|
||||
|
||||
const eventBus = useEventBus();
|
||||
@@ -85,6 +90,8 @@
|
||||
importRef.value.value = "";
|
||||
}
|
||||
|
||||
eventBus.emit(EventTypes.ClearStores);
|
||||
eventBus.emit(EventTypes.InvalidStores);
|
||||
|
||||
toast.success("Import successful!");
|
||||
}
|
||||
</script>
|
||||
|
||||
17
frontend/components/DetailAction.vue
Normal file
17
frontend/components/DetailAction.vue
Normal file
@@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-10 py-6">
|
||||
<div class="col-span-3">
|
||||
<h4 class="mb-1 text-lg font-semibold">
|
||||
<slot name="title"></slot>
|
||||
</h4>
|
||||
<p class="text-sm">
|
||||
<slot></slot>
|
||||
</p>
|
||||
</div>
|
||||
<BaseButton class="btn-primary mt-auto" @click="$emit('action')">
|
||||
<slot name="button">
|
||||
<slot name="title"></slot>
|
||||
</slot>
|
||||
</BaseButton>
|
||||
</div>
|
||||
</template>
|
||||
@@ -6,7 +6,7 @@
|
||||
<div class="dropdown dropdown-top sm:dropdown-end">
|
||||
<div class="relative">
|
||||
<input
|
||||
v-model="isearch"
|
||||
v-model="internalSearch"
|
||||
tabindex="0"
|
||||
class="input w-full items-center flex flex-wrap border border-gray-400 rounded-lg"
|
||||
@keyup.enter="selectFirst"
|
||||
@@ -26,9 +26,11 @@
|
||||
class="dropdown-content mb-1 menu shadow border border-gray-400 rounded bg-base-100 w-full z-[9999] max-h-60 overflow-y-scroll"
|
||||
>
|
||||
<li v-for="(obj, idx) in filtered" :key="idx">
|
||||
<button type="button" @click="select(obj)">
|
||||
{{ usingObjects ? obj[itemText] : obj }}
|
||||
</button>
|
||||
<div type="button" @click="select(obj)">
|
||||
<slot name="display" v-bind="{ item: obj }">
|
||||
{{ usingObjects ? obj[itemText] : obj }}
|
||||
</slot>
|
||||
</div>
|
||||
</li>
|
||||
<li class="hidden first:flex">
|
||||
<button disabled>
|
||||
@@ -49,9 +51,10 @@
|
||||
|
||||
interface Props {
|
||||
label: string;
|
||||
modelValue: string | ItemsObject;
|
||||
modelValue: string | ItemsObject | null | undefined;
|
||||
items: ItemsObject[] | string[];
|
||||
itemText?: keyof ItemsObject;
|
||||
itemSearch?: keyof ItemsObject | null;
|
||||
itemValue?: keyof ItemsObject;
|
||||
search?: string;
|
||||
noResultsText?: string;
|
||||
@@ -63,21 +66,34 @@
|
||||
modelValue: "",
|
||||
items: () => [],
|
||||
itemText: "text",
|
||||
itemValue: "value",
|
||||
search: "",
|
||||
itemSearch: null,
|
||||
itemValue: "value",
|
||||
noResultsText: "No Results Found",
|
||||
});
|
||||
|
||||
const searchKey = computed(() => props.itemSearch || props.itemText);
|
||||
|
||||
function clear() {
|
||||
select(value.value);
|
||||
}
|
||||
|
||||
const isearch = ref("");
|
||||
watch(isearch, () => {
|
||||
internalSearch.value = isearch.value;
|
||||
});
|
||||
const internalSearch = ref("");
|
||||
|
||||
watch(
|
||||
() => props.search,
|
||||
val => {
|
||||
internalSearch.value = val;
|
||||
}
|
||||
);
|
||||
|
||||
watch(
|
||||
() => internalSearch.value,
|
||||
val => {
|
||||
emit("update:search", val);
|
||||
}
|
||||
);
|
||||
|
||||
const internalSearch = useVModel(props, "search", emit);
|
||||
const value = useVModel(props, "modelValue", emit);
|
||||
|
||||
const usingObjects = computed(() => {
|
||||
@@ -102,9 +118,9 @@
|
||||
() => {
|
||||
if (value.value) {
|
||||
if (typeof value.value === "string") {
|
||||
isearch.value = value.value;
|
||||
internalSearch.value = value.value;
|
||||
} else {
|
||||
isearch.value = value.value[props.itemText] as string;
|
||||
internalSearch.value = value.value[searchKey.value] as string;
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -113,7 +129,7 @@
|
||||
}
|
||||
);
|
||||
|
||||
function select(obj: string | ItemsObject) {
|
||||
function select(obj: Props["modelValue"]) {
|
||||
if (isStrings(props.items)) {
|
||||
if (obj === value.value) {
|
||||
value.value = "";
|
||||
@@ -131,16 +147,16 @@
|
||||
}
|
||||
|
||||
const filtered = computed(() => {
|
||||
if (!isearch.value || isearch.value === "") {
|
||||
if (!internalSearch.value || internalSearch.value === "") {
|
||||
return props.items;
|
||||
}
|
||||
|
||||
if (isStrings(props.items)) {
|
||||
return props.items.filter(item => item.toLowerCase().includes(isearch.value.toLowerCase()));
|
||||
return props.items.filter(item => item.toLowerCase().includes(internalSearch.value.toLowerCase()));
|
||||
} else {
|
||||
return props.items.filter(item => {
|
||||
if (props.itemText && props.itemText in item) {
|
||||
return (item[props.itemText] as string).toLowerCase().includes(isearch.value.toLowerCase());
|
||||
if (searchKey.value && searchKey.value in item) {
|
||||
return (item[searchKey.value] as string).toLowerCase().includes(internalSearch.value.toLowerCase());
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
157
frontend/components/Form/Autocomplete2.vue
Normal file
157
frontend/components/Form/Autocomplete2.vue
Normal file
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<div>
|
||||
<Combobox v-model="value">
|
||||
<ComboboxLabel class="label">
|
||||
<span class="label-text">{{ label }}</span>
|
||||
</ComboboxLabel>
|
||||
<div class="relative">
|
||||
<ComboboxInput
|
||||
:display-value="i => extractDisplay(i as SupportValues)"
|
||||
class="w-full input input-bordered"
|
||||
@change="search = $event.target.value"
|
||||
/>
|
||||
<ComboboxButton class="absolute inset-y-0 right-0 flex items-center rounded-r-md px-2 focus:outline-none">
|
||||
<Icon name="mdi-chevron-down" class="w-5 h-5" />
|
||||
</ComboboxButton>
|
||||
<ComboboxOptions
|
||||
v-if="computedItems.length > 0"
|
||||
class="absolute dropdown-content z-10 mt-2 max-h-60 w-full overflow-auto rounded-md card bg-base-100 border border-gray-400"
|
||||
>
|
||||
<ComboboxOption
|
||||
v-for="item in computedItems"
|
||||
:key="item.id"
|
||||
v-slot="{ active, selected }"
|
||||
:value="item.value"
|
||||
as="template"
|
||||
>
|
||||
<li
|
||||
:class="[
|
||||
'relative cursor-default select-none py-2 pl-3 pr-9 duration-75 ease-in-out transition-colors',
|
||||
active ? 'bg-primary text-white' : 'text-gray-900',
|
||||
]"
|
||||
>
|
||||
<slot name="display" v-bind="{ item: item, selected, active }">
|
||||
<span :class="['block truncate', selected && 'font-semibold']">
|
||||
{{ item.display }}
|
||||
</span>
|
||||
<span
|
||||
v-if="selected"
|
||||
:class="[
|
||||
'absolute inset-y-0 right-0 flex text-primary items-center pr-4',
|
||||
active ? 'text-primary-content' : 'bg-primary',
|
||||
]"
|
||||
>
|
||||
<Icon name="mdi-check" class="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
</slot>
|
||||
</li>
|
||||
</ComboboxOption>
|
||||
</ComboboxOptions>
|
||||
</div>
|
||||
</Combobox>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
Combobox,
|
||||
ComboboxInput,
|
||||
ComboboxOptions,
|
||||
ComboboxOption,
|
||||
ComboboxButton,
|
||||
ComboboxLabel,
|
||||
} from "@headlessui/vue";
|
||||
|
||||
type SupportValues = string | { [key: string]: any };
|
||||
|
||||
type ComboItem = {
|
||||
display: string;
|
||||
value: SupportValues;
|
||||
id: number;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
label: string;
|
||||
modelValue: SupportValues | null | undefined;
|
||||
items: string[] | object[];
|
||||
display?: string;
|
||||
multiple?: boolean;
|
||||
};
|
||||
|
||||
const emit = defineEmits(["update:modelValue", "update:search"]);
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
label: "",
|
||||
modelValue: "",
|
||||
display: "text",
|
||||
multiple: false,
|
||||
});
|
||||
|
||||
const search = ref("");
|
||||
const value = useVModel(props, "modelValue", emit);
|
||||
|
||||
function extractDisplay(item?: SupportValues): string {
|
||||
if (!item) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (typeof item === "string") {
|
||||
return item;
|
||||
}
|
||||
|
||||
if (props.display in item) {
|
||||
return item[props.display] as string;
|
||||
}
|
||||
|
||||
// Try these options as well
|
||||
const fallback = ["name", "title", "display", "value"];
|
||||
for (let i = 0; i < fallback.length; i++) {
|
||||
const key = fallback[i];
|
||||
if (key in item) {
|
||||
return item[key] as string;
|
||||
}
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
const computedItems = computed<ComboItem[]>(() => {
|
||||
const list: ComboItem[] = [];
|
||||
|
||||
for (let i = 0; i < props.items.length; i++) {
|
||||
const item = props.items[i];
|
||||
|
||||
const out: Partial<ComboItem> = {
|
||||
id: i,
|
||||
value: item,
|
||||
};
|
||||
|
||||
switch (typeof item) {
|
||||
case "string":
|
||||
out.display = item;
|
||||
break;
|
||||
case "object":
|
||||
// @ts-ignore - up to the user to provide a valid display key
|
||||
out.display = item[props.display] as string;
|
||||
break;
|
||||
default:
|
||||
out.display = "";
|
||||
break;
|
||||
}
|
||||
|
||||
if (search.value && out.display) {
|
||||
const foldSearch = search.value.toLowerCase();
|
||||
const foldDisplay = out.display.toLowerCase();
|
||||
|
||||
if (foldDisplay.startsWith(foldSearch)) {
|
||||
list.push(out as ComboItem);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
list.push(out as ComboItem);
|
||||
}
|
||||
|
||||
return list;
|
||||
});
|
||||
</script>
|
||||
@@ -1,38 +1,15 @@
|
||||
<template>
|
||||
<div ref="label" class="dropdown dropdown-end dropdown-top w-full">
|
||||
<FormTextField v-model="dateText" tabindex="0" label="Date" :inline="inline" readonly />
|
||||
<div tabindex="0" class="card compact dropdown-content shadow bg-base-100 rounded-box w-64" @blur="resetTime">
|
||||
<div class="card-body">
|
||||
<div class="grid grid-cols-7 gap-2">
|
||||
<div v-for="d in daysIdx" :key="d">
|
||||
<p class="text-center">
|
||||
{{ d }}
|
||||
</p>
|
||||
</div>
|
||||
<template v-for="day in days">
|
||||
<button
|
||||
v-if="day.number != ''"
|
||||
:key="day.number"
|
||||
type="button"
|
||||
class="text-center btn-xs btn btn-outline"
|
||||
@click="select($event, day.date)"
|
||||
>
|
||||
{{ day.number }}
|
||||
</button>
|
||||
<div v-else :key="`${day.number}-empty`"></div>
|
||||
</template>
|
||||
</div>
|
||||
<div class="flex justify-between mt-1 items-center">
|
||||
<button type="button" class="btn btn-xs" @click="prevMonth">
|
||||
<Icon class="h-5 w-5" name="mdi-arrow-left"></Icon>
|
||||
</button>
|
||||
<p class="text-center">{{ month }} {{ year }}</p>
|
||||
<button type="button" class="btn btn-xs" @click="nextMonth">
|
||||
<Icon class="h-5 w-5" name="mdi-arrow-right"></Icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!inline" class="form-control w-full">
|
||||
<label class="label">
|
||||
<span class="label-text"> Date </span>
|
||||
</label>
|
||||
<input ref="input" v-model="selected" type="date" class="input input-bordered w-full" />
|
||||
</div>
|
||||
<div v-else class="sm:grid sm:grid-cols-4 sm:items-start sm:gap-4">
|
||||
<label class="label">
|
||||
<span class="label-text"> Date </span>
|
||||
</label>
|
||||
<input v-model="selected" type="date" class="input input-bordered col-span-3 w-full mt-2" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -41,7 +18,7 @@
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Date,
|
||||
type: Date as () => Date | string,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
@@ -51,88 +28,28 @@
|
||||
},
|
||||
});
|
||||
|
||||
const selected = useVModel(props, "modelValue", emit);
|
||||
const dateText = computed(() => {
|
||||
if (!validDate(selected.value)) {
|
||||
return "";
|
||||
}
|
||||
const selected = computed({
|
||||
get() {
|
||||
// return modelValue as string as YYYY-MM-DD or null
|
||||
if (validDate(props.modelValue)) {
|
||||
if (typeof props.modelValue === "string") {
|
||||
return props.modelValue;
|
||||
}
|
||||
|
||||
if (selected.value) {
|
||||
return selected.value.toLocaleDateString();
|
||||
}
|
||||
return props.modelValue ? props.modelValue.toISOString().split("T")[0] : null;
|
||||
}
|
||||
|
||||
return "";
|
||||
});
|
||||
|
||||
const time = ref(new Date());
|
||||
function resetTime() {
|
||||
time.value = new Date();
|
||||
}
|
||||
|
||||
const label = ref<HTMLElement>();
|
||||
onClickOutside(label, () => {
|
||||
resetTime();
|
||||
});
|
||||
|
||||
const month = computed(() => {
|
||||
return time.value.toLocaleString("default", { month: "long" });
|
||||
});
|
||||
|
||||
const year = computed(() => {
|
||||
return time.value.getFullYear();
|
||||
});
|
||||
|
||||
function nextMonth() {
|
||||
time.value.setMonth(time.value.getMonth() + 1);
|
||||
time.value = new Date(time.value);
|
||||
}
|
||||
|
||||
function prevMonth() {
|
||||
time.value.setMonth(time.value.getMonth() - 1);
|
||||
time.value = new Date(time.value);
|
||||
}
|
||||
|
||||
const daysIdx = computed(() => {
|
||||
return ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
|
||||
});
|
||||
|
||||
function select(e: MouseEvent, day: Date) {
|
||||
selected.value = day;
|
||||
// @ts-ignore - this is a vue3 bug
|
||||
e.target.blur();
|
||||
resetTime();
|
||||
}
|
||||
|
||||
type DayEntry = {
|
||||
number: number | string;
|
||||
date: Date;
|
||||
};
|
||||
|
||||
function daysInMonth(month: number, year: number) {
|
||||
return new Date(year, month, 0).getDate();
|
||||
}
|
||||
|
||||
const days = computed<DayEntry[]>(() => {
|
||||
const days = [];
|
||||
|
||||
const totalDays = daysInMonth(time.value.getMonth() + 1, time.value.getFullYear());
|
||||
|
||||
const firstDay = new Date(time.value.getFullYear(), time.value.getMonth(), 1).getDay();
|
||||
|
||||
for (let i = 0; i < firstDay; i++) {
|
||||
days.push({
|
||||
number: "",
|
||||
date: new Date(),
|
||||
});
|
||||
}
|
||||
|
||||
for (let i = 1; i <= totalDays; i++) {
|
||||
days.push({
|
||||
number: i,
|
||||
date: new Date(time.value.getFullYear(), time.value.getMonth(), i),
|
||||
});
|
||||
}
|
||||
|
||||
return days;
|
||||
return null;
|
||||
},
|
||||
set(value: string | null) {
|
||||
// emit update:modelValue with a Date object or null
|
||||
emit("update:modelValue", value ? new Date(value) : null);
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style class="scoped">
|
||||
::-webkit-calendar-picker-indicator {
|
||||
filter: invert(1);
|
||||
}
|
||||
</style>
|
||||
|
||||
34
frontend/components/Form/Password.vue
Normal file
34
frontend/components/Form/Password.vue
Normal file
@@ -0,0 +1,34 @@
|
||||
<template>
|
||||
<div class="flex">
|
||||
<FormTextField v-model="value" placeholder="Password" label="Password" :type="inputType"> </FormTextField>
|
||||
<button
|
||||
type="button"
|
||||
class="inline-flex p-1 ml-1 justify-center mt-auto mb-3 tooltip"
|
||||
data-tip="Toggle Password Show"
|
||||
@click="toggle()"
|
||||
>
|
||||
<Icon name="mdi-eye" class="h-5 w-5" />
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
type Props = {
|
||||
modelValue: string;
|
||||
placeholder: string;
|
||||
label: string;
|
||||
};
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
placeholder: "Password",
|
||||
label: "Password",
|
||||
});
|
||||
|
||||
const [hide, toggle] = useToggle(true);
|
||||
|
||||
const inputType = computed(() => {
|
||||
return hide.value ? "password" : "text";
|
||||
});
|
||||
|
||||
const value = useVModel(props, "modelValue");
|
||||
</script>
|
||||
@@ -2,7 +2,7 @@
|
||||
<BaseModal v-model="modal">
|
||||
<template #title> Create Item </template>
|
||||
<form @submit.prevent="create(true)">
|
||||
<FormSelect v-model="form.location" label="Location" :items="locations ?? []" />
|
||||
<LocationSelector v-model="form.location" />
|
||||
<FormTextField
|
||||
ref="locationNameRef"
|
||||
v-model="form.name"
|
||||
|
||||
65
frontend/components/Item/View/Selectable.vue
Normal file
65
frontend/components/Item/View/Selectable.vue
Normal file
@@ -0,0 +1,65 @@
|
||||
<script setup lang="ts">
|
||||
import { ViewType } from "~~/composables/use-preferences";
|
||||
import { ItemSummary } from "~~/lib/api/types/data-contracts";
|
||||
|
||||
type Props = {
|
||||
view?: ViewType;
|
||||
items: ItemSummary[];
|
||||
};
|
||||
|
||||
const preferences = useViewPreferences();
|
||||
|
||||
const props = defineProps<Props>();
|
||||
const viewSet = computed(() => {
|
||||
return !!props.view;
|
||||
});
|
||||
|
||||
const itemView = computed(() => {
|
||||
return props.view ?? preferences.value.itemDisplayView;
|
||||
});
|
||||
|
||||
function setViewPreference(view: ViewType) {
|
||||
preferences.value.itemDisplayView = view;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section>
|
||||
<BaseSectionHeader class="mb-5 flex justify-between items-center">
|
||||
Items
|
||||
|
||||
<template #description>
|
||||
<div v-if="!viewSet" class="dropdown dropdown-hover dropdown-left">
|
||||
<label tabindex="0" class="btn btn-ghost m-1">
|
||||
<Icon name="mdi-dots-vertical" class="h-7 w-7" />
|
||||
</label>
|
||||
<ul tabindex="0" class="dropdown-content menu p-2 shadow bg-base-100 rounded-box w-32">
|
||||
<li>
|
||||
<button @click="setViewPreference('card')">
|
||||
<Icon name="mdi-card-text-outline" class="h-5 w-5" />
|
||||
Card
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button @click="setViewPreference('table')">
|
||||
<Icon name="mdi-table" class="h-5 w-5" />
|
||||
Table
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
</BaseSectionHeader>
|
||||
|
||||
<template v-if="itemView === 'table'">
|
||||
<ItemViewTable :items="items" />
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4">
|
||||
<ItemCard v-for="item in items" :key="item.id" :item="item" />
|
||||
</div>
|
||||
</template>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
10
frontend/components/Item/View/Table.types.ts
Normal file
10
frontend/components/Item/View/Table.types.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { ItemSummary } from "~~/lib/api/types/data-contracts";
|
||||
|
||||
export type TableHeader = {
|
||||
text: string;
|
||||
value: keyof ItemSummary;
|
||||
sortable?: boolean;
|
||||
align?: "left" | "center" | "right";
|
||||
};
|
||||
|
||||
export type TableData = Record<string, any>;
|
||||
181
frontend/components/Item/View/Table.vue
Normal file
181
frontend/components/Item/View/Table.vue
Normal file
@@ -0,0 +1,181 @@
|
||||
<template>
|
||||
<BaseCard>
|
||||
<table class="table w-full">
|
||||
<thead>
|
||||
<tr class="bg-primary">
|
||||
<th
|
||||
v-for="h in headers"
|
||||
:key="h.value"
|
||||
class="text-no-transform text-sm bg-neutral text-neutral-content cursor-pointer"
|
||||
@click="sortBy(h.value)"
|
||||
>
|
||||
<div
|
||||
class="flex items-center gap-1"
|
||||
:class="{
|
||||
'justify-center': h.align === 'center',
|
||||
'justify-start': h.align === 'right',
|
||||
'justify-end': h.align === 'left',
|
||||
}"
|
||||
>
|
||||
<template v-if="typeof h === 'string'">{{ h }}</template>
|
||||
<template v-else>{{ h.text }}</template>
|
||||
<div :class="`inline-flex ${sortByProperty === h.value ? '' : 'opacity-0'}`">
|
||||
<span class="swap swap-rotate" :class="{ 'swap-active': pagination.descending }">
|
||||
<Icon name="mdi-arrow-down" class="swap-on h-5 w-5" />
|
||||
<Icon name="mdi-arrow-up" class="swap-off h-5 w-5" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(d, i) in data" :key="d.id" class="hover cursor-pointer" @click="navigateTo(`/item/${d.id}`)">
|
||||
<td
|
||||
v-for="h in headers"
|
||||
:key="`${h.value}-${i}`"
|
||||
class="bg-base-100"
|
||||
:class="{
|
||||
'text-center': h.align === 'center',
|
||||
'text-right': h.align === 'right',
|
||||
'text-left': h.align === 'left',
|
||||
}"
|
||||
>
|
||||
<template v-if="cell(h) === 'cell-name'">
|
||||
<NuxtLink class="hover" :to="`/item/${d.id}`">
|
||||
{{ d.name }}
|
||||
</NuxtLink>
|
||||
</template>
|
||||
<template v-else-if="cell(h) === 'cell-purchasePrice'">
|
||||
<Currency :amount="d.purchasePrice" />
|
||||
</template>
|
||||
<template v-else-if="cell(h) === 'cell-insured'">
|
||||
<Icon v-if="d.insured" name="mdi-check" class="text-green-500 h-5 w-5" />
|
||||
<Icon v-else name="mdi-close" class="text-red-500 h-5 w-5" />
|
||||
</template>
|
||||
<slot v-else :name="cell(h)" v-bind="{ item: d }">
|
||||
{{ extractValue(d, h.value) }}
|
||||
</slot>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div v-if="hasPrev || hasNext" class="border-t p-3 justify-end flex">
|
||||
<div class="btn-group">
|
||||
<button :disabled="!hasPrev" class="btn btn-sm" @click="prev()">«</button>
|
||||
<button class="btn btn-sm">Page {{ pagination.page }}</button>
|
||||
<button :disabled="!hasNext" class="btn btn-sm" @click="next()">»</button>
|
||||
</div>
|
||||
</div>
|
||||
</BaseCard>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { TableData, TableHeader } from "./Table.types";
|
||||
import { ItemSummary } from "~~/lib/api/types/data-contracts";
|
||||
|
||||
type Props = {
|
||||
items: ItemSummary[];
|
||||
};
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const sortByProperty = ref<keyof ItemSummary>("name");
|
||||
|
||||
const headers = computed<TableHeader[]>(() => {
|
||||
return [
|
||||
{ text: "Name", value: "name" },
|
||||
{ text: "Quantity", value: "quantity", align: "center" },
|
||||
{ text: "Insured", value: "insured", align: "center" },
|
||||
{ text: "Price", value: "purchasePrice" },
|
||||
] as TableHeader[];
|
||||
});
|
||||
|
||||
const pagination = reactive({
|
||||
descending: false,
|
||||
page: 1,
|
||||
rowsPerPage: 10,
|
||||
rowsNumber: 0,
|
||||
});
|
||||
|
||||
const next = () => pagination.page++;
|
||||
const hasNext = computed<boolean>(() => {
|
||||
return pagination.page * pagination.rowsPerPage < props.items.length;
|
||||
});
|
||||
|
||||
const prev = () => pagination.page--;
|
||||
const hasPrev = computed<boolean>(() => {
|
||||
return pagination.page > 1;
|
||||
});
|
||||
|
||||
function sortBy(property: keyof ItemSummary) {
|
||||
if (sortByProperty.value === property) {
|
||||
pagination.descending = !pagination.descending;
|
||||
} else {
|
||||
pagination.descending = false;
|
||||
}
|
||||
sortByProperty.value = property;
|
||||
}
|
||||
|
||||
function extractSortable(item: ItemSummary, property: keyof ItemSummary): string | number | boolean {
|
||||
const value = item[property];
|
||||
if (typeof value === "string") {
|
||||
// Try parse float
|
||||
const parsed = parseFloat(value);
|
||||
if (!isNaN(parsed)) {
|
||||
return parsed;
|
||||
}
|
||||
|
||||
return value.toLowerCase();
|
||||
}
|
||||
|
||||
if (typeof value !== "number" && typeof value !== "boolean") {
|
||||
return "";
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
function itemSort(a: ItemSummary, b: ItemSummary) {
|
||||
const aLower = extractSortable(a, sortByProperty.value);
|
||||
const bLower = extractSortable(b, sortByProperty.value);
|
||||
|
||||
if (aLower < bLower) {
|
||||
return -1;
|
||||
}
|
||||
if (aLower > bLower) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const data = computed<TableData[]>(() => {
|
||||
// sort by property
|
||||
let data = [...props.items].sort(itemSort);
|
||||
|
||||
// sort descending
|
||||
if (pagination.descending) {
|
||||
data.reverse();
|
||||
}
|
||||
|
||||
// paginate
|
||||
const start = (pagination.page - 1) * pagination.rowsPerPage;
|
||||
const end = start + pagination.rowsPerPage;
|
||||
data = data.slice(start, end);
|
||||
return data;
|
||||
});
|
||||
|
||||
function extractValue(data: TableData, value: string) {
|
||||
const parts = value.split(".");
|
||||
let current = data;
|
||||
for (const part of parts) {
|
||||
current = current[part];
|
||||
}
|
||||
return current;
|
||||
}
|
||||
|
||||
function cell(h: TableHeader) {
|
||||
return `cell-${h.value.replace(".", "_")}`;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -10,6 +10,7 @@
|
||||
label="Location Name"
|
||||
/>
|
||||
<FormTextArea v-model="form.description" label="Location Description" />
|
||||
<LocationSelector v-model="form.parent" />
|
||||
<div class="modal-action">
|
||||
<BaseButton type="submit" :loading="loading"> Create </BaseButton>
|
||||
</div>
|
||||
@@ -18,6 +19,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { LocationSummary } from "~~/lib/api/types/data-contracts";
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
@@ -31,6 +33,7 @@
|
||||
const form = reactive({
|
||||
name: "",
|
||||
description: "",
|
||||
parent: null as LocationSummary | null,
|
||||
});
|
||||
|
||||
whenever(
|
||||
@@ -43,6 +46,7 @@
|
||||
function reset() {
|
||||
form.name = "";
|
||||
form.description = "";
|
||||
form.parent = null;
|
||||
focused.value = false;
|
||||
modal.value = false;
|
||||
loading.value = false;
|
||||
@@ -54,7 +58,11 @@
|
||||
async function create() {
|
||||
loading.value = true;
|
||||
|
||||
const { data, error } = await api.locations.create(form);
|
||||
const { data, error } = await api.locations.create({
|
||||
name: form.name,
|
||||
description: form.description,
|
||||
parentId: form.parent ? form.parent.id : null,
|
||||
});
|
||||
|
||||
if (error) {
|
||||
toast.error("Couldn't create location");
|
||||
|
||||
55
frontend/components/Location/Selector.vue
Normal file
55
frontend/components/Location/Selector.vue
Normal file
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<FormAutocomplete2 v-if="locations" v-model="value" :items="locations" display="name" label="Parent Location">
|
||||
<template #display="{ item, selected, active }">
|
||||
<div>
|
||||
<div class="flex w-full">
|
||||
{{ cast(item.value).name }}
|
||||
<span
|
||||
v-if="selected"
|
||||
:class="['absolute inset-y-0 right-0 flex items-center pr-4', active ? 'text-white' : 'text-primary']"
|
||||
>
|
||||
<Icon name="mdi-check" class="h-5 w-5" aria-hidden="true" />
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="cast(item.value).name != cast(item.value).treeString" class="text-xs mt-1">
|
||||
{{ cast(item.value).treeString }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</FormAutocomplete2>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { FlatTreeItem, useFlatLocations } from "~~/composables/use-location-helpers";
|
||||
import { LocationSummary } from "~~/lib/api/types/data-contracts";
|
||||
|
||||
type Props = {
|
||||
modelValue?: LocationSummary | null;
|
||||
};
|
||||
|
||||
// Cast the type of the item to a FlatTreeItem so we can get type "safety" in the template
|
||||
// Note that this does not actually change the type of the item, it just tells the compiler
|
||||
// that the type is FlatTreeItem. We must keep this in sync with the type of the items
|
||||
function cast(value: any): FlatTreeItem {
|
||||
return value as FlatTreeItem;
|
||||
}
|
||||
|
||||
const props = defineProps<Props>();
|
||||
const value = useVModel(props, "modelValue");
|
||||
|
||||
const locations = await useFlatLocations();
|
||||
const form = ref({
|
||||
parent: null as LocationSummary | null,
|
||||
search: "",
|
||||
});
|
||||
|
||||
// Whenever parent goes from value to null reset search
|
||||
watch(
|
||||
() => value.value,
|
||||
() => {
|
||||
if (!value.value) {
|
||||
form.value.search = "";
|
||||
}
|
||||
}
|
||||
);
|
||||
</script>
|
||||
73
frontend/components/Location/Tree/Node.vue
Normal file
73
frontend/components/Location/Tree/Node.vue
Normal file
@@ -0,0 +1,73 @@
|
||||
<script setup lang="ts">
|
||||
import { useTreeState } from "./tree-state";
|
||||
import { TreeItem } from "~~/lib/api/types/data-contracts";
|
||||
|
||||
type Props = {
|
||||
treeId: string;
|
||||
item: TreeItem;
|
||||
};
|
||||
const props = withDefaults(defineProps<Props>(), {});
|
||||
|
||||
const link = computed(() => {
|
||||
return props.item.type === "location" ? `/location/${props.item.id}` : `/item/${props.item.id}`;
|
||||
});
|
||||
|
||||
const hasChildren = computed(() => {
|
||||
return props.item.children.length > 0;
|
||||
});
|
||||
|
||||
const state = useTreeState(props.treeId);
|
||||
|
||||
const openRef = computed({
|
||||
get() {
|
||||
return state.value[nodeHash.value] ?? false;
|
||||
},
|
||||
set(value) {
|
||||
state.value[nodeHash.value] = value;
|
||||
},
|
||||
});
|
||||
|
||||
const nodeHash = computed(() => {
|
||||
// converts a UUID to a short hash
|
||||
return props.item.id.replace(/-/g, "").substring(0, 8);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div
|
||||
class="node flex items-center gap-1 rounded p-1"
|
||||
:class="{
|
||||
'cursor-pointer hover:bg-base-200': hasChildren,
|
||||
}"
|
||||
@click="openRef = !openRef"
|
||||
>
|
||||
<div
|
||||
class="p-1/2 rounded mr-1 flex items-center justify-center"
|
||||
:class="{
|
||||
'hover:bg-base-200': hasChildren,
|
||||
}"
|
||||
>
|
||||
<div v-if="!hasChildren" class="h-6 w-6"></div>
|
||||
<label
|
||||
v-else
|
||||
class="swap swap-rotate"
|
||||
:class="{
|
||||
'swap-active': openRef,
|
||||
}"
|
||||
>
|
||||
<Icon name="mdi-chevron-right" class="h-6 w-6 swap-off" />
|
||||
<Icon name="mdi-chevron-down" class="h-6 w-6 swap-on" />
|
||||
</label>
|
||||
</div>
|
||||
<Icon v-if="item.type === 'location'" name="mdi-map-marker" class="h-4 w-4" />
|
||||
<Icon v-else name="mdi-package-variant" class="h-4 w-4" />
|
||||
<NuxtLink class="hover:link text-lg" :to="link" @click.stop>{{ item.name }} </NuxtLink>
|
||||
</div>
|
||||
<div v-if="openRef" class="ml-4">
|
||||
<LocationTreeNode v-for="child in item.children" :key="child.id" :item="child" :tree-id="treeId" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
18
frontend/components/Location/Tree/Root.vue
Normal file
18
frontend/components/Location/Tree/Root.vue
Normal file
@@ -0,0 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
import { TreeItem } from "~~/lib/api/types/data-contracts";
|
||||
|
||||
type Props = {
|
||||
locs: TreeItem[];
|
||||
treeId: string;
|
||||
};
|
||||
|
||||
defineProps<Props>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="p-4 border-2 root">
|
||||
<LocationTreeNode v-for="item in locs" :key="item.id" :item="item" :tree-id="treeId" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style></style>
|
||||
17
frontend/components/Location/Tree/tree-state.ts
Normal file
17
frontend/components/Location/Tree/tree-state.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import type { Ref } from "vue";
|
||||
|
||||
type TreeState = Record<string, boolean>;
|
||||
|
||||
const store: Record<string, Ref<TreeState>> = {};
|
||||
|
||||
export function newTreeKey(): string {
|
||||
return Math.random().toString(36).substring(2);
|
||||
}
|
||||
|
||||
export function useTreeState(key: string): Ref<TreeState> {
|
||||
if (!store[key]) {
|
||||
store[key] = ref({});
|
||||
}
|
||||
|
||||
return store[key];
|
||||
}
|
||||
104
frontend/components/Search/Filter.vue
Normal file
104
frontend/components/Search/Filter.vue
Normal file
@@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<div ref="el" class="dropdown" :class="{ 'dropdown-open': dropdownOpen }">
|
||||
<button ref="btn" tabindex="0" class="btn btn-xs" @click="toggle">
|
||||
{{ label }} {{ len }} <Icon name="mdi-chevron-down" class="h-4 w-4" />
|
||||
</button>
|
||||
<div tabindex="0" class="dropdown-content mt-1 w-64 shadow bg-base-100 rounded-md">
|
||||
<div class="pt-4 px-4 shadow-sm mb-1">
|
||||
<input v-model="search" type="text" placeholder="Search…" class="input input-sm input-bordered w-full mb-2" />
|
||||
</div>
|
||||
<div class="overflow-y-auto max-h-72 divide-y">
|
||||
<label
|
||||
v-for="v in selectedView"
|
||||
:key="v"
|
||||
class="cursor-pointer px-4 label flex justify-between hover:bg-base-200"
|
||||
>
|
||||
<span class="label-text mr-2">
|
||||
<slot name="display" v-bind="{ item: v }">
|
||||
{{ v[display] }}
|
||||
</slot>
|
||||
</span>
|
||||
<input v-model="selected" type="checkbox" :value="v" class="checkbox checkbox-sm checkbox-primary" />
|
||||
</label>
|
||||
<hr v-if="selected.length > 0" />
|
||||
<label
|
||||
v-for="v in unselected"
|
||||
:key="v"
|
||||
class="cursor-pointer px-4 label flex justify-between hover:bg-base-200"
|
||||
>
|
||||
<span class="label-text mr-2">
|
||||
<slot name="display" v-bind="{ item: v }">
|
||||
{{ v[display] }}
|
||||
</slot>
|
||||
</span>
|
||||
<input v-model="selected" type="checkbox" :value="v" class="checkbox checkbox-sm checkbox-primary" />
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
type Props = {
|
||||
label: string;
|
||||
options: any[];
|
||||
display?: string;
|
||||
modelValue: any[];
|
||||
};
|
||||
|
||||
const btn = ref<HTMLButtonElement>();
|
||||
|
||||
const search = ref("");
|
||||
const searchFold = computed(() => search.value.toLowerCase());
|
||||
const dropdownOpen = ref(false);
|
||||
const el = ref();
|
||||
|
||||
function toggle() {
|
||||
dropdownOpen.value = !dropdownOpen.value;
|
||||
|
||||
if (!dropdownOpen.value) {
|
||||
btn.value?.blur();
|
||||
}
|
||||
}
|
||||
|
||||
onClickOutside(el, () => {
|
||||
dropdownOpen.value = false;
|
||||
});
|
||||
|
||||
watch(dropdownOpen, val => {
|
||||
console.log(val);
|
||||
});
|
||||
|
||||
const emit = defineEmits(["update:modelValue"]);
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
label: "",
|
||||
display: "name",
|
||||
modelValue: () => [],
|
||||
});
|
||||
|
||||
const len = computed(() => {
|
||||
return selected.value.length > 0 ? `(${selected.value.length})` : "";
|
||||
});
|
||||
|
||||
const selectedView = computed(() => {
|
||||
return selected.value.filter(o => {
|
||||
if (searchFold.value.length > 0) {
|
||||
return o[props.display].toLowerCase().includes(searchFold.value);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
});
|
||||
|
||||
const selected = useVModel(props, "modelValue", emit);
|
||||
|
||||
const unselected = computed(() => {
|
||||
return props.options.filter(o => {
|
||||
if (searchFold.value.length > 0) {
|
||||
return o[props.display].toLowerCase().includes(searchFold.value) && !selected.value.includes(o);
|
||||
}
|
||||
return !selected.value.includes(o);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
@@ -4,7 +4,7 @@ import { Requests } from "~~/lib/requests";
|
||||
import { useAuthStore } from "~~/stores/auth";
|
||||
|
||||
export type Observer = {
|
||||
handler: (r: Response) => void;
|
||||
handler: (r: Response, req?: RequestInit) => void;
|
||||
};
|
||||
|
||||
export type RemoveObserver = () => void;
|
||||
|
||||
@@ -2,7 +2,7 @@ export enum EventTypes {
|
||||
// ClearStores event is used to inform the stores that _all_ the data they are using
|
||||
// is now out of date and they should refresh - This is used when the user makes large
|
||||
// changes to the data such as bulk actions or importing a CSV file
|
||||
ClearStores,
|
||||
InvalidStores,
|
||||
}
|
||||
|
||||
export type EventFn = () => void;
|
||||
@@ -15,7 +15,7 @@ export interface IEventBus {
|
||||
|
||||
class EventBus implements IEventBus {
|
||||
private listeners: Record<EventTypes, Record<string, EventFn>> = {
|
||||
[EventTypes.ClearStores]: {},
|
||||
[EventTypes.InvalidStores]: {},
|
||||
};
|
||||
|
||||
on(event: EventTypes, fn: EventFn, key: string): void {
|
||||
|
||||
@@ -63,11 +63,11 @@ export function fmtDate(value: string | Date, fmt: DateTimeFormat = "human"): st
|
||||
|
||||
switch (fmt) {
|
||||
case "relative":
|
||||
return useTimeAgo(dt).value + useDateFormat(dt, " (MM-DD-YYYY)").value;
|
||||
return useTimeAgo(dt).value + useDateFormat(dt, " (YYYY-MM-DD)").value;
|
||||
case "long":
|
||||
return useDateFormat(dt, "MM-DD-YYYY (dddd)").value;
|
||||
return useDateFormat(dt, "YYYY-MM-DD (dddd)").value;
|
||||
case "short":
|
||||
return useDateFormat(dt, "MM-DD-YYYY").value;
|
||||
return useDateFormat(dt, "YYYY-MM-DD").value;
|
||||
case "human":
|
||||
// January 1st, 2021
|
||||
return `${months[dt.getMonth()]} ${dt.getDate()}${ordinalIndicator(dt.getDate())}, ${dt.getFullYear()}`;
|
||||
|
||||
44
frontend/composables/use-location-helpers.ts
Normal file
44
frontend/composables/use-location-helpers.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { Ref } from "vue";
|
||||
import { TreeItem } from "~~/lib/api/types/data-contracts";
|
||||
|
||||
export interface FlatTreeItem {
|
||||
id: string;
|
||||
name: string;
|
||||
treeString: string;
|
||||
}
|
||||
|
||||
export function flatTree(tree: TreeItem[]): Ref<FlatTreeItem[]> {
|
||||
const v = ref<FlatTreeItem[]>([]);
|
||||
|
||||
// turns the nested items into a flat items array where
|
||||
// the display is a string of the tree hierarchy separated by breadcrumbs
|
||||
|
||||
function flatten(items: TreeItem[], display: string) {
|
||||
for (const item of items) {
|
||||
v.value.push({
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
treeString: display + item.name,
|
||||
});
|
||||
if (item.children) {
|
||||
flatten(item.children, display + item.name + " > ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flatten(tree, "");
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
export async function useFlatLocations(): Promise<Ref<FlatTreeItem[]>> {
|
||||
const api = useUserApi();
|
||||
|
||||
const locations = await api.locations.getTree();
|
||||
|
||||
if (!locations) {
|
||||
return ref([]);
|
||||
}
|
||||
|
||||
return flatTree(locations.data.items);
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
import { Ref } from "vue";
|
||||
import { DaisyTheme } from "~~/lib/data/themes";
|
||||
|
||||
export type ViewType = "table" | "card" | "tree";
|
||||
|
||||
export type LocationViewPreferences = {
|
||||
showDetails: boolean;
|
||||
showEmpty: boolean;
|
||||
editorAdvancedView: boolean;
|
||||
itemDisplayView: ViewType;
|
||||
theme: DaisyTheme;
|
||||
};
|
||||
|
||||
@@ -19,6 +22,7 @@ export function useViewPreferences(): Ref<LocationViewPreferences> {
|
||||
showDetails: true,
|
||||
showEmpty: true,
|
||||
editorAdvancedView: false,
|
||||
itemDisplayView: "card",
|
||||
theme: "homebox",
|
||||
},
|
||||
{ mergeDefaults: true }
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
up the tree
|
||||
-->
|
||||
<ModalConfirm />
|
||||
<AppImportDialog v-model="modals.import" />
|
||||
<ItemCreateModal v-model="modals.item" />
|
||||
<LabelCreateModal v-model="modals.label" />
|
||||
<LocationCreateModal v-model="modals.location" />
|
||||
@@ -78,10 +77,6 @@
|
||||
<Icon :name="n.icon" class="h-6 w-6 mr-4" />
|
||||
{{ n.name }}
|
||||
</NuxtLink>
|
||||
<button v-else class="rounded-btn" @click="n.action">
|
||||
<Icon :name="n.icon" class="h-6 w-6 mr-4" />
|
||||
{{ n.name }}
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -158,35 +153,40 @@
|
||||
to: "/profile",
|
||||
},
|
||||
{
|
||||
icon: "mdi-document",
|
||||
icon: "mdi-magnify",
|
||||
id: 3,
|
||||
active: computed(() => route.path === "/items"),
|
||||
name: "Items",
|
||||
name: "Search",
|
||||
to: "/items",
|
||||
},
|
||||
{
|
||||
icon: "mdi-database",
|
||||
id: 2,
|
||||
name: "Import",
|
||||
action: () => {
|
||||
modals.import = true;
|
||||
},
|
||||
icon: "mdi-map-marker",
|
||||
id: 4,
|
||||
active: computed(() => route.path === "/locations"),
|
||||
name: "Locations",
|
||||
to: "/locations",
|
||||
},
|
||||
{
|
||||
icon: "mdi-cog",
|
||||
id: 6,
|
||||
active: computed(() => route.path === "/tools"),
|
||||
name: "Tools",
|
||||
to: "/tools",
|
||||
},
|
||||
// {
|
||||
// icon: "mdi-database-export",
|
||||
// id: 5,
|
||||
// name: "Export",
|
||||
// action: () => {
|
||||
// console.log("Export");
|
||||
// },
|
||||
// },
|
||||
];
|
||||
|
||||
function isMutation(method: string | undefined) {
|
||||
return method === "POST" || method === "PUT" || method === "DELETE";
|
||||
}
|
||||
function isSuccess(status: number) {
|
||||
return status >= 200 && status < 300;
|
||||
}
|
||||
|
||||
const labelStore = useLabelStore();
|
||||
const reLabel = /\/api\/v1\/labels\/.*/gm;
|
||||
const rmLabelStoreObserver = defineObserver("labelStore", {
|
||||
handler: r => {
|
||||
if (r.status === 201 || r.url.match(reLabel)) {
|
||||
handler: (resp, req) => {
|
||||
if (isMutation(req?.method) && isSuccess(resp.status) && resp.url.match(reLabel)) {
|
||||
labelStore.refresh();
|
||||
}
|
||||
console.debug("labelStore handler called by observer");
|
||||
@@ -196,18 +196,19 @@
|
||||
const locationStore = useLocationStore();
|
||||
const reLocation = /\/api\/v1\/locations\/.*/gm;
|
||||
const rmLocationStoreObserver = defineObserver("locationStore", {
|
||||
handler: r => {
|
||||
if (r.status === 201 || r.url.match(reLocation)) {
|
||||
handler: (resp, req) => {
|
||||
if (isMutation(req?.method) && isSuccess(resp.status) && resp.url.match(reLocation)) {
|
||||
locationStore.refreshChildren();
|
||||
locationStore.refreshParents();
|
||||
}
|
||||
|
||||
console.debug("locationStore handler called by observer");
|
||||
},
|
||||
});
|
||||
|
||||
const eventBus = useEventBus();
|
||||
eventBus.on(
|
||||
EventTypes.ClearStores,
|
||||
EventTypes.InvalidStores,
|
||||
() => {
|
||||
labelStore.refresh();
|
||||
locationStore.refreshChildren();
|
||||
@@ -219,7 +220,7 @@
|
||||
onUnmounted(() => {
|
||||
rmLabelStoreObserver();
|
||||
rmLocationStoreObserver();
|
||||
eventBus.off(EventTypes.ClearStores, "stores");
|
||||
eventBus.off(EventTypes.InvalidStores, "stores");
|
||||
});
|
||||
|
||||
const authStore = useAuthStore();
|
||||
|
||||
@@ -5,7 +5,7 @@ const ZERO_DATE = "0001-01-01T00:00:00Z";
|
||||
type BaseApiType = {
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
[key: string]: any;
|
||||
};
|
||||
|
||||
@@ -26,9 +26,11 @@ export function parseDate<T>(obj: T, keys: Array<keyof T> = []): T {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure date like format YYYY/MM/DD - otherwise results will be 1 day off
|
||||
const dateStr: string = result[key].split("T")[0].replace(/-/g, "/");
|
||||
result[key] = new Date(dateStr);
|
||||
// transform string to ensure dates are parsed as UTC dates instead of
|
||||
// localized time stamps
|
||||
const asStr = result[key] as string;
|
||||
const cleaned = asStr.replaceAll("-", "/").split("T")[0];
|
||||
result[key] = new Date(cleaned);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import { BaseAPI, route } from "../base";
|
||||
import { EnsureAssetIDResult } from "../types/data-contracts";
|
||||
import { ActionAmountResult } from "../types/data-contracts";
|
||||
|
||||
export class ActionsAPI extends BaseAPI {
|
||||
ensureAssetIDs() {
|
||||
return this.http.post<void, EnsureAssetIDResult>({
|
||||
return this.http.post<void, ActionAmountResult>({
|
||||
url: route("/actions/ensure-asset-ids"),
|
||||
});
|
||||
}
|
||||
|
||||
resetItemDateTimes() {
|
||||
return this.http.post<void, ActionAmountResult>({
|
||||
url: route("/actions/zero-item-time-fields"),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ export type ItemsQuery = {
|
||||
locations?: string[];
|
||||
labels?: string[];
|
||||
q?: string;
|
||||
fields?: string[];
|
||||
};
|
||||
|
||||
export class AttachmentsAPI extends BaseAPI {
|
||||
@@ -48,6 +49,16 @@ export class AttachmentsAPI extends BaseAPI {
|
||||
}
|
||||
}
|
||||
|
||||
export class FieldsAPI extends BaseAPI {
|
||||
getAll() {
|
||||
return this.http.get<string[]>({ url: route("/items/fields") });
|
||||
}
|
||||
|
||||
getAllValues(field: string) {
|
||||
return this.http.get<string[]>({ url: route(`/items/fields/values`, { field }) });
|
||||
}
|
||||
}
|
||||
|
||||
export class MaintenanceAPI extends BaseAPI {
|
||||
getLog(itemId: string) {
|
||||
return this.http.get<MaintenanceLog>({ url: route(`/items/${itemId}/maintenance`) });
|
||||
@@ -75,9 +86,11 @@ export class MaintenanceAPI extends BaseAPI {
|
||||
export class ItemsApi extends BaseAPI {
|
||||
attachments: AttachmentsAPI;
|
||||
maintenance: MaintenanceAPI;
|
||||
fields: FieldsAPI;
|
||||
|
||||
constructor(http: Requests, token: string) {
|
||||
super(http, token);
|
||||
this.fields = new FieldsAPI(http);
|
||||
this.attachments = new AttachmentsAPI(http);
|
||||
this.maintenance = new MaintenanceAPI(http);
|
||||
}
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
import { BaseAPI, route } from "../base";
|
||||
import { LocationOutCount, LocationCreate, LocationOut, LocationUpdate } from "../types/data-contracts";
|
||||
import { LocationOutCount, LocationCreate, LocationOut, LocationUpdate, TreeItem } from "../types/data-contracts";
|
||||
import { Results } from "../types/non-generated";
|
||||
|
||||
export type LocationsQuery = {
|
||||
filterChildren: boolean;
|
||||
};
|
||||
|
||||
export type TreeQuery = {
|
||||
withItems: boolean;
|
||||
};
|
||||
|
||||
export class LocationsApi extends BaseAPI {
|
||||
getAll(q: LocationsQuery = { filterChildren: false }) {
|
||||
return this.http.get<Results<LocationOutCount>>({ url: route("/locations", q) });
|
||||
}
|
||||
|
||||
getTree(tq = { withItems: false }) {
|
||||
return this.http.get<Results<TreeItem>>({ url: route("/locations/tree", tq) });
|
||||
}
|
||||
|
||||
create(body: LocationCreate) {
|
||||
return this.http.post<LocationCreate, LocationOut>({ url: route("/locations"), body });
|
||||
}
|
||||
|
||||
27
frontend/lib/api/classes/reports.ts
Normal file
27
frontend/lib/api/classes/reports.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { BaseAPI, route } from "../base";
|
||||
|
||||
export class ReportsAPI extends BaseAPI {
|
||||
async billOfMaterials(): Promise<void> {
|
||||
const { data: stream, error } = await this.http.get<ReadableStream>({ url: route("/reporting/bill-of-materials") });
|
||||
|
||||
if (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
const reader = stream.getReader();
|
||||
let data = "";
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
data += new TextDecoder("utf-8").decode(value);
|
||||
}
|
||||
|
||||
const blob = new Blob([data], { type: "text/tsv" });
|
||||
const link = document.createElement("a");
|
||||
link.href = window.URL.createObjectURL(blob);
|
||||
link.download = "bill-of-materials.tsv";
|
||||
link.click();
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { BaseAPI, route } from "../base";
|
||||
import { GroupStatistics, TotalsByOrganizer, ValueOverTime } from "../types/data-contracts";
|
||||
|
||||
function YYYY_DD_MM(date?: Date): string {
|
||||
function YYYY_MM_DD(date?: Date): string {
|
||||
if (!date) {
|
||||
return "";
|
||||
}
|
||||
@@ -14,7 +14,7 @@ function YYYY_DD_MM(date?: Date): string {
|
||||
export class StatsAPI extends BaseAPI {
|
||||
totalPriceOverTime(start?: Date, end?: Date) {
|
||||
return this.http.get<ValueOverTime>({
|
||||
url: route("/groups/statistics/purchase-price", { start: YYYY_DD_MM(start), end: YYYY_DD_MM(end) }),
|
||||
url: route("/groups/statistics/purchase-price", { start: YYYY_MM_DD(start), end: YYYY_MM_DD(end) }),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -17,11 +17,11 @@ export interface DocumentOut {
|
||||
}
|
||||
|
||||
export interface Group {
|
||||
createdAt: Date;
|
||||
createdAt: Date | string;
|
||||
currency: string;
|
||||
id: string;
|
||||
name: string;
|
||||
updatedAt: Date;
|
||||
updatedAt: Date | string;
|
||||
}
|
||||
|
||||
export interface GroupStatistics {
|
||||
@@ -39,11 +39,11 @@ export interface GroupUpdate {
|
||||
}
|
||||
|
||||
export interface ItemAttachment {
|
||||
createdAt: Date;
|
||||
createdAt: Date | string;
|
||||
document: DocumentOut;
|
||||
id: string;
|
||||
type: string;
|
||||
updatedAt: Date;
|
||||
updatedAt: Date | string;
|
||||
}
|
||||
|
||||
export interface ItemAttachmentUpdate {
|
||||
@@ -76,7 +76,7 @@ export interface ItemOut {
|
||||
assetId: string;
|
||||
attachments: ItemAttachment[];
|
||||
children: ItemSummary[];
|
||||
createdAt: Date;
|
||||
createdAt: Date | string;
|
||||
description: string;
|
||||
fields: ItemField[];
|
||||
id: string;
|
||||
@@ -96,23 +96,23 @@ export interface ItemOut {
|
||||
/** @example "0" */
|
||||
purchasePrice: string;
|
||||
/** Purchase */
|
||||
purchaseTime: Date;
|
||||
purchaseTime: Date | string;
|
||||
quantity: number;
|
||||
serialNumber: string;
|
||||
soldNotes: string;
|
||||
/** @example "0" */
|
||||
soldPrice: string;
|
||||
/** Sold */
|
||||
soldTime: Date;
|
||||
soldTime: Date | string;
|
||||
soldTo: string;
|
||||
updatedAt: Date;
|
||||
updatedAt: Date | string;
|
||||
warrantyDetails: string;
|
||||
warrantyExpires: Date;
|
||||
warrantyExpires: Date | string;
|
||||
}
|
||||
|
||||
export interface ItemSummary {
|
||||
archived: boolean;
|
||||
createdAt: Date;
|
||||
createdAt: Date | string;
|
||||
description: string;
|
||||
id: string;
|
||||
insured: boolean;
|
||||
@@ -123,7 +123,7 @@ export interface ItemSummary {
|
||||
/** @example "0" */
|
||||
purchasePrice: string;
|
||||
quantity: number;
|
||||
updatedAt: Date;
|
||||
updatedAt: Date | string;
|
||||
}
|
||||
|
||||
export interface ItemUpdate {
|
||||
@@ -148,7 +148,7 @@ export interface ItemUpdate {
|
||||
/** @example "0" */
|
||||
purchasePrice: string;
|
||||
/** Purchase */
|
||||
purchaseTime: Date;
|
||||
purchaseTime: Date | string;
|
||||
quantity: number;
|
||||
/** Identifications */
|
||||
serialNumber: string;
|
||||
@@ -156,10 +156,10 @@ export interface ItemUpdate {
|
||||
/** @example "0" */
|
||||
soldPrice: string;
|
||||
/** Sold */
|
||||
soldTime: Date;
|
||||
soldTime: Date | string;
|
||||
soldTo: string;
|
||||
warrantyDetails: string;
|
||||
warrantyExpires: Date;
|
||||
warrantyExpires: Date | string;
|
||||
}
|
||||
|
||||
export interface LabelCreate {
|
||||
@@ -169,53 +169,54 @@ export interface LabelCreate {
|
||||
}
|
||||
|
||||
export interface LabelOut {
|
||||
createdAt: Date;
|
||||
createdAt: Date | string;
|
||||
description: string;
|
||||
id: string;
|
||||
items: ItemSummary[];
|
||||
name: string;
|
||||
updatedAt: Date;
|
||||
updatedAt: Date | string;
|
||||
}
|
||||
|
||||
export interface LabelSummary {
|
||||
createdAt: Date;
|
||||
createdAt: Date | string;
|
||||
description: string;
|
||||
id: string;
|
||||
name: string;
|
||||
updatedAt: Date;
|
||||
updatedAt: Date | string;
|
||||
}
|
||||
|
||||
export interface LocationCreate {
|
||||
description: string;
|
||||
name: string;
|
||||
parentId: string | null;
|
||||
}
|
||||
|
||||
export interface LocationOut {
|
||||
children: LocationSummary[];
|
||||
createdAt: Date;
|
||||
createdAt: Date | string;
|
||||
description: string;
|
||||
id: string;
|
||||
items: ItemSummary[];
|
||||
name: string;
|
||||
parent: LocationSummary;
|
||||
updatedAt: Date;
|
||||
updatedAt: Date | string;
|
||||
}
|
||||
|
||||
export interface LocationOutCount {
|
||||
createdAt: Date;
|
||||
createdAt: Date | string;
|
||||
description: string;
|
||||
id: string;
|
||||
itemCount: number;
|
||||
name: string;
|
||||
updatedAt: Date;
|
||||
updatedAt: Date | string;
|
||||
}
|
||||
|
||||
export interface LocationSummary {
|
||||
createdAt: Date;
|
||||
createdAt: Date | string;
|
||||
description: string;
|
||||
id: string;
|
||||
name: string;
|
||||
updatedAt: Date;
|
||||
updatedAt: Date | string;
|
||||
}
|
||||
|
||||
export interface LocationUpdate {
|
||||
@@ -228,7 +229,7 @@ export interface LocationUpdate {
|
||||
export interface MaintenanceEntry {
|
||||
/** @example "0" */
|
||||
cost: string;
|
||||
date: Date;
|
||||
date: Date | string;
|
||||
description: string;
|
||||
id: string;
|
||||
name: string;
|
||||
@@ -237,7 +238,7 @@ export interface MaintenanceEntry {
|
||||
export interface MaintenanceEntryCreate {
|
||||
/** @example "0" */
|
||||
cost: string;
|
||||
date: Date;
|
||||
date: Date | string;
|
||||
description: string;
|
||||
name: string;
|
||||
}
|
||||
@@ -245,7 +246,7 @@ export interface MaintenanceEntryCreate {
|
||||
export interface MaintenanceEntryUpdate {
|
||||
/** @example "0" */
|
||||
cost: string;
|
||||
date: Date;
|
||||
date: Date | string;
|
||||
description: string;
|
||||
name: string;
|
||||
}
|
||||
@@ -257,7 +258,7 @@ export interface MaintenanceLog {
|
||||
itemId: string;
|
||||
}
|
||||
|
||||
export interface PaginationResultRepoItemSummary {
|
||||
export interface PaginationResultItemSummary {
|
||||
items: ItemSummary[];
|
||||
page: number;
|
||||
pageSize: number;
|
||||
@@ -270,6 +271,13 @@ export interface TotalsByOrganizer {
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface TreeItem {
|
||||
children: TreeItem[];
|
||||
id: string;
|
||||
name: string;
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface UserOut {
|
||||
email: string;
|
||||
groupId: string;
|
||||
@@ -294,7 +302,7 @@ export interface ValueOverTime {
|
||||
}
|
||||
|
||||
export interface ValueOverTimeEntry {
|
||||
date: Date;
|
||||
date: Date | string;
|
||||
name: string;
|
||||
value: number;
|
||||
}
|
||||
@@ -322,6 +330,10 @@ export interface UserRegistration {
|
||||
token: string;
|
||||
}
|
||||
|
||||
export interface ActionAmountResult {
|
||||
completed: number;
|
||||
}
|
||||
|
||||
export interface ApiSummary {
|
||||
build: Build;
|
||||
demo: boolean;
|
||||
@@ -342,18 +354,14 @@ export interface ChangePassword {
|
||||
new: string;
|
||||
}
|
||||
|
||||
export interface EnsureAssetIDResult {
|
||||
completed: number;
|
||||
}
|
||||
|
||||
export interface GroupInvitation {
|
||||
expiresAt: string;
|
||||
expiresAt: Date | string;
|
||||
token: string;
|
||||
uses: number;
|
||||
}
|
||||
|
||||
export interface GroupInvitationCreate {
|
||||
expiresAt: string;
|
||||
expiresAt: Date | string;
|
||||
uses: number;
|
||||
}
|
||||
|
||||
@@ -363,6 +371,6 @@ export interface ItemAttachmentToken {
|
||||
|
||||
export interface TokenResponse {
|
||||
attachmentToken: string;
|
||||
expiresAt: string;
|
||||
expiresAt: Date | string;
|
||||
token: string;
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { UserApi } from "./classes/users";
|
||||
import { ActionsAPI } from "./classes/actions";
|
||||
import { StatsAPI } from "./classes/stats";
|
||||
import { AssetsApi } from "./classes/assets";
|
||||
import { ReportsAPI } from "./classes/reports";
|
||||
import { Requests } from "~~/lib/requests";
|
||||
|
||||
export class UserClient extends BaseAPI {
|
||||
@@ -18,6 +19,7 @@ export class UserClient extends BaseAPI {
|
||||
actions: ActionsAPI;
|
||||
stats: StatsAPI;
|
||||
assets: AssetsApi;
|
||||
reports: ReportsAPI;
|
||||
|
||||
constructor(requests: Requests, attachmentToken: string) {
|
||||
super(requests, attachmentToken);
|
||||
@@ -30,6 +32,7 @@ export class UserClient extends BaseAPI {
|
||||
this.actions = new ActionsAPI(requests);
|
||||
this.stats = new StatsAPI(requests);
|
||||
this.assets = new AssetsApi(requests);
|
||||
this.reports = new ReportsAPI(requests);
|
||||
|
||||
Object.freeze(this);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user