mirror of
https://github.com/sysadminsmedia/homebox.git
synced 2025-12-27 15:41:42 +01:00
Compare commits
118 Commits
v0.5.1
...
feat/new-n
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3cfd274212 | ||
|
|
e71146df3d | ||
|
|
8c72d66d87 | ||
|
|
b6c2db0e83 | ||
|
|
883468e04c | ||
|
|
ccd40ffcac | ||
|
|
9c6421a9ff | ||
|
|
c18d72b8a9 | ||
|
|
737007b156 | ||
|
|
9fa4da819f | ||
|
|
77fb37ebf4 | ||
|
|
7167d200ea | ||
|
|
e1f9c2997b | ||
|
|
c2f432cb4d | ||
|
|
b6f44dfe58 | ||
|
|
30b1879c35 | ||
|
|
913912a1d9 | ||
|
|
fa069845fa | ||
|
|
882f86f6f4 | ||
|
|
d79d0b45bf | ||
|
|
b0a9c510ad | ||
|
|
b82fbb01f5 | ||
|
|
4d744c0e4b | ||
|
|
9f59a5d393 | ||
|
|
37857682e6 | ||
|
|
43b34e2899 | ||
|
|
65d0b8fe4f | ||
|
|
791d6979b6 | ||
|
|
b491ff9ec1 | ||
|
|
f169f1c710 | ||
|
|
4725d9c823 | ||
|
|
14315cb88a | ||
|
|
cf536393f5 | ||
|
|
025521431e | ||
|
|
70297b9d27 | ||
|
|
729293745f | ||
|
|
a6bcb36c5b | ||
|
|
a005fa5b9b | ||
|
|
a2dfa9dcef | ||
|
|
32216f63bd | ||
|
|
ef190e26df | ||
|
|
c3e3702a7e | ||
|
|
fb57120067 | ||
|
|
9d9b05d8a6 | ||
|
|
3ac6c7c858 | ||
|
|
859d3b9ffe | ||
|
|
6cfa6c9fc8 | ||
|
|
12975ce26e | ||
|
|
bd321af29f | ||
|
|
88f9ff90d4 | ||
|
|
354f1adbee | ||
|
|
2a62a43493 | ||
|
|
673db41f37 | ||
|
|
830ce2b0a9 | ||
|
|
e8e6a425dd | ||
|
|
da00db0608 | ||
|
|
efd7069fe4 | ||
|
|
dd349aa98e | ||
|
|
607b06d2f2 | ||
|
|
44f13f751a | ||
|
|
986d2c586e | ||
|
|
9361997a42 | ||
|
|
2e96d8c4c2 | ||
|
|
ff75daf6b3 | ||
|
|
c0953bbd26 | ||
|
|
1f7e917c70 | ||
|
|
6ff2d64996 | ||
|
|
ab22ea6a25 | ||
|
|
ce2fc7712a | ||
|
|
bd933af874 | ||
|
|
f36f17b57d | ||
|
|
504569bed0 | ||
|
|
bd06fdafaf | ||
|
|
7b28973c60 | ||
|
|
cbac17c059 | ||
|
|
6ed1f3695a | ||
|
|
3d295b5132 | ||
|
|
4d220cdd9c | ||
|
|
ad20e4e39b | ||
|
|
3e2f6a96bf | ||
|
|
2ece97c42a | ||
|
|
a8ee4d421b | ||
|
|
91d0c588d9 | ||
|
|
c19fe94c08 | ||
|
|
f532b39c46 | ||
|
|
243742a75c | ||
|
|
2b7c1fa429 | ||
|
|
125b8f5ecd | ||
|
|
580de45cec | ||
|
|
da52b4ec64 | ||
|
|
5b0dba854d | ||
|
|
984c1a08ac | ||
|
|
8419a17109 | ||
|
|
f3406eec19 | ||
|
|
3ed07a909f | ||
|
|
07441eec8e | ||
|
|
c78f10ba5d | ||
|
|
490a0ece86 | ||
|
|
891d41b75f | ||
|
|
58d6f9a28c | ||
|
|
6a8a25e3f8 | ||
|
|
a3954dab0f | ||
|
|
08d483d907 | ||
|
|
a53f89ceac | ||
|
|
5bbb969763 | ||
|
|
d6da63187b | ||
|
|
de419dc37d | ||
|
|
974d6914a2 | ||
|
|
d2aa022347 | ||
|
|
6af048dc93 | ||
|
|
73c42f4784 | ||
|
|
f42a917390 | ||
|
|
f149c3e4ab | ||
|
|
1dc1ee54e2 | ||
|
|
e8f215ce34 | ||
|
|
1aafbcd201 | ||
|
|
6dc2ae1bea | ||
|
|
976f68252d |
31
.github/dependabot.yml
vendored
31
.github/dependabot.yml
vendored
@@ -1,31 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
# Fetch and update latest `npm` packages
|
||||
- package-ecosystem: npm
|
||||
directory: "/frontend"
|
||||
schedule:
|
||||
interval: daily
|
||||
time: "00:00"
|
||||
open-pull-requests-limit: 10
|
||||
reviewers:
|
||||
- hay-kot
|
||||
assignees:
|
||||
- hay-kot
|
||||
commit-message:
|
||||
prefix: fix
|
||||
prefix-development: chore
|
||||
include: scope
|
||||
- package-ecosystem: gomod
|
||||
directory: backend
|
||||
schedule:
|
||||
interval: daily
|
||||
time: "00:00"
|
||||
open-pull-requests-limit: 10
|
||||
reviewers:
|
||||
- hay-kot
|
||||
assignees:
|
||||
- hay-kot
|
||||
commit-message:
|
||||
prefix: fix
|
||||
prefix-development: chore
|
||||
include: scope
|
||||
4
.github/workflows/partial-backend.yaml
vendored
4
.github/workflows/partial-backend.yaml
vendored
@@ -7,10 +7,10 @@ jobs:
|
||||
Go:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19
|
||||
|
||||
|
||||
38
.github/workflows/partial-frontend.yaml
vendored
38
.github/workflows/partial-frontend.yaml
vendored
@@ -4,11 +4,37 @@ on:
|
||||
workflow_call:
|
||||
|
||||
jobs:
|
||||
Frontend:
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- uses: pnpm/action-setup@v2.2.4
|
||||
with:
|
||||
version: 6.0.2
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --shamefully-hoist
|
||||
working-directory: frontend
|
||||
|
||||
- name: Run Lint
|
||||
run: pnpm run lint:ci
|
||||
working-directory: frontend
|
||||
|
||||
- name: Run Typecheck
|
||||
run: pnpm run typecheck
|
||||
working-directory: frontend
|
||||
|
||||
integration-tests:
|
||||
name: Integration Tests
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -18,7 +44,7 @@ jobs:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19
|
||||
|
||||
@@ -26,7 +52,7 @@ jobs:
|
||||
with:
|
||||
node-version: 18
|
||||
|
||||
- uses: pnpm/action-setup@v2.2.2
|
||||
- uses: pnpm/action-setup@v2.2.4
|
||||
with:
|
||||
version: 6.0.2
|
||||
|
||||
@@ -34,9 +60,5 @@ jobs:
|
||||
run: pnpm install
|
||||
working-directory: frontend
|
||||
|
||||
- name: Run linter 👀
|
||||
run: pnpm lint
|
||||
working-directory: "frontend"
|
||||
|
||||
- name: Run Integration Tests
|
||||
run: task test:ci
|
||||
|
||||
8
.github/workflows/partial-publish.yaml
vendored
8
.github/workflows/partial-publish.yaml
vendored
@@ -20,22 +20,22 @@ jobs:
|
||||
name: "Publish Homebox"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.19
|
||||
|
||||
- name: Set up QEMU
|
||||
id: qemu
|
||||
uses: docker/setup-qemu-action@v1
|
||||
uses: docker/setup-qemu-action@v2
|
||||
with:
|
||||
image: tonistiigi/binfmt:latest
|
||||
platforms: all
|
||||
|
||||
- name: install buildx
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
uses: docker/setup-buildx-action@v2
|
||||
with:
|
||||
install: true
|
||||
|
||||
|
||||
4
.github/workflows/publish.yaml
vendored
4
.github/workflows/publish.yaml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
- backend-tests
|
||||
- frontend-tests
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- uses: superfly/flyctl-actions/setup-flyctl@master
|
||||
- run: flyctl deploy --remote-only
|
||||
|
||||
@@ -63,7 +63,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout main
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Deploy docs
|
||||
uses: mhausenblas/mkdocs-deploy-gh-pages@master
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -45,3 +45,7 @@ node_modules
|
||||
.output
|
||||
.env
|
||||
dist
|
||||
|
||||
.pnpm-store
|
||||
backend/app/api/app
|
||||
backend/app/api/__debug_bin
|
||||
33
.scaffold/model/scaffold.yaml
Normal file
33
.scaffold/model/scaffold.yaml
Normal file
@@ -0,0 +1,33 @@
|
||||
---
|
||||
# yaml-language-server: $schema=https://hay-kot.github.io/scaffold/schema.json
|
||||
messages:
|
||||
pre: |
|
||||
# Ent Model Generation
|
||||
|
||||
With Boilerplate!
|
||||
post: |
|
||||
Complete!
|
||||
|
||||
questions:
|
||||
- name: "model"
|
||||
prompt:
|
||||
message: "What is the name of the model? (PascalCase)"
|
||||
required: true
|
||||
|
||||
- name: "by_group"
|
||||
prompt:
|
||||
confirm: "Include a Group Edge? (group_id -> id)"
|
||||
required: true
|
||||
|
||||
rewrites:
|
||||
- from: 'templates/model.go'
|
||||
to: 'backend/internal/data/ent/schema/{{ lower .Scaffold.model }}.go'
|
||||
|
||||
inject:
|
||||
- name: "Insert Groups Edge"
|
||||
path: 'backend/internal/data/ent/schema/group.go'
|
||||
at: // $scaffold_edge
|
||||
template: |
|
||||
{{- if .Scaffold.by_group -}}
|
||||
owned("{{ lower .Scaffold.model }}s", {{ .Scaffold.model }}.Type),
|
||||
{{- end -}}
|
||||
40
.scaffold/model/templates/model.go
Normal file
40
.scaffold/model/templates/model.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"entgo.io/ent"
|
||||
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/schema/mixins"
|
||||
)
|
||||
|
||||
type {{ .Scaffold.model }} struct {
|
||||
ent.Schema
|
||||
}
|
||||
|
||||
func ({{ .Scaffold.model }}) Mixin() []ent.Mixin {
|
||||
return []ent.Mixin{
|
||||
mixins.BaseMixin{},
|
||||
{{- if .Scaffold.by_group }}
|
||||
GroupMixin{ref: "{{ snakecase .Scaffold.model }}s"},
|
||||
{{- end }}
|
||||
}
|
||||
}
|
||||
|
||||
// Fields of the {{ .Scaffold.model }}.
|
||||
func ({{ .Scaffold.model }}) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
// field.String("name").
|
||||
}
|
||||
}
|
||||
|
||||
// Edges of the {{ .Scaffold.model }}.
|
||||
func ({{ .Scaffold.model }}) Edges() []ent.Edge {
|
||||
return []ent.Edge{
|
||||
// edge.From("group", Group.Type).
|
||||
}
|
||||
}
|
||||
|
||||
func ({{ .Scaffold.model }}) Indexes() []ent.Index {
|
||||
return []ent.Index{
|
||||
// index.Fields("token"),
|
||||
}
|
||||
}
|
||||
47
.vscode/launch.json
vendored
Normal file
47
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"compounds": [
|
||||
{
|
||||
"name": "Full Stack",
|
||||
"configurations": ["Launch Backend", "Launch Frontend"],
|
||||
"stopAll": true
|
||||
}
|
||||
],
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Launch Backend",
|
||||
"type": "go",
|
||||
"request": "launch",
|
||||
"mode": "debug",
|
||||
"program": "${workspaceRoot}/backend/app/api/",
|
||||
"args": [],
|
||||
"env": {
|
||||
"HBOX_DEMO": "true",
|
||||
"HBOX_LOG_LEVEL": "debug",
|
||||
"HBOX_DEBUG_ENABLED": "true",
|
||||
"HBOX_STORAGE_DATA": "${workspaceRoot}/backend/.data",
|
||||
"HBOX_STORAGE_SQLITE_URL": "${workspaceRoot}/backend/.data/homebox.db?_fk=1"
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "Launch Frontend",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "pnpm",
|
||||
"runtimeArgs": [
|
||||
"run",
|
||||
"dev"
|
||||
],
|
||||
"cwd": "${workspaceFolder}/frontend",
|
||||
"serverReadyAction": {
|
||||
"action": "debugWithChrome",
|
||||
"pattern": "Local: http://localhost:([0-9]+)",
|
||||
"uriFormat": "http://localhost:%s",
|
||||
"webRoot": "${workspaceFolder}/frontend"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
27
.vscode/settings.json
vendored
27
.vscode/settings.json
vendored
@@ -1,7 +1,4 @@
|
||||
{
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
},
|
||||
"yaml.schemas": {
|
||||
"https://squidfunk.github.io/mkdocs-material/schema.json": "mkdocs.yml"
|
||||
},
|
||||
@@ -12,6 +9,26 @@
|
||||
"README.md": "LICENSE, SECURITY.md"
|
||||
},
|
||||
"cSpell.words": [
|
||||
"debughandlers"
|
||||
]
|
||||
"debughandlers",
|
||||
"Homebox"
|
||||
],
|
||||
// use ESLint to format code on save
|
||||
"editor.formatOnSave": false,
|
||||
"editor.defaultFormatter": "dbaeumer.vscode-eslint",
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": true
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
|
||||
},
|
||||
"eslint.format.enable": true,
|
||||
"css.validate": false,
|
||||
"tailwindCSS.includeLanguages": {
|
||||
"vue": "html",
|
||||
"vue-html": "html"
|
||||
},
|
||||
"editor.quickSuggestions": {
|
||||
"strings": true
|
||||
},
|
||||
"tailwindCSS.experimental.configFile": "./frontend/tailwind.config.js"
|
||||
}
|
||||
|
||||
@@ -41,9 +41,10 @@ COPY --from=builder /go/bin/api /app
|
||||
RUN chmod +x /app/api
|
||||
|
||||
LABEL Name=homebox Version=0.0.1
|
||||
LABEL org.opencontainers.image.source="https://github.com/hay-kot/homebox"
|
||||
EXPOSE 7745
|
||||
WORKDIR /app
|
||||
VOLUME [ "/data" ]
|
||||
|
||||
ENTRYPOINT [ "/app/api" ]
|
||||
CMD [ "/data/config.yml" ]
|
||||
CMD [ "/data/config.yml" ]
|
||||
|
||||
23
Taskfile.yml
23
Taskfile.yml
@@ -2,6 +2,7 @@ version: "3"
|
||||
|
||||
env:
|
||||
HBOX_STORAGE_SQLITE_URL: .data/homebox.db?_fk=1
|
||||
HBOX_OPTIONS_ALLOW_REGISTRATION: true
|
||||
UNSAFE_DISABLE_PASSWORD_PROJECTION: "yes_i_am_sure"
|
||||
tasks:
|
||||
setup:
|
||||
@@ -26,7 +27,8 @@ tasks:
|
||||
--modular \
|
||||
--path ./backend/app/api/static/docs/swagger.json \
|
||||
--output ./frontend/lib/api/types
|
||||
- python3 ./scripts/process-types.py ./frontend/lib/api/types/data-contracts.ts
|
||||
- go run ./scripts/process-types/*.go ./frontend/lib/api/types/data-contracts.ts
|
||||
- cp ./backend/app/api/static/docs/swagger.json docs/docs/api/openapi-2.0.json
|
||||
sources:
|
||||
- "./backend/app/api/**/*"
|
||||
- "./backend/internal/data/**"
|
||||
@@ -107,6 +109,16 @@ tasks:
|
||||
cmds:
|
||||
- cd frontend && pnpm dev
|
||||
|
||||
ui:fix:
|
||||
desc: Runs prettier and eslint on the frontend
|
||||
cmds:
|
||||
- cd frontend && pnpm run lint:fix
|
||||
|
||||
ui:check:
|
||||
desc: Runs type checking
|
||||
cmds:
|
||||
- cd frontend && pnpm run typecheck
|
||||
|
||||
test:ci:
|
||||
desc: Runs end-to-end test on a live server (only for use in CI)
|
||||
cmds:
|
||||
@@ -115,3 +127,12 @@ tasks:
|
||||
- sleep 5
|
||||
- cd frontend && pnpm run test:ci
|
||||
silent: true
|
||||
|
||||
pr:
|
||||
desc: Runs all tasks required for a PR
|
||||
cmds:
|
||||
- task: generate
|
||||
- task: go:all
|
||||
- task: ui:check
|
||||
- task: ui:fix
|
||||
- task: test:ci
|
||||
@@ -2,7 +2,6 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/csv"
|
||||
"strings"
|
||||
|
||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||
@@ -10,7 +9,7 @@ import (
|
||||
)
|
||||
|
||||
func (a *app) SetupDemo() {
|
||||
csvText := `Import Ref,Location,Labels,Quantity,Name,Description,Insured,Serial Number,Model Number,Manufacturer,Notes,Purchase From,Purchased Price,Purchased Time,Lifetime Warranty,Warranty Expires,Warranty Details,Sold To,Sold Price,Sold Time,Sold Notes
|
||||
csvText := `HB.import_ref,HB.location,HB.labels,HB.quantity,HB.name,HB.description,HB.insured,HB.serial_number,HB.model_number,HB.manufacturer,HB.notes,HB.purchase_from,HB.purchase_price,HB.purchase_time,HB.lifetime_warranty,HB.warranty_expires,HB.warranty_details,HB.sold_to,HB.sold_price,HB.sold_time,HB.sold_notes
|
||||
,Garage,IOT;Home Assistant; Z-Wave,1,Zooz Universal Relay ZEN17,"Zooz 700 Series Z-Wave Universal Relay ZEN17 for Awnings, Garage Doors, Sprinklers, and More | 2 NO-C-NC Relays (20A, 10A) | Signal Repeater | Hub Required (Compatible with SmartThings and Hubitat)",,,ZEN17,Zooz,,Amazon,39.95,10/13/2021,,,,,,,
|
||||
,Living Room,IOT;Home Assistant; Z-Wave,1,Zooz Motion Sensor,"Zooz Z-Wave Plus S2 Motion Sensor ZSE18 with Magnetic Mount, Works with Vera and SmartThings",,,ZSE18,Zooz,,Amazon,29.95,10/15/2021,,,,,,,
|
||||
,Office,IOT;Home Assistant; Z-Wave,1,Zooz 110v Power Switch,"Zooz Z-Wave Plus Power Switch ZEN15 for 110V AC Units, Sump Pumps, Humidifiers, and More",,,ZEN15,Zooz,,Amazon,39.95,10/13/2021,,,,,,,
|
||||
@@ -19,13 +18,11 @@ func (a *app) SetupDemo() {
|
||||
,Kitchen,IOT;Home Assistant; Z-Wave,1,Smart Rocker Light Dimmer,"UltraPro Z-Wave Smart Rocker Light Dimmer with QuickFit and SimpleWire, 3-Way Ready, Compatible with Alexa, Google Assistant, ZWave Hub Required, Repeater/Range Extender, White Paddle Only, 39351",,,39351,Honeywell,,Amazon,65.98,09/30/0202,,,,,,,
|
||||
`
|
||||
|
||||
var (
|
||||
registration = services.UserRegistration{
|
||||
Email: "demo@example.com",
|
||||
Name: "Demo",
|
||||
Password: "demo",
|
||||
}
|
||||
)
|
||||
registration := services.UserRegistration{
|
||||
Email: "demo@example.com",
|
||||
Name: "Demo",
|
||||
Password: "demo",
|
||||
}
|
||||
|
||||
// First check if we've already setup a demo user and skip if so
|
||||
_, err := a.services.User.Login(context.Background(), registration.Email, registration.Password)
|
||||
@@ -42,17 +39,7 @@ func (a *app) SetupDemo() {
|
||||
token, _ := a.services.User.Login(context.Background(), registration.Email, registration.Password)
|
||||
self, _ := a.services.User.GetSelf(context.Background(), token.Raw)
|
||||
|
||||
// Read CSV Text
|
||||
reader := csv.NewReader(strings.NewReader(csvText))
|
||||
reader.Comma = ','
|
||||
|
||||
records, err := reader.ReadAll()
|
||||
if err != nil {
|
||||
log.Err(err).Msg("Failed to read CSV")
|
||||
log.Fatal().Msg("Failed to setup demo")
|
||||
}
|
||||
|
||||
_, err = a.services.Items.CsvImport(context.Background(), self.GroupID, records)
|
||||
_, err = a.services.Items.CsvImport(context.Background(), self.GroupID, strings.NewReader(csvText))
|
||||
if err != nil {
|
||||
log.Err(err).Msg("Failed to import CSV")
|
||||
log.Fatal().Msg("Failed to setup demo")
|
||||
|
||||
BIN
backend/app/api/handlers/v1/assets/QRIcon.png
Normal file
BIN
backend/app/api/handlers/v1/assets/QRIcon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.5 KiB |
@@ -44,12 +44,13 @@ type (
|
||||
}
|
||||
|
||||
ApiSummary struct {
|
||||
Healthy bool `json:"health"`
|
||||
Versions []string `json:"versions"`
|
||||
Title string `json:"title"`
|
||||
Message string `json:"message"`
|
||||
Build Build `json:"build"`
|
||||
Demo bool `json:"demo"`
|
||||
Healthy bool `json:"health"`
|
||||
Versions []string `json:"versions"`
|
||||
Title string `json:"title"`
|
||||
Message string `json:"message"`
|
||||
Build Build `json:"build"`
|
||||
Demo bool `json:"demo"`
|
||||
AllowRegistration bool `json:"allowRegistration"`
|
||||
}
|
||||
)
|
||||
|
||||
@@ -74,19 +75,21 @@ func NewControllerV1(svc *services.AllServices, repos *repo.AllRepos, options ..
|
||||
}
|
||||
|
||||
// HandleBase godoc
|
||||
// @Summary Retrieves the basic information about the API
|
||||
// @Tags Base
|
||||
// @Produce json
|
||||
// @Success 200 {object} ApiSummary
|
||||
// @Router /v1/status [GET]
|
||||
//
|
||||
// @Summary Application Info
|
||||
// @Tags Base
|
||||
// @Produce json
|
||||
// @Success 200 {object} ApiSummary
|
||||
// @Router /v1/status [GET]
|
||||
func (ctrl *V1Controller) HandleBase(ready ReadyFunc, build Build) server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
return server.Respond(w, http.StatusOK, ApiSummary{
|
||||
Healthy: ready(),
|
||||
Title: "Go API Template",
|
||||
Message: "Welcome to the Go API Template Application!",
|
||||
Build: build,
|
||||
Demo: ctrl.isDemo,
|
||||
Healthy: ready(),
|
||||
Title: "Homebox",
|
||||
Message: "Track, Manage, and Organize your shit",
|
||||
Build: build,
|
||||
Demo: ctrl.isDemo,
|
||||
AllowRegistration: ctrl.allowRegistration,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ func (ctrl *V1Controller) routeID(r *http.Request) (uuid.UUID, error) {
|
||||
func (ctrl *V1Controller) routeUUID(r *http.Request, key string) (uuid.UUID, error) {
|
||||
ID, err := uuid.Parse(chi.URLParam(r, key))
|
||||
if err != nil {
|
||||
return uuid.Nil, validate.NewInvalidRouteKeyError(key)
|
||||
return uuid.Nil, validate.NewRouteKeyError(key)
|
||||
}
|
||||
return ID, nil
|
||||
}
|
||||
|
||||
69
backend/app/api/handlers/v1/v1_ctrl_actions.go
Normal file
69
backend/app/api/handlers/v1/v1_ctrl_actions.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
type ActionAmountResult struct {
|
||||
Completed int `json:"completed"`
|
||||
}
|
||||
|
||||
func actionHandlerFactory(ref string, fn func(context.Context, uuid.UUID) (int, error)) server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
ctx := services.NewContext(r.Context())
|
||||
|
||||
totalCompleted, err := fn(ctx, ctx.GID)
|
||||
if err != nil {
|
||||
log.Err(err).Str("action_ref", ref).Msg("failed to run action")
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return server.Respond(w, http.StatusOK, ActionAmountResult{Completed: totalCompleted})
|
||||
}
|
||||
}
|
||||
|
||||
// HandleEnsureAssetID godoc
|
||||
//
|
||||
// @Summary Ensure Asset IDs
|
||||
// @Description Ensures all items in the database have an asset ID
|
||||
// @Tags Actions
|
||||
// @Produce json
|
||||
// @Success 200 {object} ActionAmountResult
|
||||
// @Router /v1/actions/ensure-asset-ids [Post]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleEnsureAssetID() server.HandlerFunc {
|
||||
return actionHandlerFactory("ensure asset IDs", ctrl.svc.Items.EnsureAssetID)
|
||||
}
|
||||
|
||||
// HandleEnsureImportRefs godoc
|
||||
//
|
||||
// @Summary Ensures Import Refs
|
||||
// @Description Ensures all items in the database have an import ref
|
||||
// @Tags Actions
|
||||
// @Produce json
|
||||
// @Success 200 {object} ActionAmountResult
|
||||
// @Router /v1/actions/ensure-import-refs [Post]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleEnsureImportRefs() server.HandlerFunc {
|
||||
return actionHandlerFactory("ensure import refs", ctrl.svc.Items.EnsureImportRef)
|
||||
}
|
||||
|
||||
// HandleItemDateZeroOut godoc
|
||||
//
|
||||
// @Summary Zero Out Time Fields
|
||||
// @Description Resets all item date fields to the beginning of the day
|
||||
// @Tags Actions
|
||||
// @Produce json
|
||||
// @Success 200 {object} ActionAmountResult
|
||||
// @Router /v1/actions/zero-item-time-fields [Post]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleItemDateZeroOut() server.HandlerFunc {
|
||||
return actionHandlerFactory("zero out date time", ctrl.repo.Items.ZeroOutTimeFields)
|
||||
}
|
||||
61
backend/app/api/handlers/v1/v1_ctrl_assets.go
Normal file
61
backend/app/api/handlers/v1/v1_ctrl_assets.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// HandleAssetGet godocs
|
||||
//
|
||||
// @Summary Get Item by Asset ID
|
||||
// @Tags Items
|
||||
// @Produce json
|
||||
// @Param id path string true "Asset ID"
|
||||
// @Success 200 {object} repo.PaginationResult[repo.ItemSummary]{}
|
||||
// @Router /v1/assets/{id} [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleAssetGet() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
ctx := services.NewContext(r.Context())
|
||||
assetIdParam := chi.URLParam(r, "id")
|
||||
assetIdParam = strings.ReplaceAll(assetIdParam, "-", "") // Remove dashes
|
||||
// Convert the asset ID to an int64
|
||||
assetId, err := strconv.ParseInt(assetIdParam, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pageParam := r.URL.Query().Get("page")
|
||||
var page int64 = -1
|
||||
if pageParam != "" {
|
||||
page, err = strconv.ParseInt(pageParam, 10, 64)
|
||||
if err != nil {
|
||||
return server.Respond(w, http.StatusBadRequest, "Invalid page number")
|
||||
}
|
||||
}
|
||||
|
||||
pageSizeParam := r.URL.Query().Get("pageSize")
|
||||
var pageSize int64 = -1
|
||||
if pageSizeParam != "" {
|
||||
pageSize, err = strconv.ParseInt(pageSizeParam, 10, 64)
|
||||
if err != nil {
|
||||
return server.Respond(w, http.StatusBadRequest, "Invalid page size")
|
||||
}
|
||||
}
|
||||
|
||||
items, err := ctrl.repo.Items.QueryByAssetID(r.Context(), ctx.GID, repo.AssetID(assetId), int(page), int(pageSize))
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to get item")
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
return server.Respond(w, http.StatusOK, items)
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package v1
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||
@@ -13,8 +14,9 @@ import (
|
||||
|
||||
type (
|
||||
TokenResponse struct {
|
||||
Token string `json:"token"`
|
||||
ExpiresAt time.Time `json:"expiresAt"`
|
||||
Token string `json:"token"`
|
||||
ExpiresAt time.Time `json:"expiresAt"`
|
||||
AttachmentToken string `json:"attachmentToken"`
|
||||
}
|
||||
|
||||
LoginForm struct {
|
||||
@@ -24,15 +26,16 @@ type (
|
||||
)
|
||||
|
||||
// HandleAuthLogin godoc
|
||||
// @Summary User Login
|
||||
// @Tags Authentication
|
||||
// @Accept x-www-form-urlencoded
|
||||
// @Accept application/json
|
||||
// @Param username formData string false "string" example(admin@admin.com)
|
||||
// @Param password formData string false "string" example(admin)
|
||||
// @Produce json
|
||||
// @Success 200 {object} TokenResponse
|
||||
// @Router /v1/users/login [POST]
|
||||
//
|
||||
// @Summary User Login
|
||||
// @Tags Authentication
|
||||
// @Accept x-www-form-urlencoded
|
||||
// @Accept application/json
|
||||
// @Param username formData string false "string" example(admin@admin.com)
|
||||
// @Param password formData string false "string" example(admin)
|
||||
// @Produce json
|
||||
// @Success 200 {object} TokenResponse
|
||||
// @Router /v1/users/login [POST]
|
||||
func (ctrl *V1Controller) HandleAuthLogin() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
loginForm := &LoginForm{}
|
||||
@@ -48,7 +51,6 @@ func (ctrl *V1Controller) HandleAuthLogin() server.HandlerFunc {
|
||||
loginForm.Password = r.PostFormValue("password")
|
||||
case server.ContentJSON:
|
||||
err := server.Decode(r, loginForm)
|
||||
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to decode login form")
|
||||
}
|
||||
@@ -69,25 +71,26 @@ 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)
|
||||
}
|
||||
|
||||
return server.Respond(w, http.StatusOK, TokenResponse{
|
||||
Token: "Bearer " + newToken.Raw,
|
||||
ExpiresAt: newToken.ExpiresAt,
|
||||
Token: "Bearer " + newToken.Raw,
|
||||
ExpiresAt: newToken.ExpiresAt,
|
||||
AttachmentToken: newToken.AttachmentToken,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// HandleAuthLogout godoc
|
||||
// @Summary User Logout
|
||||
// @Tags Authentication
|
||||
// @Success 204
|
||||
// @Router /v1/users/logout [POST]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary User Logout
|
||||
// @Tags Authentication
|
||||
// @Success 204
|
||||
// @Router /v1/users/logout [POST]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleAuthLogout() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
token := services.UseTokenCtx(r.Context())
|
||||
@@ -105,13 +108,14 @@ func (ctrl *V1Controller) HandleAuthLogout() server.HandlerFunc {
|
||||
}
|
||||
|
||||
// HandleAuthLogout godoc
|
||||
// @Summary User Token Refresh
|
||||
// @Description handleAuthRefresh returns a handler that will issue a new token from an existing token.
|
||||
// @Description This does not validate that the user still exists within the database.
|
||||
// @Tags Authentication
|
||||
// @Success 200
|
||||
// @Router /v1/users/refresh [GET]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary User Token Refresh
|
||||
// @Description handleAuthRefresh returns a handler that will issue a new token from an existing token.
|
||||
// @Description This does not validate that the user still exists within the database.
|
||||
// @Tags Authentication
|
||||
// @Success 200
|
||||
// @Router /v1/users/refresh [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleAuthRefresh() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
requestToken := services.UseTokenCtx(r.Context())
|
||||
|
||||
@@ -25,44 +25,26 @@ type (
|
||||
)
|
||||
|
||||
// HandleGroupGet godoc
|
||||
// @Summary Get the current user's group
|
||||
// @Tags Group
|
||||
// @Produce json
|
||||
// @Success 200 {object} repo.GroupStatistics
|
||||
// @Router /v1/groups/statistics [Get]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleGroupStatistics() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
ctx := services.NewContext(r.Context())
|
||||
|
||||
stats, err := ctrl.repo.Groups.GroupStatistics(ctx, ctx.GID)
|
||||
if err != nil {
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return server.Respond(w, http.StatusOK, stats)
|
||||
}
|
||||
}
|
||||
|
||||
// HandleGroupGet godoc
|
||||
// @Summary Get the current user's group
|
||||
// @Tags Group
|
||||
// @Produce json
|
||||
// @Success 200 {object} repo.Group
|
||||
// @Router /v1/groups [Get]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Get Group
|
||||
// @Tags Group
|
||||
// @Produce json
|
||||
// @Success 200 {object} repo.Group
|
||||
// @Router /v1/groups [Get]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleGroupGet() server.HandlerFunc {
|
||||
return ctrl.handleGroupGeneral()
|
||||
}
|
||||
|
||||
// HandleGroupUpdate godoc
|
||||
// @Summary Updates some fields of the current users group
|
||||
// @Tags Group
|
||||
// @Produce json
|
||||
// @Param payload body repo.GroupUpdate true "User Data"
|
||||
// @Success 200 {object} repo.Group
|
||||
// @Router /v1/groups [Put]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Update Group
|
||||
// @Tags Group
|
||||
// @Produce json
|
||||
// @Param payload body repo.GroupUpdate true "User Data"
|
||||
// @Success 200 {object} repo.Group
|
||||
// @Router /v1/groups [Put]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleGroupUpdate() server.HandlerFunc {
|
||||
return ctrl.handleGroupGeneral()
|
||||
}
|
||||
@@ -101,13 +83,14 @@ func (ctrl *V1Controller) handleGroupGeneral() server.HandlerFunc {
|
||||
}
|
||||
|
||||
// HandleGroupInvitationsCreate godoc
|
||||
// @Summary Get the current user
|
||||
// @Tags Group
|
||||
// @Produce json
|
||||
// @Param payload body GroupInvitationCreate true "User Data"
|
||||
// @Success 200 {object} GroupInvitation
|
||||
// @Router /v1/groups/invitations [Post]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Create Group Invitation
|
||||
// @Tags Group
|
||||
// @Produce json
|
||||
// @Param payload body GroupInvitationCreate true "User Data"
|
||||
// @Success 200 {object} GroupInvitation
|
||||
// @Router /v1/groups/invitations [Post]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleGroupInvitationsCreate() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
data := GroupInvitationCreate{}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/csv"
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
@@ -12,36 +15,71 @@ import (
|
||||
)
|
||||
|
||||
// HandleItemsGetAll godoc
|
||||
// @Summary Get All Items
|
||||
// @Tags Items
|
||||
// @Produce json
|
||||
// @Param q query string false "search string"
|
||||
// @Param page query int false "page number"
|
||||
// @Param pageSize query int false "items per page"
|
||||
// @Param labels query []string false "label Ids" collectionFormat(multi)
|
||||
// @Param locations query []string false "location Ids" collectionFormat(multi)
|
||||
// @Success 200 {object} repo.PaginationResult[repo.ItemSummary]{}
|
||||
// @Router /v1/items [GET]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Query All Items
|
||||
// @Tags Items
|
||||
// @Produce json
|
||||
// @Param q query string false "search string"
|
||||
// @Param page query int false "page number"
|
||||
// @Param pageSize query int false "items per page"
|
||||
// @Param labels query []string false "label Ids" collectionFormat(multi)
|
||||
// @Param locations query []string false "location Ids" collectionFormat(multi)
|
||||
// @Success 200 {object} repo.PaginationResult[repo.ItemSummary]{}
|
||||
// @Router /v1/items [GET]
|
||||
// @Security Bearer
|
||||
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("perPage")),
|
||||
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) {
|
||||
return server.Respond(w, http.StatusOK, repo.PaginationResult[repo.ItemSummary]{
|
||||
Items: []repo.ItemSummary{},
|
||||
})
|
||||
}
|
||||
log.Err(err).Msg("failed to get items")
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
@@ -50,13 +88,14 @@ func (ctrl *V1Controller) HandleItemsGetAll() server.HandlerFunc {
|
||||
}
|
||||
|
||||
// HandleItemsCreate godoc
|
||||
// @Summary Create a new item
|
||||
// @Tags Items
|
||||
// @Produce json
|
||||
// @Param payload body repo.ItemCreate true "Item Data"
|
||||
// @Success 200 {object} repo.ItemSummary
|
||||
// @Router /v1/items [POST]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Create Item
|
||||
// @Tags Items
|
||||
// @Produce json
|
||||
// @Param payload body repo.ItemCreate true "Item Data"
|
||||
// @Success 200 {object} repo.ItemSummary
|
||||
// @Router /v1/items [POST]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleItemsCreate() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
createData := repo.ItemCreate{}
|
||||
@@ -65,8 +104,8 @@ func (ctrl *V1Controller) HandleItemsCreate() server.HandlerFunc {
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
user := services.UseUserCtx(r.Context())
|
||||
item, err := ctrl.repo.Items.Create(r.Context(), user.GroupID, createData)
|
||||
ctx := services.NewContext(r.Context())
|
||||
item, err := ctrl.svc.Items.Create(ctx, createData)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to create item")
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
@@ -77,38 +116,41 @@ func (ctrl *V1Controller) HandleItemsCreate() server.HandlerFunc {
|
||||
}
|
||||
|
||||
// HandleItemGet godocs
|
||||
// @Summary Gets a item and fields
|
||||
// @Tags Items
|
||||
// @Produce json
|
||||
// @Param id path string true "Item ID"
|
||||
// @Success 200 {object} repo.ItemOut
|
||||
// @Router /v1/items/{id} [GET]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Get Item
|
||||
// @Tags Items
|
||||
// @Produce json
|
||||
// @Param id path string true "Item ID"
|
||||
// @Success 200 {object} repo.ItemOut
|
||||
// @Router /v1/items/{id} [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleItemGet() server.HandlerFunc {
|
||||
return ctrl.handleItemsGeneral()
|
||||
}
|
||||
|
||||
// HandleItemDelete godocs
|
||||
// @Summary deletes a item
|
||||
// @Tags Items
|
||||
// @Produce json
|
||||
// @Param id path string true "Item ID"
|
||||
// @Success 204
|
||||
// @Router /v1/items/{id} [DELETE]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Delete Item
|
||||
// @Tags Items
|
||||
// @Produce json
|
||||
// @Param id path string true "Item ID"
|
||||
// @Success 204
|
||||
// @Router /v1/items/{id} [DELETE]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleItemDelete() server.HandlerFunc {
|
||||
return ctrl.handleItemsGeneral()
|
||||
}
|
||||
|
||||
// HandleItemUpdate godocs
|
||||
// @Summary updates a item
|
||||
// @Tags Items
|
||||
// @Produce json
|
||||
// @Param id path string true "Item ID"
|
||||
// @Param payload body repo.ItemUpdate true "Item Data"
|
||||
// @Success 200 {object} repo.ItemOut
|
||||
// @Router /v1/items/{id} [PUT]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Update Item
|
||||
// @Tags Items
|
||||
// @Produce json
|
||||
// @Param id path string true "Item ID"
|
||||
// @Param payload body repo.ItemUpdate true "Item Data"
|
||||
// @Success 200 {object} repo.ItemOut
|
||||
// @Router /v1/items/{id} [PUT]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleItemUpdate() server.HandlerFunc {
|
||||
return ctrl.handleItemsGeneral()
|
||||
}
|
||||
@@ -155,17 +197,61 @@ func (ctrl *V1Controller) handleItemsGeneral() server.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// HandleGetAllCustomFieldNames godocs
|
||||
//
|
||||
// @Summary Get All Custom Field Names
|
||||
// @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 Get All Custom Field Values
|
||||
// @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
|
||||
// @Produce json
|
||||
// @Success 204
|
||||
// @Param csv formData file true "Image to upload"
|
||||
// @Router /v1/items/import [Post]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Import Items
|
||||
// @Tags Items
|
||||
// @Produce json
|
||||
// @Success 204
|
||||
// @Param csv formData file true "Image to upload"
|
||||
// @Router /v1/items/import [Post]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleItemsImport() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
|
||||
err := r.ParseMultipartForm(ctrl.maxUploadSize << 20)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to parse multipart form")
|
||||
@@ -178,16 +264,9 @@ func (ctrl *V1Controller) HandleItemsImport() server.HandlerFunc {
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
reader := csv.NewReader(file)
|
||||
data, err := reader.ReadAll()
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to read csv")
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
user := services.UseUserCtx(r.Context())
|
||||
|
||||
_, err = ctrl.svc.Items.CsvImport(r.Context(), user.GroupID, data)
|
||||
_, err = ctrl.svc.Items.CsvImport(r.Context(), user.GroupID, file)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to import items")
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
@@ -196,3 +275,27 @@ func (ctrl *V1Controller) HandleItemsImport() server.HandlerFunc {
|
||||
return server.Respond(w, http.StatusNoContent, nil)
|
||||
}
|
||||
}
|
||||
|
||||
// HandleItemsExport godocs
|
||||
//
|
||||
// @Summary Export Items
|
||||
// @Tags Items
|
||||
// @Success 200 {string} string "text/csv"
|
||||
// @Router /v1/items/export [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleItemsExport() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
ctx := services.NewContext(r.Context())
|
||||
|
||||
csvData, err := ctrl.svc.Items.ExportTSV(r.Context(), ctx.GID)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to export items")
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/tsv")
|
||||
w.Header().Set("Content-Disposition", "attachment;filename=homebox-items.tsv")
|
||||
writer := csv.NewWriter(w)
|
||||
return writer.WriteAll(csvData)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package v1
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||
@@ -19,18 +18,19 @@ type (
|
||||
}
|
||||
)
|
||||
|
||||
// HandleItemsImport godocs
|
||||
// @Summary imports items into the database
|
||||
// @Tags Items Attachments
|
||||
// @Produce json
|
||||
// @Param id path string true "Item ID"
|
||||
// @Param file formData file true "File attachment"
|
||||
// @Param type formData string true "Type of file"
|
||||
// @Param name formData string true "name of the file including extension"
|
||||
// @Success 200 {object} repo.ItemOut
|
||||
// @Failure 422 {object} server.ErrorResponse
|
||||
// @Router /v1/items/{id}/attachments [POST]
|
||||
// @Security Bearer
|
||||
// HandleItemAttachmentCreate godocs
|
||||
//
|
||||
// @Summary Create Item Attachment
|
||||
// @Tags Items Attachments
|
||||
// @Produce json
|
||||
// @Param id path string true "Item ID"
|
||||
// @Param file formData file true "File attachment"
|
||||
// @Param type formData string true "Type of file"
|
||||
// @Param name formData string true "name of the file including extension"
|
||||
// @Success 200 {object} repo.ItemOut
|
||||
// @Failure 422 {object} server.ErrorResponse
|
||||
// @Router /v1/items/{id}/attachments [POST]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleItemAttachmentCreate() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
err := r.ParseMultipartForm(ctrl.maxUploadSize << 20)
|
||||
@@ -83,7 +83,6 @@ func (ctrl *V1Controller) HandleItemAttachmentCreate() server.HandlerFunc {
|
||||
attachment.Type(attachmentType),
|
||||
file,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to add attachment")
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
@@ -94,66 +93,42 @@ func (ctrl *V1Controller) HandleItemAttachmentCreate() server.HandlerFunc {
|
||||
}
|
||||
|
||||
// HandleItemAttachmentGet godocs
|
||||
// @Summary retrieves an attachment for an item
|
||||
// @Tags Items Attachments
|
||||
// @Produce application/octet-stream
|
||||
// @Param id path string true "Item ID"
|
||||
// @Param token query string true "Attachment token"
|
||||
// @Success 200
|
||||
// @Router /v1/items/{id}/attachments/download [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleItemAttachmentDownload() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
token := server.GetParam(r, "token", "")
|
||||
|
||||
doc, err := ctrl.svc.Items.AttachmentPath(r.Context(), token)
|
||||
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to get attachment")
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=\"%s\"", doc.Title))
|
||||
w.Header().Set("Content-Type", "application/octet-stream")
|
||||
http.ServeFile(w, r, doc.Path)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// HandleItemAttachmentToken godocs
|
||||
// @Summary retrieves an attachment for an item
|
||||
// @Tags Items Attachments
|
||||
// @Produce application/octet-stream
|
||||
// @Param id path string true "Item ID"
|
||||
// @Param attachment_id path string true "Attachment ID"
|
||||
// @Success 200 {object} ItemAttachmentToken
|
||||
// @Router /v1/items/{id}/attachments/{attachment_id} [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleItemAttachmentToken() server.HandlerFunc {
|
||||
//
|
||||
// @Summary Get Item Attachment
|
||||
// @Tags Items Attachments
|
||||
// @Produce application/octet-stream
|
||||
// @Param id path string true "Item ID"
|
||||
// @Param attachment_id path string true "Attachment ID"
|
||||
// @Success 200 {object} ItemAttachmentToken
|
||||
// @Router /v1/items/{id}/attachments/{attachment_id} [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleItemAttachmentGet() server.HandlerFunc {
|
||||
return ctrl.handleItemAttachmentsHandler
|
||||
}
|
||||
|
||||
// HandleItemAttachmentDelete godocs
|
||||
// @Summary retrieves an attachment for an item
|
||||
// @Tags Items Attachments
|
||||
// @Param id path string true "Item ID"
|
||||
// @Param attachment_id path string true "Attachment ID"
|
||||
// @Success 204
|
||||
// @Router /v1/items/{id}/attachments/{attachment_id} [DELETE]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Delete Item Attachment
|
||||
// @Tags Items Attachments
|
||||
// @Param id path string true "Item ID"
|
||||
// @Param attachment_id path string true "Attachment ID"
|
||||
// @Success 204
|
||||
// @Router /v1/items/{id}/attachments/{attachment_id} [DELETE]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleItemAttachmentDelete() server.HandlerFunc {
|
||||
return ctrl.handleItemAttachmentsHandler
|
||||
}
|
||||
|
||||
// HandleItemAttachmentUpdate godocs
|
||||
// @Summary retrieves an attachment for an item
|
||||
// @Tags Items Attachments
|
||||
// @Param id path string true "Item ID"
|
||||
// @Param attachment_id path string true "Attachment ID"
|
||||
// @Param payload body repo.ItemAttachmentUpdate true "Attachment Update"
|
||||
// @Success 200 {object} repo.ItemOut
|
||||
// @Router /v1/items/{id}/attachments/{attachment_id} [PUT]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Update Item Attachment
|
||||
// @Tags Items Attachments
|
||||
// @Param id path string true "Item ID"
|
||||
// @Param attachment_id path string true "Attachment ID"
|
||||
// @Param payload body repo.ItemAttachmentUpdate true "Attachment Update"
|
||||
// @Success 200 {object} repo.ItemOut
|
||||
// @Router /v1/items/{id}/attachments/{attachment_id} [PUT]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleItemAttachmentUpdate() server.HandlerFunc {
|
||||
return ctrl.handleItemAttachmentsHandler
|
||||
}
|
||||
@@ -171,33 +146,15 @@ func (ctrl *V1Controller) handleItemAttachmentsHandler(w http.ResponseWriter, r
|
||||
|
||||
ctx := services.NewContext(r.Context())
|
||||
switch r.Method {
|
||||
// Token Handler
|
||||
case http.MethodGet:
|
||||
token, err := ctrl.svc.Items.AttachmentToken(ctx, ID, attachmentID)
|
||||
doc, err := ctrl.svc.Items.AttachmentPath(r.Context(), attachmentID)
|
||||
if err != nil {
|
||||
switch err {
|
||||
case services.ErrNotFound:
|
||||
log.Err(err).
|
||||
Str("id", attachmentID.String()).
|
||||
Msg("failed to find attachment with id")
|
||||
|
||||
return validate.NewRequestError(err, http.StatusNotFound)
|
||||
|
||||
case services.ErrFileNotFound:
|
||||
log.Err(err).
|
||||
Str("id", attachmentID.String()).
|
||||
Msg("failed to find file path for attachment with id")
|
||||
log.Warn().Msg("attachment with no file path removed from database")
|
||||
|
||||
return validate.NewRequestError(err, http.StatusNotFound)
|
||||
|
||||
default:
|
||||
log.Err(err).Msg("failed to get attachment")
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
log.Err(err).Msg("failed to get attachment path")
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return server.Respond(w, http.StatusOK, ItemAttachmentToken{Token: token})
|
||||
http.ServeFile(w, r, doc.Path)
|
||||
return nil
|
||||
|
||||
// Delete Attachment Handler
|
||||
case http.MethodDelete:
|
||||
|
||||
@@ -12,12 +12,13 @@ import (
|
||||
)
|
||||
|
||||
// HandleLabelsGetAll godoc
|
||||
// @Summary Get All Labels
|
||||
// @Tags Labels
|
||||
// @Produce json
|
||||
// @Success 200 {object} server.Results{items=[]repo.LabelOut}
|
||||
// @Router /v1/labels [GET]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Get All Labels
|
||||
// @Tags Labels
|
||||
// @Produce json
|
||||
// @Success 200 {object} server.Results{items=[]repo.LabelOut}
|
||||
// @Router /v1/labels [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleLabelsGetAll() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
user := services.UseUserCtx(r.Context())
|
||||
@@ -31,13 +32,14 @@ func (ctrl *V1Controller) HandleLabelsGetAll() server.HandlerFunc {
|
||||
}
|
||||
|
||||
// HandleLabelsCreate godoc
|
||||
// @Summary Create a new label
|
||||
// @Tags Labels
|
||||
// @Produce json
|
||||
// @Param payload body repo.LabelCreate true "Label Data"
|
||||
// @Success 200 {object} repo.LabelSummary
|
||||
// @Router /v1/labels [POST]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Create Label
|
||||
// @Tags Labels
|
||||
// @Produce json
|
||||
// @Param payload body repo.LabelCreate true "Label Data"
|
||||
// @Success 200 {object} repo.LabelSummary
|
||||
// @Router /v1/labels [POST]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleLabelsCreate() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
createData := repo.LabelCreate{}
|
||||
@@ -58,37 +60,40 @@ func (ctrl *V1Controller) HandleLabelsCreate() server.HandlerFunc {
|
||||
}
|
||||
|
||||
// HandleLabelDelete godocs
|
||||
// @Summary deletes a label
|
||||
// @Tags Labels
|
||||
// @Produce json
|
||||
// @Param id path string true "Label ID"
|
||||
// @Success 204
|
||||
// @Router /v1/labels/{id} [DELETE]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Delete Label
|
||||
// @Tags Labels
|
||||
// @Produce json
|
||||
// @Param id path string true "Label ID"
|
||||
// @Success 204
|
||||
// @Router /v1/labels/{id} [DELETE]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleLabelDelete() server.HandlerFunc {
|
||||
return ctrl.handleLabelsGeneral()
|
||||
}
|
||||
|
||||
// HandleLabelGet godocs
|
||||
// @Summary Gets a label and fields
|
||||
// @Tags Labels
|
||||
// @Produce json
|
||||
// @Param id path string true "Label ID"
|
||||
// @Success 200 {object} repo.LabelOut
|
||||
// @Router /v1/labels/{id} [GET]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Get Label
|
||||
// @Tags Labels
|
||||
// @Produce json
|
||||
// @Param id path string true "Label ID"
|
||||
// @Success 200 {object} repo.LabelOut
|
||||
// @Router /v1/labels/{id} [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleLabelGet() server.HandlerFunc {
|
||||
return ctrl.handleLabelsGeneral()
|
||||
}
|
||||
|
||||
// HandleLabelUpdate godocs
|
||||
// @Summary updates a label
|
||||
// @Tags Labels
|
||||
// @Produce json
|
||||
// @Param id path string true "Label ID"
|
||||
// @Success 200 {object} repo.LabelOut
|
||||
// @Router /v1/labels/{id} [PUT]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Update Label
|
||||
// @Tags Labels
|
||||
// @Produce json
|
||||
// @Param id path string true "Label ID"
|
||||
// @Success 200 {object} repo.LabelOut
|
||||
// @Router /v1/labels/{id} [PUT]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleLabelUpdate() server.HandlerFunc {
|
||||
return ctrl.handleLabelsGeneral()
|
||||
}
|
||||
|
||||
@@ -11,14 +11,48 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// HandleLocationTreeQuery godoc
|
||||
//
|
||||
// @Summary Get Locations Tree
|
||||
// @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
|
||||
// @Produce json
|
||||
// @Param filterChildren query bool false "Filter locations with parents"
|
||||
// @Success 200 {object} server.Results{items=[]repo.LocationOutCount}
|
||||
// @Router /v1/locations [GET]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Get All Locations
|
||||
// @Tags Locations
|
||||
// @Produce json
|
||||
// @Param filterChildren query bool false "Filter locations with parents"
|
||||
// @Success 200 {object} server.Results{items=[]repo.LocationOutCount}
|
||||
// @Router /v1/locations [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleLocationGetAll() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
user := services.UseUserCtx(r.Context())
|
||||
@@ -40,13 +74,14 @@ func (ctrl *V1Controller) HandleLocationGetAll() server.HandlerFunc {
|
||||
}
|
||||
|
||||
// HandleLocationCreate godoc
|
||||
// @Summary Create a new location
|
||||
// @Tags Locations
|
||||
// @Produce json
|
||||
// @Param payload body repo.LocationCreate true "Location Data"
|
||||
// @Success 200 {object} repo.LocationSummary
|
||||
// @Router /v1/locations [POST]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Create Location
|
||||
// @Tags Locations
|
||||
// @Produce json
|
||||
// @Param payload body repo.LocationCreate true "Location Data"
|
||||
// @Success 200 {object} repo.LocationSummary
|
||||
// @Router /v1/locations [POST]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleLocationCreate() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
createData := repo.LocationCreate{}
|
||||
@@ -67,38 +102,41 @@ func (ctrl *V1Controller) HandleLocationCreate() server.HandlerFunc {
|
||||
}
|
||||
|
||||
// HandleLocationDelete godocs
|
||||
// @Summary deletes a location
|
||||
// @Tags Locations
|
||||
// @Produce json
|
||||
// @Param id path string true "Location ID"
|
||||
// @Success 204
|
||||
// @Router /v1/locations/{id} [DELETE]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Delete Location
|
||||
// @Tags Locations
|
||||
// @Produce json
|
||||
// @Param id path string true "Location ID"
|
||||
// @Success 204
|
||||
// @Router /v1/locations/{id} [DELETE]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleLocationDelete() server.HandlerFunc {
|
||||
return ctrl.handleLocationGeneral()
|
||||
}
|
||||
|
||||
// HandleLocationGet godocs
|
||||
// @Summary Gets a location and fields
|
||||
// @Tags Locations
|
||||
// @Produce json
|
||||
// @Param id path string true "Location ID"
|
||||
// @Success 200 {object} repo.LocationOut
|
||||
// @Router /v1/locations/{id} [GET]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Get Location
|
||||
// @Tags Locations
|
||||
// @Produce json
|
||||
// @Param id path string true "Location ID"
|
||||
// @Success 200 {object} repo.LocationOut
|
||||
// @Router /v1/locations/{id} [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleLocationGet() server.HandlerFunc {
|
||||
return ctrl.handleLocationGeneral()
|
||||
}
|
||||
|
||||
// HandleLocationUpdate godocs
|
||||
// @Summary updates a location
|
||||
// @Tags Locations
|
||||
// @Produce json
|
||||
// @Param id path string true "Location ID"
|
||||
// @Param payload body repo.LocationUpdate true "Location Data"
|
||||
// @Success 200 {object} repo.LocationOut
|
||||
// @Router /v1/locations/{id} [PUT]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Update Location
|
||||
// @Tags Locations
|
||||
// @Produce json
|
||||
// @Param id path string true "Location ID"
|
||||
// @Param payload body repo.LocationUpdate true "Location Data"
|
||||
// @Success 200 {object} repo.LocationOut
|
||||
// @Router /v1/locations/{id} [PUT]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleLocationUpdate() server.HandlerFunc {
|
||||
return ctrl.handleLocationGeneral()
|
||||
}
|
||||
|
||||
137
backend/app/api/handlers/v1/v1_ctrl_maint_entry.go
Normal file
137
backend/app/api/handlers/v1/v1_ctrl_maint_entry.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// HandleMaintenanceGetLog godoc
|
||||
//
|
||||
// @Summary Get Maintenance Log
|
||||
// @Tags Maintenance
|
||||
// @Produce json
|
||||
// @Success 200 {object} repo.MaintenanceLog
|
||||
// @Router /v1/items/{id}/maintenance [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleMaintenanceLogGet() server.HandlerFunc {
|
||||
return ctrl.handleMaintenanceLog()
|
||||
}
|
||||
|
||||
// HandleMaintenanceEntryCreate godoc
|
||||
//
|
||||
// @Summary Create Maintenance Entry
|
||||
// @Tags Maintenance
|
||||
// @Produce json
|
||||
// @Param payload body repo.MaintenanceEntryCreate true "Entry Data"
|
||||
// @Success 200 {object} repo.MaintenanceEntry
|
||||
// @Router /v1/items/{id}/maintenance [POST]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleMaintenanceEntryCreate() server.HandlerFunc {
|
||||
return ctrl.handleMaintenanceLog()
|
||||
}
|
||||
|
||||
// HandleMaintenanceEntryDelete godoc
|
||||
//
|
||||
// @Summary Delete Maintenance Entry
|
||||
// @Tags Maintenance
|
||||
// @Produce json
|
||||
// @Success 204
|
||||
// @Router /v1/items/{id}/maintenance/{entry_id} [DELETE]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleMaintenanceEntryDelete() server.HandlerFunc {
|
||||
return ctrl.handleMaintenanceLog()
|
||||
}
|
||||
|
||||
// HandleMaintenanceEntryUpdate godoc
|
||||
//
|
||||
// @Summary Update Maintenance Entry
|
||||
// @Tags Maintenance
|
||||
// @Produce json
|
||||
// @Param payload body repo.MaintenanceEntryUpdate true "Entry Data"
|
||||
// @Success 200 {object} repo.MaintenanceEntry
|
||||
// @Router /v1/items/{id}/maintenance/{entry_id} [PUT]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleMaintenanceEntryUpdate() server.HandlerFunc {
|
||||
return ctrl.handleMaintenanceLog()
|
||||
}
|
||||
|
||||
func (ctrl *V1Controller) handleMaintenanceLog() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
ctx := services.NewContext(r.Context())
|
||||
itemID, err := ctrl.routeID(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
completed, _ := strconv.ParseBool(r.URL.Query().Get("completed"))
|
||||
scheduled, _ := strconv.ParseBool(r.URL.Query().Get("scheduled"))
|
||||
query := repo.MaintenanceLogQuery{
|
||||
Completed: completed,
|
||||
Scheduled: scheduled,
|
||||
}
|
||||
|
||||
mlog, err := ctrl.repo.MaintEntry.GetLog(ctx, itemID, query)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to get items")
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
return server.Respond(w, http.StatusOK, mlog)
|
||||
case http.MethodPost:
|
||||
var create repo.MaintenanceEntryCreate
|
||||
err := server.Decode(r, &create)
|
||||
if err != nil {
|
||||
return validate.NewRequestError(err, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
entry, err := ctrl.repo.MaintEntry.Create(ctx, itemID, create)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to create item")
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return server.Respond(w, http.StatusCreated, entry)
|
||||
case http.MethodPut:
|
||||
entryID, err := ctrl.routeUUID(r, "entry_id")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var update repo.MaintenanceEntryUpdate
|
||||
err = server.Decode(r, &update)
|
||||
if err != nil {
|
||||
return validate.NewRequestError(err, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
entry, err := ctrl.repo.MaintEntry.Update(ctx, entryID, update)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to update item")
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return server.Respond(w, http.StatusOK, entry)
|
||||
case http.MethodDelete:
|
||||
entryID, err := ctrl.routeUUID(r, "entry_id")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ctrl.repo.MaintEntry.Delete(ctx, entryID)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("failed to delete item")
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return server.Respond(w, http.StatusNoContent, nil)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
106
backend/app/api/handlers/v1/v1_ctrl_notifiers.go
Normal file
106
backend/app/api/handlers/v1/v1_ctrl_notifiers.go
Normal file
@@ -0,0 +1,106 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/containrrr/shoutrrr"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
"github.com/hay-kot/homebox/backend/internal/web/adapters"
|
||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
||||
)
|
||||
|
||||
// HandleGetUserNotifiers godoc
|
||||
//
|
||||
// @Summary Get Notifiers
|
||||
// @Tags Notifiers
|
||||
// @Produce json
|
||||
// @Success 200 {object} server.Results{items=[]repo.NotifierOut}
|
||||
// @Router /v1/notifiers [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleGetUserNotifiers() server.HandlerFunc {
|
||||
fn := func(ctx context.Context, _ struct{}) ([]repo.NotifierOut, error) {
|
||||
user := services.UseUserCtx(ctx)
|
||||
return ctrl.repo.Notifiers.GetByUser(ctx, user.ID)
|
||||
}
|
||||
|
||||
return adapters.Query(fn, http.StatusOK)
|
||||
}
|
||||
|
||||
// HandleCreateNotifier godoc
|
||||
//
|
||||
// @Summary Create Notifier
|
||||
// @Tags Notifiers
|
||||
// @Produce json
|
||||
// @Param payload body repo.NotifierCreate true "Notifier Data"
|
||||
// @Success 200 {object} repo.NotifierOut
|
||||
// @Router /v1/notifiers [POST]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleCreateNotifier() server.HandlerFunc {
|
||||
fn := func(ctx context.Context, in repo.NotifierCreate) (repo.NotifierOut, error) {
|
||||
auth := services.NewContext(ctx)
|
||||
return ctrl.repo.Notifiers.Create(ctx, auth.GID, auth.UID, in)
|
||||
}
|
||||
|
||||
return adapters.Action(fn, http.StatusCreated)
|
||||
}
|
||||
|
||||
// HandleDeleteNotifier godocs
|
||||
//
|
||||
// @Summary Delete a Notifier
|
||||
// @Tags Notifiers
|
||||
// @Param id path string true "Notifier ID"
|
||||
// @Success 204
|
||||
// @Router /v1/notifiers/{id} [DELETE]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleDeleteNotifier() server.HandlerFunc {
|
||||
fn := func(ctx context.Context, ID uuid.UUID) (any, error) {
|
||||
auth := services.NewContext(ctx)
|
||||
return nil, ctrl.repo.Notifiers.Delete(ctx, auth.UID, ID)
|
||||
}
|
||||
|
||||
return adapters.CommandID("id", fn, http.StatusNoContent)
|
||||
}
|
||||
|
||||
// HandleUpdateNotifier godocs
|
||||
//
|
||||
// @Summary Update Notifier
|
||||
// @Tags Notifiers
|
||||
// @Param id path string true "Notifier ID"
|
||||
// @Param payload body repo.NotifierUpdate true "Notifier Data"
|
||||
// @Success 200 {object} repo.NotifierOut
|
||||
// @Router /v1/notifiers/{id} [PUT]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleUpdateNotifier() server.HandlerFunc {
|
||||
fn := func(ctx context.Context, ID uuid.UUID, in repo.NotifierUpdate) (repo.NotifierOut, error) {
|
||||
auth := services.NewContext(ctx)
|
||||
return ctrl.repo.Notifiers.Update(ctx, auth.UID, ID, in)
|
||||
}
|
||||
|
||||
return adapters.ActionID("id", fn, http.StatusOK)
|
||||
}
|
||||
|
||||
// HandlerNotifierTest godoc
|
||||
//
|
||||
// @Summary Test Notifier
|
||||
// @Tags Notifiers
|
||||
// @Produce json
|
||||
// @Param id path string true "Notifier ID"
|
||||
// @Param url query string true "URL"
|
||||
// @Success 204
|
||||
// @Router /v1/notifiers/test [POST]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandlerNotifierTest() server.HandlerFunc {
|
||||
type body struct {
|
||||
URL string `json:"url" validate:"required"`
|
||||
}
|
||||
|
||||
fn := func(ctx context.Context, q body) (any, error) {
|
||||
err := shoutrrr.Send(q.URL, "Test message from Homebox")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return adapters.Action(fn, http.StatusOK)
|
||||
}
|
||||
67
backend/app/api/handlers/v1/v1_ctrl_qrcode.go
Normal file
67
backend/app/api/handlers/v1/v1_ctrl_qrcode.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"image/png"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
||||
"github.com/yeqown/go-qrcode/v2"
|
||||
"github.com/yeqown/go-qrcode/writer/standard"
|
||||
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
//go:embed assets/QRIcon.png
|
||||
var qrcodeLogo []byte
|
||||
|
||||
// HandleGenerateQRCode godoc
|
||||
//
|
||||
// @Summary Create QR Code
|
||||
// @Tags Items
|
||||
// @Produce json
|
||||
// @Param data query string false "data to be encoded into qrcode"
|
||||
// @Success 200 {string} string "image/jpeg"
|
||||
// @Router /v1/qrcode [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleGenerateQRCode() server.HandlerFunc {
|
||||
const MaxLength = 4_296 // assume alphanumeric characters only
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
data := r.URL.Query().Get("data")
|
||||
|
||||
image, err := png.Decode(bytes.NewReader(qrcodeLogo))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if len(data) > MaxLength {
|
||||
return validate.NewFieldErrors(validate.FieldError{
|
||||
Field: "data",
|
||||
Error: "max length is 4,296 characters exceeded",
|
||||
})
|
||||
}
|
||||
|
||||
qrc, err := qrcode.New(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
toWriteCloser := struct {
|
||||
io.Writer
|
||||
io.Closer
|
||||
}{
|
||||
Writer: w,
|
||||
Closer: io.NopCloser(nil),
|
||||
}
|
||||
|
||||
qrwriter := standard.NewWithWriter(toWriteCloser, standard.WithLogoImage(image))
|
||||
|
||||
// Return the QR code as a jpeg image
|
||||
w.Header().Set("Content-Type", "image/jpeg")
|
||||
w.Header().Set("Content-Disposition", "attachment; filename=qrcode.jpg")
|
||||
return qrc.Save(qrwriter)
|
||||
}
|
||||
}
|
||||
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 Export Bill of Materials
|
||||
// @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.Items.ExportBillOfMaterialsTSV(r.Context(), actor.GroupID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/tsv")
|
||||
w.Header().Set("Content-Disposition", "attachment; filename=bill-of-materials.tsv")
|
||||
_, err = w.Write(csv)
|
||||
return err
|
||||
}
|
||||
}
|
||||
113
backend/app/api/handlers/v1/v1_ctrl_statistics.go
Normal file
113
backend/app/api/handlers/v1/v1_ctrl_statistics.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||
"github.com/hay-kot/homebox/backend/internal/sys/validate"
|
||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
||||
)
|
||||
|
||||
// HandleGroupGet godoc
|
||||
//
|
||||
// @Summary Get Location Statistics
|
||||
// @Tags Statistics
|
||||
// @Produce json
|
||||
// @Success 200 {object} []repo.TotalsByOrganizer
|
||||
// @Router /v1/groups/statistics/locations [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleGroupStatisticsLocations() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
ctx := services.NewContext(r.Context())
|
||||
|
||||
stats, err := ctrl.repo.Groups.StatsLocationsByPurchasePrice(ctx, ctx.GID)
|
||||
if err != nil {
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return server.Respond(w, http.StatusOK, stats)
|
||||
}
|
||||
}
|
||||
|
||||
// HandleGroupStatisticsLabels godoc
|
||||
//
|
||||
// @Summary Get Label Statistics
|
||||
// @Tags Statistics
|
||||
// @Produce json
|
||||
// @Success 200 {object} []repo.TotalsByOrganizer
|
||||
// @Router /v1/groups/statistics/labels [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleGroupStatisticsLabels() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
ctx := services.NewContext(r.Context())
|
||||
|
||||
stats, err := ctrl.repo.Groups.StatsLabelsByPurchasePrice(ctx, ctx.GID)
|
||||
if err != nil {
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return server.Respond(w, http.StatusOK, stats)
|
||||
}
|
||||
}
|
||||
|
||||
// HandleGroupStatistics godoc
|
||||
//
|
||||
// @Summary Get Group Statistics
|
||||
// @Tags Statistics
|
||||
// @Produce json
|
||||
// @Success 200 {object} repo.GroupStatistics
|
||||
// @Router /v1/groups/statistics [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleGroupStatistics() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
ctx := services.NewContext(r.Context())
|
||||
|
||||
stats, err := ctrl.repo.Groups.StatsGroup(ctx, ctx.GID)
|
||||
if err != nil {
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return server.Respond(w, http.StatusOK, stats)
|
||||
}
|
||||
}
|
||||
|
||||
// HandleGroupStatisticsPriceOverTime godoc
|
||||
//
|
||||
// @Summary Get Purchase Price Statistics
|
||||
// @Tags Statistics
|
||||
// @Produce json
|
||||
// @Success 200 {object} repo.ValueOverTime
|
||||
// @Param start query string false "start date"
|
||||
// @Param end query string false "end date"
|
||||
// @Router /v1/groups/statistics/purchase-price [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleGroupStatisticsPriceOverTime() server.HandlerFunc {
|
||||
parseDate := func(datestr string, defaultDate time.Time) (time.Time, error) {
|
||||
if datestr == "" {
|
||||
return defaultDate, nil
|
||||
}
|
||||
return time.Parse("2006-01-02", datestr)
|
||||
}
|
||||
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
ctx := services.NewContext(r.Context())
|
||||
|
||||
startDate, err := parseDate(r.URL.Query().Get("start"), time.Now().AddDate(0, -1, 0))
|
||||
if err != nil {
|
||||
return validate.NewRequestError(err, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
endDate, err := parseDate(r.URL.Query().Get("end"), time.Now())
|
||||
if err != nil {
|
||||
return validate.NewRequestError(err, http.StatusBadRequest)
|
||||
}
|
||||
|
||||
stats, err := ctrl.repo.Groups.StatsPurchasePrice(ctx, ctx.GID, startDate, endDate)
|
||||
if err != nil {
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
return server.Respond(w, http.StatusOK, stats)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package v1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/google/uuid"
|
||||
@@ -11,13 +12,14 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// HandleUserSelf godoc
|
||||
// @Summary Get the current user
|
||||
// @Tags User
|
||||
// @Produce json
|
||||
// @Param payload body services.UserRegistration true "User Data"
|
||||
// @Success 204
|
||||
// @Router /v1/users/register [Post]
|
||||
// HandleUserRegistration godoc
|
||||
//
|
||||
// @Summary Register New User
|
||||
// @Tags User
|
||||
// @Produce json
|
||||
// @Param payload body services.UserRegistration true "User Data"
|
||||
// @Success 204
|
||||
// @Router /v1/users/register [Post]
|
||||
func (ctrl *V1Controller) HandleUserRegistration() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
regData := services.UserRegistration{}
|
||||
@@ -28,7 +30,7 @@ func (ctrl *V1Controller) HandleUserRegistration() server.HandlerFunc {
|
||||
}
|
||||
|
||||
if !ctrl.allowRegistration && regData.GroupToken == "" {
|
||||
return validate.NewRequestError(nil, http.StatusForbidden)
|
||||
return validate.NewRequestError(fmt.Errorf("user registration disabled"), http.StatusForbidden)
|
||||
}
|
||||
|
||||
_, err := ctrl.svc.User.RegisterUser(r.Context(), regData)
|
||||
@@ -42,12 +44,13 @@ func (ctrl *V1Controller) HandleUserRegistration() server.HandlerFunc {
|
||||
}
|
||||
|
||||
// HandleUserSelf godoc
|
||||
// @Summary Get the current user
|
||||
// @Tags User
|
||||
// @Produce json
|
||||
// @Success 200 {object} server.Result{item=repo.UserOut}
|
||||
// @Router /v1/users/self [GET]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Get User Self
|
||||
// @Tags User
|
||||
// @Produce json
|
||||
// @Success 200 {object} server.Result{item=repo.UserOut}
|
||||
// @Router /v1/users/self [GET]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleUserSelf() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
token := services.UseTokenCtx(r.Context())
|
||||
@@ -62,13 +65,14 @@ func (ctrl *V1Controller) HandleUserSelf() server.HandlerFunc {
|
||||
}
|
||||
|
||||
// HandleUserSelfUpdate godoc
|
||||
// @Summary Update the current user
|
||||
// @Tags User
|
||||
// @Produce json
|
||||
// @Param payload body repo.UserUpdate true "User Data"
|
||||
// @Success 200 {object} server.Result{item=repo.UserUpdate}
|
||||
// @Router /v1/users/self [PUT]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Update Account
|
||||
// @Tags User
|
||||
// @Produce json
|
||||
// @Param payload body repo.UserUpdate true "User Data"
|
||||
// @Success 200 {object} server.Result{item=repo.UserUpdate}
|
||||
// @Router /v1/users/self [PUT]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleUserSelfUpdate() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
updateData := repo.UserUpdate{}
|
||||
@@ -79,7 +83,6 @@ func (ctrl *V1Controller) HandleUserSelfUpdate() server.HandlerFunc {
|
||||
|
||||
actor := services.UseUserCtx(r.Context())
|
||||
newData, err := ctrl.svc.User.UpdateSelf(r.Context(), actor.ID, updateData)
|
||||
|
||||
if err != nil {
|
||||
return validate.NewRequestError(err, http.StatusInternalServerError)
|
||||
}
|
||||
@@ -89,12 +92,13 @@ func (ctrl *V1Controller) HandleUserSelfUpdate() server.HandlerFunc {
|
||||
}
|
||||
|
||||
// HandleUserSelfDelete godoc
|
||||
// @Summary Deletes the user account
|
||||
// @Tags User
|
||||
// @Produce json
|
||||
// @Success 204
|
||||
// @Router /v1/users/self [DELETE]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Delete Account
|
||||
// @Tags User
|
||||
// @Produce json
|
||||
// @Success 204
|
||||
// @Router /v1/users/self [DELETE]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleUserSelfDelete() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
if ctrl.isDemo {
|
||||
@@ -118,12 +122,13 @@ type (
|
||||
)
|
||||
|
||||
// HandleUserSelfChangePassword godoc
|
||||
// @Summary Updates the users password
|
||||
// @Tags User
|
||||
// @Success 204
|
||||
// @Param payload body ChangePassword true "Password Payload"
|
||||
// @Router /v1/users/change-password [PUT]
|
||||
// @Security Bearer
|
||||
//
|
||||
// @Summary Change Password
|
||||
// @Tags User
|
||||
// @Success 204
|
||||
// @Param payload body ChangePassword true "Password Payload"
|
||||
// @Router /v1/users/change-password [PUT]
|
||||
// @Security Bearer
|
||||
func (ctrl *V1Controller) HandleUserSelfChangePassword() server.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) error {
|
||||
if ctrl.isDemo {
|
||||
|
||||
@@ -27,9 +27,9 @@ var (
|
||||
buildTime = "now"
|
||||
)
|
||||
|
||||
// @title Go API Templates
|
||||
// @title Homebox API
|
||||
// @version 1.0
|
||||
// @description This is a simple Rest API Server Template that implements some basic User and Authentication patterns to help you get started and bootstrap your next project!.
|
||||
// @description Track, Manage, and Organize your Shit.
|
||||
// @contact.name Don't
|
||||
// @license.name MIT
|
||||
// @BasePath /api
|
||||
@@ -57,7 +57,7 @@ func run(cfg *config.Config) error {
|
||||
// =========================================================================
|
||||
// Initialize Database & Repos
|
||||
|
||||
err := os.MkdirAll(cfg.Storage.Data, 0755)
|
||||
err := os.MkdirAll(cfg.Storage.Data, 0o755)
|
||||
if err != nil {
|
||||
log.Fatal().Err(err).Msg("failed to create data directory")
|
||||
}
|
||||
@@ -112,7 +112,10 @@ func run(cfg *config.Config) error {
|
||||
|
||||
app.db = c
|
||||
app.repos = repo.New(c, cfg.Storage.Data)
|
||||
app.services = services.New(app.repos)
|
||||
app.services = services.New(
|
||||
app.repos,
|
||||
services.WithAutoIncrementAssetID(cfg.Options.AutoIncrementAssetID),
|
||||
)
|
||||
|
||||
// =========================================================================
|
||||
// Start Server\
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/hay-kot/homebox/backend/internal/core/services"
|
||||
@@ -10,22 +12,139 @@ import (
|
||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
||||
)
|
||||
|
||||
type tokenHasKey struct {
|
||||
key string
|
||||
}
|
||||
|
||||
var hashedToken = tokenHasKey{key: "hashedToken"}
|
||||
|
||||
type RoleMode int
|
||||
|
||||
const (
|
||||
RoleModeOr RoleMode = 0
|
||||
RoleModeAnd RoleMode = 1
|
||||
)
|
||||
|
||||
// mwRoles is a middleware that will validate the required roles are met. All roles
|
||||
// are required to be met for the request to be allowed. If the user does not have
|
||||
// the required roles, a 403 Forbidden will be returned.
|
||||
//
|
||||
// WARNING: This middleware _MUST_ be called after mwAuthToken or else it will panic
|
||||
func (a *app) mwRoles(rm RoleMode, required ...string) server.Middleware {
|
||||
return func(next server.Handler) server.Handler {
|
||||
return server.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
|
||||
ctx := r.Context()
|
||||
|
||||
maybeToken := ctx.Value(hashedToken)
|
||||
if maybeToken == nil {
|
||||
panic("mwRoles: token not found in context, you must call mwAuthToken before mwRoles")
|
||||
}
|
||||
|
||||
token := maybeToken.(string)
|
||||
|
||||
roles, err := a.repos.AuthTokens.GetRoles(r.Context(), token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
outer:
|
||||
switch rm {
|
||||
case RoleModeOr:
|
||||
for _, role := range required {
|
||||
if roles.Contains(role) {
|
||||
break outer
|
||||
}
|
||||
}
|
||||
return validate.NewRequestError(errors.New("Forbidden"), http.StatusForbidden)
|
||||
case RoleModeAnd:
|
||||
for _, req := range required {
|
||||
if !roles.Contains(req) {
|
||||
return validate.NewRequestError(errors.New("Unauthorized"), http.StatusForbidden)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type KeyFunc func(r *http.Request) (string, error)
|
||||
|
||||
func getBearer(r *http.Request) (string, error) {
|
||||
auth := r.Header.Get("Authorization")
|
||||
if auth == "" {
|
||||
return "", errors.New("authorization header is required")
|
||||
}
|
||||
|
||||
return auth, nil
|
||||
}
|
||||
|
||||
func getQuery(r *http.Request) (string, error) {
|
||||
token := r.URL.Query().Get("access_token")
|
||||
if token == "" {
|
||||
return "", errors.New("access_token query is required")
|
||||
}
|
||||
|
||||
token, err := url.QueryUnescape(token)
|
||||
if err != nil {
|
||||
return "", errors.New("access_token query is required")
|
||||
}
|
||||
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func getCookie(r *http.Request) (string, error) {
|
||||
cookie, err := r.Cookie("hb.auth.token")
|
||||
if err != nil {
|
||||
return "", errors.New("access_token cookie is required")
|
||||
}
|
||||
|
||||
token, err := url.QueryUnescape(cookie.Value)
|
||||
if err != nil {
|
||||
return "", errors.New("access_token cookie is required")
|
||||
}
|
||||
|
||||
return token, nil
|
||||
}
|
||||
|
||||
// mwAuthToken is a middleware that will check the database for a stateful token
|
||||
// and attach it to the request context with the user, or return a 401 if it doesn't exist.
|
||||
// and attach it's user to the request context, or return an appropriate error.
|
||||
// Authorization support is by token via Headers or Query Parameter
|
||||
//
|
||||
// Example:
|
||||
// - header = "Bearer 1234567890"
|
||||
// - query = "?access_token=1234567890"
|
||||
// - cookie = hb.auth.token = 1234567890
|
||||
func (a *app) mwAuthToken(next server.Handler) server.Handler {
|
||||
return server.HandlerFunc(func(w http.ResponseWriter, r *http.Request) error {
|
||||
requestToken := r.Header.Get("Authorization")
|
||||
keyFuncs := [...]KeyFunc{
|
||||
getBearer,
|
||||
getCookie,
|
||||
getQuery,
|
||||
}
|
||||
|
||||
var requestToken string
|
||||
for _, keyFunc := range keyFuncs {
|
||||
token, err := keyFunc(r)
|
||||
if err == nil {
|
||||
requestToken = token
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if requestToken == "" {
|
||||
return validate.NewRequestError(errors.New("Authorization header is required"), http.StatusUnauthorized)
|
||||
return validate.NewRequestError(errors.New("Authorization header or query is required"), http.StatusUnauthorized)
|
||||
}
|
||||
|
||||
requestToken = strings.TrimPrefix(requestToken, "Bearer ")
|
||||
usr, err := a.services.User.GetSelf(r.Context(), requestToken)
|
||||
|
||||
r = r.WithContext(context.WithValue(r.Context(), hashedToken, requestToken))
|
||||
|
||||
usr, err := a.services.User.GetSelf(r.Context(), requestToken)
|
||||
// Check the database for the token
|
||||
if err != nil {
|
||||
return validate.NewRequestError(errors.New("Authorization header is required"), http.StatusUnauthorized)
|
||||
return validate.NewRequestError(errors.New("valid authorization header is required"), http.StatusUnauthorized)
|
||||
}
|
||||
|
||||
r = r.WithContext(services.SetUserCtx(r.Context(), &usr, requestToken))
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/hay-kot/homebox/backend/app/api/handlers/debughandlers"
|
||||
v1 "github.com/hay-kot/homebox/backend/app/api/handlers/v1"
|
||||
_ "github.com/hay-kot/homebox/backend/app/api/static/docs"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
"github.com/hay-kot/homebox/backend/pkgs/server"
|
||||
httpSwagger "github.com/swaggo/http-swagger" // http-swagger middleware
|
||||
@@ -51,7 +52,7 @@ func (a *app) mountRoutes(repos *repo.AllRepos) {
|
||||
a.services,
|
||||
a.repos,
|
||||
v1.WithMaxUploadSize(a.conf.Web.MaxUploadSize),
|
||||
v1.WithRegistration(a.conf.AllowRegistration),
|
||||
v1.WithRegistration(a.conf.Options.AllowRegistration),
|
||||
v1.WithDemoStatus(a.conf.Demo), // Disable Password Change in Demo Mode
|
||||
)
|
||||
|
||||
@@ -64,47 +65,88 @@ func (a *app) mountRoutes(repos *repo.AllRepos) {
|
||||
a.server.Post(v1Base("/users/register"), v1Ctrl.HandleUserRegistration())
|
||||
a.server.Post(v1Base("/users/login"), v1Ctrl.HandleAuthLogin())
|
||||
|
||||
// Attachment download URl needs a `token` query param to be passed in the request.
|
||||
// and also needs to be outside of the `auth` middleware.
|
||||
a.server.Get(v1Base("/items/{id}/attachments/download"), v1Ctrl.HandleItemAttachmentDownload())
|
||||
userMW := []server.Middleware{
|
||||
a.mwAuthToken,
|
||||
a.mwRoles(RoleModeOr, authroles.RoleUser.String()),
|
||||
}
|
||||
|
||||
a.server.Get(v1Base("/users/self"), v1Ctrl.HandleUserSelf(), a.mwAuthToken)
|
||||
a.server.Put(v1Base("/users/self"), v1Ctrl.HandleUserSelfUpdate(), a.mwAuthToken)
|
||||
a.server.Delete(v1Base("/users/self"), v1Ctrl.HandleUserSelfDelete(), a.mwAuthToken)
|
||||
a.server.Post(v1Base("/users/logout"), v1Ctrl.HandleAuthLogout(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/users/refresh"), v1Ctrl.HandleAuthRefresh(), a.mwAuthToken)
|
||||
a.server.Put(v1Base("/users/self/change-password"), v1Ctrl.HandleUserSelfChangePassword(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/users/self"), v1Ctrl.HandleUserSelf(), userMW...)
|
||||
a.server.Put(v1Base("/users/self"), v1Ctrl.HandleUserSelfUpdate(), userMW...)
|
||||
a.server.Delete(v1Base("/users/self"), v1Ctrl.HandleUserSelfDelete(), userMW...)
|
||||
a.server.Post(v1Base("/users/logout"), v1Ctrl.HandleAuthLogout(), userMW...)
|
||||
a.server.Get(v1Base("/users/refresh"), v1Ctrl.HandleAuthRefresh(), userMW...)
|
||||
a.server.Put(v1Base("/users/self/change-password"), v1Ctrl.HandleUserSelfChangePassword(), userMW...)
|
||||
|
||||
a.server.Post(v1Base("/groups/invitations"), v1Ctrl.HandleGroupInvitationsCreate(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/groups/statistics"), v1Ctrl.HandleGroupStatistics(), a.mwAuthToken)
|
||||
a.server.Post(v1Base("/groups/invitations"), v1Ctrl.HandleGroupInvitationsCreate(), userMW...)
|
||||
a.server.Get(v1Base("/groups/statistics"), v1Ctrl.HandleGroupStatistics(), userMW...)
|
||||
a.server.Get(v1Base("/groups/statistics/purchase-price"), v1Ctrl.HandleGroupStatisticsPriceOverTime(), userMW...)
|
||||
a.server.Get(v1Base("/groups/statistics/locations"), v1Ctrl.HandleGroupStatisticsLocations(), userMW...)
|
||||
a.server.Get(v1Base("/groups/statistics/labels"), v1Ctrl.HandleGroupStatisticsLabels(), userMW...)
|
||||
|
||||
// TODO: I don't like /groups being the URL for users
|
||||
a.server.Get(v1Base("/groups"), v1Ctrl.HandleGroupGet(), a.mwAuthToken)
|
||||
a.server.Put(v1Base("/groups"), v1Ctrl.HandleGroupUpdate(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/groups"), v1Ctrl.HandleGroupGet(), userMW...)
|
||||
a.server.Put(v1Base("/groups"), v1Ctrl.HandleGroupUpdate(), userMW...)
|
||||
|
||||
a.server.Get(v1Base("/locations"), v1Ctrl.HandleLocationGetAll(), a.mwAuthToken)
|
||||
a.server.Post(v1Base("/locations"), v1Ctrl.HandleLocationCreate(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/locations/{id}"), v1Ctrl.HandleLocationGet(), a.mwAuthToken)
|
||||
a.server.Put(v1Base("/locations/{id}"), v1Ctrl.HandleLocationUpdate(), a.mwAuthToken)
|
||||
a.server.Delete(v1Base("/locations/{id}"), v1Ctrl.HandleLocationDelete(), a.mwAuthToken)
|
||||
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.Post(v1Base("/actions/ensure-import-refs"), v1Ctrl.HandleEnsureImportRefs(), userMW...)
|
||||
|
||||
a.server.Get(v1Base("/labels"), v1Ctrl.HandleLabelsGetAll(), a.mwAuthToken)
|
||||
a.server.Post(v1Base("/labels"), v1Ctrl.HandleLabelsCreate(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/labels/{id}"), v1Ctrl.HandleLabelGet(), a.mwAuthToken)
|
||||
a.server.Put(v1Base("/labels/{id}"), v1Ctrl.HandleLabelUpdate(), a.mwAuthToken)
|
||||
a.server.Delete(v1Base("/labels/{id}"), v1Ctrl.HandleLabelDelete(), a.mwAuthToken)
|
||||
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...)
|
||||
|
||||
a.server.Get(v1Base("/items"), v1Ctrl.HandleItemsGetAll(), a.mwAuthToken)
|
||||
a.server.Post(v1Base("/items/import"), v1Ctrl.HandleItemsImport(), a.mwAuthToken)
|
||||
a.server.Post(v1Base("/items"), v1Ctrl.HandleItemsCreate(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/items/{id}"), v1Ctrl.HandleItemGet(), a.mwAuthToken)
|
||||
a.server.Put(v1Base("/items/{id}"), v1Ctrl.HandleItemUpdate(), a.mwAuthToken)
|
||||
a.server.Delete(v1Base("/items/{id}"), v1Ctrl.HandleItemDelete(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/labels"), v1Ctrl.HandleLabelsGetAll(), userMW...)
|
||||
a.server.Post(v1Base("/labels"), v1Ctrl.HandleLabelsCreate(), userMW...)
|
||||
a.server.Get(v1Base("/labels/{id}"), v1Ctrl.HandleLabelGet(), userMW...)
|
||||
a.server.Put(v1Base("/labels/{id}"), v1Ctrl.HandleLabelUpdate(), userMW...)
|
||||
a.server.Delete(v1Base("/labels/{id}"), v1Ctrl.HandleLabelDelete(), userMW...)
|
||||
|
||||
a.server.Post(v1Base("/items/{id}/attachments"), v1Ctrl.HandleItemAttachmentCreate(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/items/{id}/attachments/{attachment_id}"), v1Ctrl.HandleItemAttachmentToken(), a.mwAuthToken)
|
||||
a.server.Put(v1Base("/items/{id}/attachments/{attachment_id}"), v1Ctrl.HandleItemAttachmentUpdate(), a.mwAuthToken)
|
||||
a.server.Delete(v1Base("/items/{id}/attachments/{attachment_id}"), v1Ctrl.HandleItemAttachmentDelete(), a.mwAuthToken)
|
||||
a.server.Get(v1Base("/items"), v1Ctrl.HandleItemsGetAll(), userMW...)
|
||||
a.server.Post(v1Base("/items"), v1Ctrl.HandleItemsCreate(), userMW...)
|
||||
a.server.Post(v1Base("/items/import"), v1Ctrl.HandleItemsImport(), userMW...)
|
||||
a.server.Get(v1Base("/items/export"), v1Ctrl.HandleItemsExport(), 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...)
|
||||
|
||||
a.server.Post(v1Base("/items/{id}/attachments"), v1Ctrl.HandleItemAttachmentCreate(), userMW...)
|
||||
a.server.Put(v1Base("/items/{id}/attachments/{attachment_id}"), v1Ctrl.HandleItemAttachmentUpdate(), userMW...)
|
||||
a.server.Delete(v1Base("/items/{id}/attachments/{attachment_id}"), v1Ctrl.HandleItemAttachmentDelete(), userMW...)
|
||||
|
||||
a.server.Get(v1Base("/items/{id}/maintenance"), v1Ctrl.HandleMaintenanceEntryCreate(), userMW...)
|
||||
a.server.Post(v1Base("/items/{id}/maintenance"), v1Ctrl.HandleMaintenanceEntryCreate(), userMW...)
|
||||
a.server.Put(v1Base("/items/{id}/maintenance/{entry_id}"), v1Ctrl.HandleMaintenanceEntryUpdate(), userMW...)
|
||||
a.server.Delete(v1Base("/items/{id}/maintenance/{entry_id}"), v1Ctrl.HandleMaintenanceEntryDelete(), userMW...)
|
||||
|
||||
a.server.Get(v1Base("/asset/{id}"), v1Ctrl.HandleAssetGet(), userMW...)
|
||||
|
||||
// Notifiers
|
||||
a.server.Get(v1Base("/notifiers"), v1Ctrl.HandleGetUserNotifiers(), userMW...)
|
||||
a.server.Post(v1Base("/notifiers"), v1Ctrl.HandleCreateNotifier(), userMW...)
|
||||
a.server.Put(v1Base("/notifiers/{id}"), v1Ctrl.HandleUpdateNotifier(), userMW...)
|
||||
a.server.Delete(v1Base("/notifiers/{id}"), v1Ctrl.HandleDeleteNotifier(), userMW...)
|
||||
a.server.Post(v1Base("/notifiers/test"), v1Ctrl.HandlerNotifierTest(), userMW...)
|
||||
|
||||
// Asset-Like endpoints
|
||||
a.server.Get(
|
||||
v1Base("/qrcode"),
|
||||
v1Ctrl.HandleGenerateQRCode(),
|
||||
a.mwAuthToken, a.mwRoles(RoleModeOr, authroles.RoleUser.String(), authroles.RoleAttachments.String()),
|
||||
)
|
||||
a.server.Get(
|
||||
v1Base("/items/{id}/attachments/{attachment_id}"),
|
||||
v1Ctrl.HandleItemAttachmentGet(),
|
||||
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())
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -24,6 +24,8 @@ definitions:
|
||||
type: object
|
||||
repo.GroupStatistics:
|
||||
properties:
|
||||
totalItemPrice:
|
||||
type: number
|
||||
totalItems:
|
||||
type: integer
|
||||
totalLabels:
|
||||
@@ -32,6 +34,8 @@ definitions:
|
||||
type: integer
|
||||
totalUsers:
|
||||
type: integer
|
||||
totalWithWarranty:
|
||||
type: integer
|
||||
type: object
|
||||
repo.GroupUpdate:
|
||||
properties:
|
||||
@@ -89,8 +93,6 @@ definitions:
|
||||
type: integer
|
||||
textValue:
|
||||
type: string
|
||||
timeValue:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
type: object
|
||||
@@ -98,6 +100,9 @@ definitions:
|
||||
properties:
|
||||
archived:
|
||||
type: boolean
|
||||
assetId:
|
||||
example: "0"
|
||||
type: string
|
||||
attachments:
|
||||
items:
|
||||
$ref: '#/definitions/repo.ItemAttachment'
|
||||
@@ -195,6 +200,9 @@ definitions:
|
||||
x-omitempty: true
|
||||
name:
|
||||
type: string
|
||||
purchasePrice:
|
||||
example: "0"
|
||||
type: string
|
||||
quantity:
|
||||
type: integer
|
||||
updatedAt:
|
||||
@@ -204,6 +212,8 @@ definitions:
|
||||
properties:
|
||||
archived:
|
||||
type: boolean
|
||||
assetId:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
fields:
|
||||
@@ -263,6 +273,7 @@ definitions:
|
||||
warrantyDetails:
|
||||
type: string
|
||||
warrantyExpires:
|
||||
description: Sold
|
||||
type: string
|
||||
type: object
|
||||
repo.LabelCreate:
|
||||
@@ -310,6 +321,9 @@ definitions:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
parentId:
|
||||
type: string
|
||||
x-nullable: true
|
||||
type: object
|
||||
repo.LocationOut:
|
||||
properties:
|
||||
@@ -374,6 +388,114 @@ definitions:
|
||||
type: string
|
||||
x-nullable: true
|
||||
type: object
|
||||
repo.MaintenanceEntry:
|
||||
properties:
|
||||
completedDate:
|
||||
description: Sold
|
||||
type: string
|
||||
cost:
|
||||
example: "0"
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
scheduledDate:
|
||||
description: Sold
|
||||
type: string
|
||||
type: object
|
||||
repo.MaintenanceEntryCreate:
|
||||
properties:
|
||||
completedDate:
|
||||
description: Sold
|
||||
type: string
|
||||
cost:
|
||||
example: "0"
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
scheduledDate:
|
||||
description: Sold
|
||||
type: string
|
||||
type: object
|
||||
repo.MaintenanceEntryUpdate:
|
||||
properties:
|
||||
completedDate:
|
||||
description: Sold
|
||||
type: string
|
||||
cost:
|
||||
example: "0"
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
scheduledDate:
|
||||
description: Sold
|
||||
type: string
|
||||
type: object
|
||||
repo.MaintenanceLog:
|
||||
properties:
|
||||
costAverage:
|
||||
type: number
|
||||
costTotal:
|
||||
type: number
|
||||
entries:
|
||||
items:
|
||||
$ref: '#/definitions/repo.MaintenanceEntry'
|
||||
type: array
|
||||
itemId:
|
||||
type: string
|
||||
type: object
|
||||
repo.NotifierCreate:
|
||||
properties:
|
||||
isActive:
|
||||
type: boolean
|
||||
name:
|
||||
maxLength: 255
|
||||
minLength: 1
|
||||
type: string
|
||||
url:
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
- url
|
||||
type: object
|
||||
repo.NotifierOut:
|
||||
properties:
|
||||
createdAt:
|
||||
type: string
|
||||
groupId:
|
||||
type: string
|
||||
id:
|
||||
type: string
|
||||
isActive:
|
||||
type: boolean
|
||||
name:
|
||||
type: string
|
||||
updatedAt:
|
||||
type: string
|
||||
userId:
|
||||
type: string
|
||||
type: object
|
||||
repo.NotifierUpdate:
|
||||
properties:
|
||||
isActive:
|
||||
type: boolean
|
||||
name:
|
||||
maxLength: 255
|
||||
minLength: 1
|
||||
type: string
|
||||
url:
|
||||
type: string
|
||||
x-nullable: true
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
repo.PaginationResult-repo_ItemSummary:
|
||||
properties:
|
||||
items:
|
||||
@@ -387,6 +509,28 @@ definitions:
|
||||
total:
|
||||
type: integer
|
||||
type: object
|
||||
repo.TotalsByOrganizer:
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
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:
|
||||
@@ -411,6 +555,30 @@ definitions:
|
||||
name:
|
||||
type: string
|
||||
type: object
|
||||
repo.ValueOverTime:
|
||||
properties:
|
||||
end:
|
||||
type: string
|
||||
entries:
|
||||
items:
|
||||
$ref: '#/definitions/repo.ValueOverTimeEntry'
|
||||
type: array
|
||||
start:
|
||||
type: string
|
||||
valueAtEnd:
|
||||
type: number
|
||||
valueAtStart:
|
||||
type: number
|
||||
type: object
|
||||
repo.ValueOverTimeEntry:
|
||||
properties:
|
||||
date:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
value:
|
||||
type: number
|
||||
type: object
|
||||
server.ErrorResponse:
|
||||
properties:
|
||||
error:
|
||||
@@ -444,8 +612,15 @@ definitions:
|
||||
token:
|
||||
type: string
|
||||
type: object
|
||||
v1.ActionAmountResult:
|
||||
properties:
|
||||
completed:
|
||||
type: integer
|
||||
type: object
|
||||
v1.ApiSummary:
|
||||
properties:
|
||||
allowRegistration:
|
||||
type: boolean
|
||||
build:
|
||||
$ref: '#/definitions/v1.Build'
|
||||
demo:
|
||||
@@ -500,6 +675,8 @@ definitions:
|
||||
type: object
|
||||
v1.TokenResponse:
|
||||
properties:
|
||||
attachmentToken:
|
||||
type: string
|
||||
expiresAt:
|
||||
type: string
|
||||
token:
|
||||
@@ -508,14 +685,77 @@ definitions:
|
||||
info:
|
||||
contact:
|
||||
name: Don't
|
||||
description: This is a simple Rest API Server Template that implements some basic
|
||||
User and Authentication patterns to help you get started and bootstrap your next
|
||||
project!.
|
||||
description: Track, Manage, and Organize your Shit.
|
||||
license:
|
||||
name: MIT
|
||||
title: Go API Templates
|
||||
title: Homebox API
|
||||
version: "1.0"
|
||||
paths:
|
||||
/v1/actions/ensure-asset-ids:
|
||||
post:
|
||||
description: Ensures all items in the database have an asset ID
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/v1.ActionAmountResult'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Ensure Asset IDs
|
||||
tags:
|
||||
- Actions
|
||||
/v1/actions/ensure-import-refs:
|
||||
post:
|
||||
description: Ensures all items in the database have an import ref
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/v1.ActionAmountResult'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Ensures Import Refs
|
||||
tags:
|
||||
- Actions
|
||||
/v1/actions/zero-item-time-fields:
|
||||
post:
|
||||
description: Resets all item date fields to the beginning of the day
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/v1.ActionAmountResult'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Zero Out Time Fields
|
||||
tags:
|
||||
- Actions
|
||||
/v1/assets/{id}:
|
||||
get:
|
||||
parameters:
|
||||
- description: Asset ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/repo.PaginationResult-repo_ItemSummary'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Get Item by Asset ID
|
||||
tags:
|
||||
- Items
|
||||
/v1/groups:
|
||||
get:
|
||||
produces:
|
||||
@@ -527,7 +767,7 @@ paths:
|
||||
$ref: '#/definitions/repo.Group'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Get the current user's group
|
||||
summary: Get Group
|
||||
tags:
|
||||
- Group
|
||||
put:
|
||||
@@ -547,7 +787,7 @@ paths:
|
||||
$ref: '#/definitions/repo.Group'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Updates some fields of the current users group
|
||||
summary: Update Group
|
||||
tags:
|
||||
- Group
|
||||
/v1/groups/invitations:
|
||||
@@ -568,7 +808,7 @@ paths:
|
||||
$ref: '#/definitions/v1.GroupInvitation'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Get the current user
|
||||
summary: Create Group Invitation
|
||||
tags:
|
||||
- Group
|
||||
/v1/groups/statistics:
|
||||
@@ -582,9 +822,64 @@ paths:
|
||||
$ref: '#/definitions/repo.GroupStatistics'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Get the current user's group
|
||||
summary: Get Group Statistics
|
||||
tags:
|
||||
- Group
|
||||
- Statistics
|
||||
/v1/groups/statistics/labels:
|
||||
get:
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/definitions/repo.TotalsByOrganizer'
|
||||
type: array
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Get Label Statistics
|
||||
tags:
|
||||
- Statistics
|
||||
/v1/groups/statistics/locations:
|
||||
get:
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
items:
|
||||
$ref: '#/definitions/repo.TotalsByOrganizer'
|
||||
type: array
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Get Location Statistics
|
||||
tags:
|
||||
- Statistics
|
||||
/v1/groups/statistics/purchase-price:
|
||||
get:
|
||||
parameters:
|
||||
- description: start date
|
||||
in: query
|
||||
name: start
|
||||
type: string
|
||||
- description: end date
|
||||
in: query
|
||||
name: end
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/repo.ValueOverTime'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Get Purchase Price Statistics
|
||||
tags:
|
||||
- Statistics
|
||||
/v1/items:
|
||||
get:
|
||||
parameters:
|
||||
@@ -623,7 +918,7 @@ paths:
|
||||
$ref: '#/definitions/repo.PaginationResult-repo_ItemSummary'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Get All Items
|
||||
summary: Query All Items
|
||||
tags:
|
||||
- Items
|
||||
post:
|
||||
@@ -643,7 +938,7 @@ paths:
|
||||
$ref: '#/definitions/repo.ItemSummary'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Create a new item
|
||||
summary: Create Item
|
||||
tags:
|
||||
- Items
|
||||
/v1/items/{id}:
|
||||
@@ -661,7 +956,7 @@ paths:
|
||||
description: No Content
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: deletes a item
|
||||
summary: Delete Item
|
||||
tags:
|
||||
- Items
|
||||
get:
|
||||
@@ -680,7 +975,7 @@ paths:
|
||||
$ref: '#/definitions/repo.ItemOut'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Gets a item and fields
|
||||
summary: Get Item
|
||||
tags:
|
||||
- Items
|
||||
put:
|
||||
@@ -705,7 +1000,7 @@ paths:
|
||||
$ref: '#/definitions/repo.ItemOut'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: updates a item
|
||||
summary: Update Item
|
||||
tags:
|
||||
- Items
|
||||
/v1/items/{id}/attachments:
|
||||
@@ -744,7 +1039,7 @@ paths:
|
||||
$ref: '#/definitions/server.ErrorResponse'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: imports items into the database
|
||||
summary: Create Item Attachment
|
||||
tags:
|
||||
- Items Attachments
|
||||
/v1/items/{id}/attachments/{attachment_id}:
|
||||
@@ -765,7 +1060,7 @@ paths:
|
||||
description: No Content
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: retrieves an attachment for an item
|
||||
summary: Delete Item Attachment
|
||||
tags:
|
||||
- Items Attachments
|
||||
get:
|
||||
@@ -789,7 +1084,7 @@ paths:
|
||||
$ref: '#/definitions/v1.ItemAttachmentToken'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: retrieves an attachment for an item
|
||||
summary: Get Item Attachment
|
||||
tags:
|
||||
- Items Attachments
|
||||
put:
|
||||
@@ -817,32 +1112,119 @@ paths:
|
||||
$ref: '#/definitions/repo.ItemOut'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: retrieves an attachment for an item
|
||||
summary: Update Item Attachment
|
||||
tags:
|
||||
- Items Attachments
|
||||
/v1/items/{id}/attachments/download:
|
||||
/v1/items/{id}/maintenance:
|
||||
get:
|
||||
parameters:
|
||||
- description: Item ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
- description: Attachment token
|
||||
in: query
|
||||
name: token
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/octet-stream
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/repo.MaintenanceLog'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: retrieves an attachment for an item
|
||||
summary: Get Maintenance Log
|
||||
tags:
|
||||
- Items Attachments
|
||||
- Maintenance
|
||||
post:
|
||||
parameters:
|
||||
- description: Entry Data
|
||||
in: body
|
||||
name: payload
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/repo.MaintenanceEntryCreate'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/repo.MaintenanceEntry'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Create Maintenance Entry
|
||||
tags:
|
||||
- Maintenance
|
||||
/v1/items/{id}/maintenance/{entry_id}:
|
||||
delete:
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Delete Maintenance Entry
|
||||
tags:
|
||||
- Maintenance
|
||||
put:
|
||||
parameters:
|
||||
- description: Entry Data
|
||||
in: body
|
||||
name: payload
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/repo.MaintenanceEntryUpdate'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/repo.MaintenanceEntry'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Update Maintenance Entry
|
||||
tags:
|
||||
- Maintenance
|
||||
/v1/items/export:
|
||||
get:
|
||||
responses:
|
||||
"200":
|
||||
description: text/csv
|
||||
schema:
|
||||
type: string
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Export Items
|
||||
tags:
|
||||
- Items
|
||||
/v1/items/fields:
|
||||
get:
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Get All Custom Field Names
|
||||
tags:
|
||||
- Items
|
||||
/v1/items/fields/values:
|
||||
get:
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Get All Custom Field Values
|
||||
tags:
|
||||
- Items
|
||||
/v1/items/import:
|
||||
post:
|
||||
parameters:
|
||||
@@ -858,7 +1240,7 @@ paths:
|
||||
description: No Content
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: imports items into the database
|
||||
summary: Import Items
|
||||
tags:
|
||||
- Items
|
||||
/v1/labels:
|
||||
@@ -899,7 +1281,7 @@ paths:
|
||||
$ref: '#/definitions/repo.LabelSummary'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Create a new label
|
||||
summary: Create Label
|
||||
tags:
|
||||
- Labels
|
||||
/v1/labels/{id}:
|
||||
@@ -917,7 +1299,7 @@ paths:
|
||||
description: No Content
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: deletes a label
|
||||
summary: Delete Label
|
||||
tags:
|
||||
- Labels
|
||||
get:
|
||||
@@ -936,7 +1318,7 @@ paths:
|
||||
$ref: '#/definitions/repo.LabelOut'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Gets a label and fields
|
||||
summary: Get Label
|
||||
tags:
|
||||
- Labels
|
||||
put:
|
||||
@@ -955,7 +1337,7 @@ paths:
|
||||
$ref: '#/definitions/repo.LabelOut'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: updates a label
|
||||
summary: Update Label
|
||||
tags:
|
||||
- Labels
|
||||
/v1/locations:
|
||||
@@ -1001,7 +1383,7 @@ paths:
|
||||
$ref: '#/definitions/repo.LocationSummary'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Create a new location
|
||||
summary: Create Location
|
||||
tags:
|
||||
- Locations
|
||||
/v1/locations/{id}:
|
||||
@@ -1019,7 +1401,7 @@ paths:
|
||||
description: No Content
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: deletes a location
|
||||
summary: Delete Location
|
||||
tags:
|
||||
- Locations
|
||||
get:
|
||||
@@ -1038,7 +1420,7 @@ paths:
|
||||
$ref: '#/definitions/repo.LocationOut'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Gets a location and fields
|
||||
summary: Get Location
|
||||
tags:
|
||||
- Locations
|
||||
put:
|
||||
@@ -1063,9 +1445,171 @@ paths:
|
||||
$ref: '#/definitions/repo.LocationOut'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: updates a location
|
||||
summary: Update 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 Locations Tree
|
||||
tags:
|
||||
- Locations
|
||||
/v1/notifiers:
|
||||
get:
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
allOf:
|
||||
- $ref: '#/definitions/server.Results'
|
||||
- properties:
|
||||
items:
|
||||
items:
|
||||
$ref: '#/definitions/repo.NotifierOut'
|
||||
type: array
|
||||
type: object
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Get Notifiers
|
||||
tags:
|
||||
- Notifiers
|
||||
post:
|
||||
parameters:
|
||||
- description: Notifier Data
|
||||
in: body
|
||||
name: payload
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/repo.NotifierCreate'
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/repo.NotifierOut'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Create Notifier
|
||||
tags:
|
||||
- Notifiers
|
||||
/v1/notifiers/{id}:
|
||||
delete:
|
||||
parameters:
|
||||
- description: Notifier ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Delete a Notifier
|
||||
tags:
|
||||
- Notifiers
|
||||
put:
|
||||
parameters:
|
||||
- description: Notifier ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
- description: Notifier Data
|
||||
in: body
|
||||
name: payload
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/repo.NotifierUpdate'
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/repo.NotifierOut'
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Update Notifier
|
||||
tags:
|
||||
- Notifiers
|
||||
/v1/notifiers/test:
|
||||
post:
|
||||
parameters:
|
||||
- description: Notifier ID
|
||||
in: path
|
||||
name: id
|
||||
required: true
|
||||
type: string
|
||||
- description: URL
|
||||
in: query
|
||||
name: url
|
||||
required: true
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Test Notifier
|
||||
tags:
|
||||
- Notifiers
|
||||
/v1/qrcode:
|
||||
get:
|
||||
parameters:
|
||||
- description: data to be encoded into qrcode
|
||||
in: query
|
||||
name: data
|
||||
type: string
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: image/jpeg
|
||||
schema:
|
||||
type: string
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Create QR Code
|
||||
tags:
|
||||
- Items
|
||||
/v1/reporting/bill-of-materials:
|
||||
get:
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: text/csv
|
||||
schema:
|
||||
type: string
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Export Bill of Materials
|
||||
tags:
|
||||
- Reporting
|
||||
/v1/status:
|
||||
get:
|
||||
produces:
|
||||
@@ -1075,7 +1619,7 @@ paths:
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/v1.ApiSummary'
|
||||
summary: Retrieves the basic information about the API
|
||||
summary: Application Info
|
||||
tags:
|
||||
- Base
|
||||
/v1/users/change-password:
|
||||
@@ -1092,7 +1636,7 @@ paths:
|
||||
description: No Content
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Updates the users password
|
||||
summary: Change Password
|
||||
tags:
|
||||
- User
|
||||
/v1/users/login:
|
||||
@@ -1158,7 +1702,7 @@ paths:
|
||||
responses:
|
||||
"204":
|
||||
description: No Content
|
||||
summary: Get the current user
|
||||
summary: Register New User
|
||||
tags:
|
||||
- User
|
||||
/v1/users/self:
|
||||
@@ -1170,7 +1714,7 @@ paths:
|
||||
description: No Content
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Deletes the user account
|
||||
summary: Delete Account
|
||||
tags:
|
||||
- User
|
||||
get:
|
||||
@@ -1188,7 +1732,7 @@ paths:
|
||||
type: object
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Get the current user
|
||||
summary: Get User Self
|
||||
tags:
|
||||
- User
|
||||
put:
|
||||
@@ -1213,7 +1757,7 @@ paths:
|
||||
type: object
|
||||
security:
|
||||
- Bearer: []
|
||||
summary: Update the current user
|
||||
summary: Update Account
|
||||
tags:
|
||||
- User
|
||||
securityDefinitions:
|
||||
|
||||
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
@@ -39,4 +40,6 @@ func main() {
|
||||
if err != nil {
|
||||
log.Fatalf("failed generating migration file: %v", err)
|
||||
}
|
||||
|
||||
fmt.Println("Migration file generated successfully.")
|
||||
}
|
||||
|
||||
@@ -3,18 +3,23 @@ module github.com/hay-kot/homebox/backend
|
||||
go 1.19
|
||||
|
||||
require (
|
||||
ariga.io/atlas v0.7.2-0.20220927111110-867ee0cca56a
|
||||
entgo.io/ent v0.11.3
|
||||
github.com/ardanlabs/conf/v2 v2.2.0
|
||||
github.com/go-chi/chi/v5 v5.0.7
|
||||
github.com/go-playground/validator/v10 v10.11.1
|
||||
ariga.io/atlas v0.9.1-0.20230119145809-92243f7c55cb
|
||||
entgo.io/ent v0.11.8
|
||||
github.com/ardanlabs/conf/v3 v3.1.4
|
||||
github.com/containrrr/shoutrrr v0.7.1
|
||||
github.com/go-chi/chi/v5 v5.0.8
|
||||
github.com/go-playground/validator/v10 v10.11.2
|
||||
github.com/gocarina/gocsv v0.0.0-20230219202803-bcce7dc8d0bb
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/gorilla/schema v1.2.0
|
||||
github.com/mattn/go-sqlite3 v1.14.16
|
||||
github.com/rs/zerolog v1.28.0
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/rs/zerolog v1.29.0
|
||||
github.com/stretchr/testify v1.8.2
|
||||
github.com/swaggo/http-swagger v1.3.3
|
||||
github.com/swaggo/swag v1.8.7
|
||||
golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90
|
||||
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.7.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -22,28 +27,34 @@ require (
|
||||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/fatih/color v1.13.0 // indirect
|
||||
github.com/fogleman/gg v1.3.0 // indirect
|
||||
github.com/go-openapi/inflect v0.19.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
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.14.1 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.15.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.16 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/swaggo/files v0.0.0-20220728132757-551d4a08d97a // indirect
|
||||
github.com/zclconf/go-cty v1.11.0 // indirect
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
|
||||
golang.org/x/net v0.0.0-20220923203811-8be639271d50 // indirect
|
||||
golang.org/x/sys v0.0.0-20220919091848-fb04ddd9f9c8 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/tools v0.1.13-0.20220804200503-81c7dc4e4efa // indirect
|
||||
github.com/swaggo/files v1.0.0 // indirect
|
||||
github.com/yeqown/reedsolomon v1.0.0 // indirect
|
||||
github.com/zclconf/go-cty v1.12.1 // indirect
|
||||
golang.org/x/image v0.0.0-20200927104501-e162460cd6b5 // indirect
|
||||
golang.org/x/mod v0.8.0 // indirect
|
||||
golang.org/x/net v0.8.0 // indirect
|
||||
golang.org/x/sys v0.6.0 // indirect
|
||||
golang.org/x/text v0.8.0 // indirect
|
||||
golang.org/x/tools v0.6.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
1183
backend/go.sum
1183
backend/go.sum
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,8 @@
|
||||
package services
|
||||
|
||||
import "github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
import (
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
)
|
||||
|
||||
type AllServices struct {
|
||||
User *UserService
|
||||
@@ -8,17 +10,37 @@ type AllServices struct {
|
||||
Items *ItemService
|
||||
}
|
||||
|
||||
func New(repos *repo.AllRepos) *AllServices {
|
||||
type OptionsFunc func(*options)
|
||||
|
||||
type options struct {
|
||||
autoIncrementAssetID bool
|
||||
}
|
||||
|
||||
func WithAutoIncrementAssetID(v bool) func(*options) {
|
||||
return func(o *options) {
|
||||
o.autoIncrementAssetID = v
|
||||
}
|
||||
}
|
||||
|
||||
func New(repos *repo.AllRepos, opts ...OptionsFunc) *AllServices {
|
||||
if repos == nil {
|
||||
panic("repos cannot be nil")
|
||||
}
|
||||
|
||||
options := &options{
|
||||
autoIncrementAssetID: true,
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(options)
|
||||
}
|
||||
|
||||
return &AllServices{
|
||||
User: &UserService{repos},
|
||||
Group: &GroupService{repos},
|
||||
Items: &ItemService{
|
||||
repo: repos,
|
||||
at: attachmentTokens{},
|
||||
repo: repos,
|
||||
autoIncrementAssetID: options.autoIncrementAssetID,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
Import Ref,Location,Labels,Quantity,Name,Description,Insured,Serial Number,Mode Number,Manufacturer,Notes,Purchase From,Purchased Price,Purchased Time,Lifetime Warranty,Warranty Expires,Warranty Details,Sold To,Sold Price,Sold Time,Sold Notes
|
||||
A,Garage,IOT;Home Assistant; Z-Wave,1,Zooz Universal Relay ZEN17,Description 1,TRUE,,ZEN17,Zooz,,Amazon,39.95,10/13/2021,,10/13/2021,,,,10/13/2021,
|
||||
B,Living Room,IOT;Home Assistant; Z-Wave,1,Zooz Motion Sensor,Description 2,FALSE,,ZSE18,Zooz,,Amazon,29.95,10/15/2021,,10/15/2021,,,,10/15/2021,
|
||||
C,Office,IOT;Home Assistant; Z-Wave,1,Zooz 110v Power Switch,Description 3,TRUE,,ZEN15,Zooz,,Amazon,39.95,10/13/2021,,10/13/2021,,,,10/13/2021,
|
||||
D,Downstairs,IOT;Home Assistant; Z-Wave,1,Ecolink Z-Wave PIR Motion Sensor,Description 4,FALSE,,PIRZWAVE2.5-ECO,Ecolink,,Amazon,35.58,10/21/2020,,10/21/2020,,,,10/21/2020,
|
||||
E,Entry,IOT;Home Assistant; Z-Wave,1,Yale Security Touchscreen Deadbolt,Description 5,TRUE,,YRD226ZW2619,Yale,,Amazon,120.39,10/14/2020,,10/14/2020,,,,10/14/2020,
|
||||
F,Kitchen,IOT;Home Assistant; Z-Wave,1,Smart Rocker Light Dimmer,Description 6,FALSE,,39351,Honeywell,,Amazon,65.98,09/30/2020,,09/30/2020,,,,09/30/2020,
|
||||
|
@@ -0,0 +1,7 @@
|
||||
Import Ref Location Labels Quantity Name Description Insured Serial Number Mode Number Manufacturer Notes Purchase From Purchased Price Purchased Time Lifetime Warranty Warranty Expires Warranty Details Sold To Sold Price Sold Time Sold Notes
|
||||
A Garage IOT;Home Assistant; Z-Wave 1 Zooz Universal Relay ZEN17 Description 1 TRUE ZEN17 Zooz Amazon 39.95 10/13/2021 10/13/2021 10/13/2021
|
||||
B Living Room IOT;Home Assistant; Z-Wave 1 Zooz Motion Sensor Description 2 FALSE ZSE18 Zooz Amazon 29.95 10/15/2021 10/15/2021 10/15/2021
|
||||
C Office IOT;Home Assistant; Z-Wave 1 Zooz 110v Power Switch Description 3 TRUE ZEN15 Zooz Amazon 39.95 10/13/2021 10/13/2021 10/13/2021
|
||||
D Downstairs IOT;Home Assistant; Z-Wave 1 Ecolink Z-Wave PIR Motion Sensor Description 4 FALSE PIRZWAVE2.5-ECO Ecolink Amazon 35.58 10/21/2020 10/21/2020 10/21/2020
|
||||
E Entry IOT;Home Assistant; Z-Wave 1 Yale Security Touchscreen Deadbolt Description 5 TRUE YRD226ZW2619 Yale Amazon 120.39 10/14/2020 10/14/2020 10/14/2020
|
||||
F Kitchen IOT;Home Assistant; Z-Wave 1 Smart Rocker Light Dimmer Description 6 FALSE 39351 Honeywell Amazon 65.98 09/30/2020 09/30/2020 09/30/2020
|
||||
|
@@ -0,0 +1,5 @@
|
||||
HB.location,HB.name,HB.quantity,HB.description,HB.field.Custom Field 1,HB.field.Custom Field 2,HB.field.Custom Field 3
|
||||
loc,Item 1,1,Description 1,Value 1[1],Value 1[2],Value 1[3]
|
||||
loc,Item 2,2,Description 2,Value 2[1],Value 2[2],Value 2[3]
|
||||
loc,Item 3,3,Description 3,Value 3[1],Value 3[2],Value 3[3]
|
||||
|
||||
|
@@ -0,0 +1,4 @@
|
||||
HB.location,HB.name,HB.quantity,HB.description
|
||||
loc,Item 1,1,Description 1
|
||||
loc,Item 2,2,Description 2
|
||||
loc,Item 3,3,Description 3
|
||||
|
@@ -0,0 +1,4 @@
|
||||
HB.name,HB.asset_id,HB.location,HB.labels
|
||||
Item 1,1,Path / To / Location 1,L1 ; L2 ; L3
|
||||
Item 2,000-002,Path /To/ Location 2,L1;L2;L3
|
||||
Item 3,1000-003,Path / To /Location 3 , L1;L2; L3
|
||||
|
@@ -0,0 +1,42 @@
|
||||
package reporting
|
||||
|
||||
import (
|
||||
"github.com/gocarina/gocsv"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/types"
|
||||
)
|
||||
|
||||
// =================================================================================================
|
||||
|
||||
type BillOfMaterialsEntry struct {
|
||||
PurchaseDate types.Date `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 BillOfMaterialsTSV(entities []repo.ItemOut) ([]byte, error) {
|
||||
bomEntries := make([]BillOfMaterialsEntry, len(entities))
|
||||
for i, entity := range entities {
|
||||
bomEntries[i] = BillOfMaterialsEntry{
|
||||
PurchaseDate: 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)
|
||||
}
|
||||
93
backend/internal/core/services/reporting/import.go
Normal file
93
backend/internal/core/services/reporting/import.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package reporting
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/csv"
|
||||
"errors"
|
||||
"io"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrNoHomeboxHeaders = errors.New("no headers found")
|
||||
ErrMissingRequiredHeaders = errors.New("missing required headers `HB.location` or `HB.name`")
|
||||
)
|
||||
|
||||
// determineSeparator determines the separator used in the CSV file
|
||||
// It returns the separator as a rune and an error if it could not be determined
|
||||
//
|
||||
// It is assumed that the first row is the header row and that the separator is the same
|
||||
// for all rows.
|
||||
//
|
||||
// Supported separators are `,` and `\t`
|
||||
func determineSeparator(data []byte) (rune, error) {
|
||||
// First row
|
||||
firstRow := bytes.Split(data, []byte("\n"))[0]
|
||||
|
||||
// find first comma or /t
|
||||
comma := bytes.IndexByte(firstRow, ',')
|
||||
tab := bytes.IndexByte(firstRow, '\t')
|
||||
|
||||
switch {
|
||||
case comma == -1 && tab == -1:
|
||||
return 0, errors.New("could not determine separator")
|
||||
case tab > comma:
|
||||
return '\t', nil
|
||||
default:
|
||||
return ',', nil
|
||||
}
|
||||
}
|
||||
|
||||
// readRawCsv reads a CSV file and returns the raw data as a 2D string array
|
||||
// It determines the separator used in the CSV file and returns an error if
|
||||
// it could not be determined
|
||||
func readRawCsv(r io.Reader) ([][]string, error) {
|
||||
data, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reader := csv.NewReader(bytes.NewReader(data))
|
||||
|
||||
// Determine separator
|
||||
sep, err := determineSeparator(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
reader.Comma = sep
|
||||
|
||||
return reader.ReadAll()
|
||||
}
|
||||
|
||||
// parseHeaders parses the homebox headers from the CSV file and returns a map of the headers
|
||||
// and their column index as well as a list of the field headers (HB.field.*) in the order
|
||||
// they appear in the CSV file
|
||||
//
|
||||
// It returns an error if no homebox headers are found
|
||||
func parseHeaders(headers []string) (hbHeaders map[string]int, fieldHeaders []string, err error) {
|
||||
hbHeaders = map[string]int{} // initialize map
|
||||
|
||||
for col, h := range headers {
|
||||
if strings.HasPrefix(h, "HB.field.") {
|
||||
fieldHeaders = append(fieldHeaders, h)
|
||||
}
|
||||
|
||||
if strings.HasPrefix(h, "HB.") {
|
||||
hbHeaders[h] = col
|
||||
}
|
||||
}
|
||||
|
||||
required := []string{"HB.location", "HB.name"}
|
||||
for _, h := range required {
|
||||
if _, ok := hbHeaders[h]; !ok {
|
||||
return nil, nil, ErrMissingRequiredHeaders
|
||||
}
|
||||
}
|
||||
|
||||
if len(hbHeaders) == 0 {
|
||||
return nil, nil, ErrNoHomeboxHeaders
|
||||
}
|
||||
|
||||
return hbHeaders, fieldHeaders, nil
|
||||
}
|
||||
85
backend/internal/core/services/reporting/io_row.go
Normal file
85
backend/internal/core/services/reporting/io_row.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package reporting
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/types"
|
||||
)
|
||||
|
||||
type ExportItemFields struct {
|
||||
Name string
|
||||
Value string
|
||||
}
|
||||
|
||||
type ExportTSVRow struct {
|
||||
ImportRef string `csv:"HB.import_ref"`
|
||||
Location LocationString `csv:"HB.location"`
|
||||
LabelStr LabelString `csv:"HB.labels"`
|
||||
AssetID repo.AssetID `csv:"HB.asset_id"`
|
||||
Archived bool `csv:"HB.archived"`
|
||||
|
||||
Name string `csv:"HB.name"`
|
||||
Quantity int `csv:"HB.quantity"`
|
||||
Description string `csv:"HB.description"`
|
||||
Insured bool `csv:"HB.insured"`
|
||||
Notes string `csv:"HB.notes"`
|
||||
|
||||
PurchasePrice float64 `csv:"HB.purchase_price"`
|
||||
PurchaseFrom string `csv:"HB.purchase_from"`
|
||||
PurchaseTime types.Date `csv:"HB.purchase_time"`
|
||||
|
||||
Manufacturer string `csv:"HB.manufacturer"`
|
||||
ModelNumber string `csv:"HB.model_number"`
|
||||
SerialNumber string `csv:"HB.serial_number"`
|
||||
|
||||
LifetimeWarranty bool `csv:"HB.lifetime_warranty"`
|
||||
WarrantyExpires types.Date `csv:"HB.warranty_expires"`
|
||||
WarrantyDetails string `csv:"HB.warranty_details"`
|
||||
|
||||
SoldTo string `csv:"HB.sold_to"`
|
||||
SoldPrice float64 `csv:"HB.sold_price"`
|
||||
SoldTime types.Date `csv:"HB.sold_time"`
|
||||
SoldNotes string `csv:"HB.sold_notes"`
|
||||
|
||||
Fields []ExportItemFields `csv:"-"`
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
// LabelString is a string slice that is used to represent a list of labels.
|
||||
//
|
||||
// For example, a list of labels "Important; Work" would be represented as a
|
||||
// LabelString with the following values:
|
||||
//
|
||||
// LabelString{"Important", "Work"}
|
||||
type LabelString []string
|
||||
|
||||
func parseLabelString(s string) LabelString {
|
||||
v, _ := parseSeparatedString(s, ";")
|
||||
return v
|
||||
}
|
||||
|
||||
func (ls LabelString) String() string {
|
||||
return strings.Join(ls, "; ")
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
|
||||
// LocationString is a string slice that is used to represent a location
|
||||
// hierarchy.
|
||||
//
|
||||
// For example, a location hierarchy of "Home / Bedroom / Desk" would be
|
||||
// represented as a LocationString with the following values:
|
||||
//
|
||||
// LocationString{"Home", "Bedroom", "Desk"}
|
||||
type LocationString []string
|
||||
|
||||
func parseLocationString(s string) LocationString {
|
||||
v, _ := parseSeparatedString(s, "/")
|
||||
return v
|
||||
}
|
||||
|
||||
func (csf LocationString) String() string {
|
||||
return strings.Join(csf, " / ")
|
||||
}
|
||||
310
backend/internal/core/services/reporting/io_sheet.go
Normal file
310
backend/internal/core/services/reporting/io_sheet.go
Normal file
@@ -0,0 +1,310 @@
|
||||
package reporting
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/types"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// IOSheet is the representation of a CSV/TSV sheet that is used for importing/exporting
|
||||
// items from homebox. It is used to read/write the data from/to a CSV/TSV file given
|
||||
// the standard format of the file.
|
||||
//
|
||||
// See ExportTSVRow for the format of the data in the sheet.
|
||||
type IOSheet struct {
|
||||
headers []string
|
||||
custom []int
|
||||
index map[string]int
|
||||
Rows []ExportTSVRow
|
||||
}
|
||||
|
||||
func (s *IOSheet) indexHeaders() {
|
||||
s.index = make(map[string]int)
|
||||
|
||||
for i, h := range s.headers {
|
||||
if strings.HasPrefix(h, "HB.field") {
|
||||
s.custom = append(s.custom, i)
|
||||
}
|
||||
|
||||
if strings.HasPrefix(h, "HB.") {
|
||||
s.index[h] = i
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *IOSheet) GetColumn(str string) (col int, ok bool) {
|
||||
if s.index == nil {
|
||||
s.indexHeaders()
|
||||
}
|
||||
|
||||
col, ok = s.index[str]
|
||||
return
|
||||
}
|
||||
|
||||
// Read reads a CSV/TSV and populates the "Rows" field with the data from the sheet
|
||||
// Custom Fields are supported via the `HB.field.*` headers. The `HB.field.*` the "Name"
|
||||
// of the field is the part after the `HB.field.` prefix. Additionally, Custom Fields with
|
||||
// no value are excluded from the row.Fields slice, this includes empty strings.
|
||||
//
|
||||
// Note That
|
||||
// - the first row is assumed to be the header
|
||||
// - at least 1 row of data is required
|
||||
// - rows and columns must be rectangular (i.e. all rows must have the same number of columns)
|
||||
func (s *IOSheet) Read(data io.Reader) error {
|
||||
sheet, err := readRawCsv(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(sheet) < 2 {
|
||||
return fmt.Errorf("sheet must have at least 1 row of data (header + 1)")
|
||||
}
|
||||
|
||||
s.headers = sheet[0]
|
||||
s.Rows = make([]ExportTSVRow, len(sheet)-1)
|
||||
|
||||
for i, row := range sheet[1:] {
|
||||
if len(row) != len(s.headers) {
|
||||
return fmt.Errorf("row has %d columns, expected %d", len(row), len(s.headers))
|
||||
}
|
||||
|
||||
rowData := ExportTSVRow{}
|
||||
|
||||
st := reflect.TypeOf(ExportTSVRow{})
|
||||
|
||||
for i := 0; i < st.NumField(); i++ {
|
||||
field := st.Field(i)
|
||||
tag := field.Tag.Get("csv")
|
||||
if tag == "" || tag == "-" {
|
||||
continue
|
||||
}
|
||||
|
||||
col, ok := s.GetColumn(tag)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
val := row[col]
|
||||
|
||||
var v interface{}
|
||||
|
||||
switch field.Type {
|
||||
case reflect.TypeOf(""):
|
||||
v = val
|
||||
case reflect.TypeOf(int(0)):
|
||||
v = parseInt(val)
|
||||
case reflect.TypeOf(bool(false)):
|
||||
v = parseBool(val)
|
||||
case reflect.TypeOf(float64(0)):
|
||||
v = parseFloat(val)
|
||||
|
||||
// Custom Types
|
||||
case reflect.TypeOf(types.Date{}):
|
||||
v = types.DateFromString(val)
|
||||
case reflect.TypeOf(repo.AssetID(0)):
|
||||
v, _ = repo.ParseAssetID(val)
|
||||
case reflect.TypeOf(LocationString{}):
|
||||
v = parseLocationString(val)
|
||||
case reflect.TypeOf(LabelString{}):
|
||||
v = parseLabelString(val)
|
||||
}
|
||||
|
||||
log.Debug().
|
||||
Str("tag", tag).
|
||||
Interface("val", v).
|
||||
Str("type", fmt.Sprintf("%T", v)).
|
||||
Msg("parsed value")
|
||||
|
||||
// Nil values are not allowed at the moment. This may change.
|
||||
if v == nil {
|
||||
return fmt.Errorf("could not convert %q to %s", val, field.Type)
|
||||
}
|
||||
|
||||
ptrField := reflect.ValueOf(&rowData).Elem().Field(i)
|
||||
ptrField.Set(reflect.ValueOf(v))
|
||||
}
|
||||
|
||||
for _, col := range s.custom {
|
||||
colName := strings.TrimPrefix(s.headers[col], "HB.field.")
|
||||
customVal := row[col]
|
||||
if customVal == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
rowData.Fields = append(rowData.Fields, ExportItemFields{
|
||||
Name: colName,
|
||||
Value: customVal,
|
||||
})
|
||||
}
|
||||
|
||||
s.Rows[i] = rowData
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Write writes the sheet to a writer.
|
||||
func (s *IOSheet) ReadItems(items []repo.ItemOut) {
|
||||
s.Rows = make([]ExportTSVRow, len(items))
|
||||
|
||||
extraHeaders := map[string]struct{}{}
|
||||
|
||||
for i := range items {
|
||||
item := items[i]
|
||||
|
||||
// TODO: Support fetching nested locations
|
||||
locString := LocationString{item.Location.Name}
|
||||
|
||||
labelString := make([]string, len(item.Labels))
|
||||
|
||||
for i, l := range item.Labels {
|
||||
labelString[i] = l.Name
|
||||
}
|
||||
|
||||
customFields := make([]ExportItemFields, len(item.Fields))
|
||||
|
||||
for i, f := range item.Fields {
|
||||
extraHeaders[f.Name] = struct{}{}
|
||||
|
||||
customFields[i] = ExportItemFields{
|
||||
Name: f.Name,
|
||||
Value: f.TextValue,
|
||||
}
|
||||
}
|
||||
|
||||
s.Rows[i] = ExportTSVRow{
|
||||
// fill struct
|
||||
Location: locString,
|
||||
LabelStr: labelString,
|
||||
|
||||
ImportRef: item.ImportRef,
|
||||
AssetID: item.AssetID,
|
||||
Name: item.Name,
|
||||
Quantity: item.Quantity,
|
||||
Description: item.Description,
|
||||
Insured: item.Insured,
|
||||
Archived: item.Archived,
|
||||
|
||||
PurchasePrice: item.PurchasePrice,
|
||||
PurchaseFrom: item.PurchaseFrom,
|
||||
PurchaseTime: item.PurchaseTime,
|
||||
|
||||
Manufacturer: item.Manufacturer,
|
||||
ModelNumber: item.ModelNumber,
|
||||
SerialNumber: item.SerialNumber,
|
||||
|
||||
LifetimeWarranty: item.LifetimeWarranty,
|
||||
WarrantyExpires: item.WarrantyExpires,
|
||||
WarrantyDetails: item.WarrantyDetails,
|
||||
|
||||
SoldTo: item.SoldTo,
|
||||
SoldTime: item.SoldTime,
|
||||
SoldPrice: item.SoldPrice,
|
||||
SoldNotes: item.SoldNotes,
|
||||
|
||||
Fields: customFields,
|
||||
}
|
||||
}
|
||||
|
||||
// Extract and sort additional headers for deterministic output
|
||||
customHeaders := make([]string, 0, len(extraHeaders))
|
||||
|
||||
for k := range extraHeaders {
|
||||
customHeaders = append(customHeaders, k)
|
||||
}
|
||||
|
||||
sort.Strings(customHeaders)
|
||||
|
||||
st := reflect.TypeOf(ExportTSVRow{})
|
||||
|
||||
// Write headers
|
||||
for i := 0; i < st.NumField(); i++ {
|
||||
field := st.Field(i)
|
||||
tag := field.Tag.Get("csv")
|
||||
if tag == "" || tag == "-" {
|
||||
continue
|
||||
}
|
||||
|
||||
s.headers = append(s.headers, tag)
|
||||
}
|
||||
|
||||
for _, h := range customHeaders {
|
||||
s.headers = append(s.headers, "HB.field."+h)
|
||||
}
|
||||
}
|
||||
|
||||
// Writes the current sheet to a writer in TSV format.
|
||||
func (s *IOSheet) TSV() ([][]string, error) {
|
||||
memcsv := make([][]string, len(s.Rows)+1)
|
||||
|
||||
memcsv[0] = s.headers
|
||||
|
||||
// use struct tags in rows to dertmine column order
|
||||
for i, row := range s.Rows {
|
||||
rowIdx := i + 1
|
||||
|
||||
memcsv[rowIdx] = make([]string, len(s.headers))
|
||||
|
||||
st := reflect.TypeOf(row)
|
||||
|
||||
for i := 0; i < st.NumField(); i++ {
|
||||
field := st.Field(i)
|
||||
tag := field.Tag.Get("csv")
|
||||
if tag == "" || tag == "-" {
|
||||
continue
|
||||
}
|
||||
|
||||
col, ok := s.GetColumn(tag)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
val := reflect.ValueOf(row).Field(i)
|
||||
|
||||
var v string
|
||||
|
||||
switch field.Type {
|
||||
case reflect.TypeOf(""):
|
||||
v = val.String()
|
||||
case reflect.TypeOf(int(0)):
|
||||
v = strconv.Itoa(int(val.Int()))
|
||||
case reflect.TypeOf(bool(false)):
|
||||
v = strconv.FormatBool(val.Bool())
|
||||
case reflect.TypeOf(float64(0)):
|
||||
v = strconv.FormatFloat(val.Float(), 'f', -1, 64)
|
||||
|
||||
// Custom Types
|
||||
case reflect.TypeOf(types.Date{}):
|
||||
v = val.Interface().(types.Date).String()
|
||||
case reflect.TypeOf(repo.AssetID(0)):
|
||||
v = val.Interface().(repo.AssetID).String()
|
||||
case reflect.TypeOf(LocationString{}):
|
||||
v = val.Interface().(LocationString).String()
|
||||
case reflect.TypeOf(LabelString{}):
|
||||
v = val.Interface().(LabelString).String()
|
||||
default:
|
||||
log.Debug().Str("type", field.Type.String()).Msg("unknown type")
|
||||
}
|
||||
|
||||
memcsv[rowIdx][col] = v
|
||||
}
|
||||
|
||||
for _, f := range row.Fields {
|
||||
col, ok := s.GetColumn("HB.field." + f.Name)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
memcsv[i+1][col] = f.Value
|
||||
}
|
||||
}
|
||||
|
||||
return memcsv, nil
|
||||
}
|
||||
226
backend/internal/core/services/reporting/io_sheet_test.go
Normal file
226
backend/internal/core/services/reporting/io_sheet_test.go
Normal file
@@ -0,0 +1,226 @@
|
||||
package reporting
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
_ "embed"
|
||||
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var (
|
||||
//go:embed .testdata/import/minimal.csv
|
||||
minimalImportCSV []byte
|
||||
|
||||
//go:embed .testdata/import/fields.csv
|
||||
customFieldImportCSV []byte
|
||||
|
||||
//go:embed .testdata/import/types.csv
|
||||
customTypesImportCSV []byte
|
||||
|
||||
//go:embed .testdata/import.csv
|
||||
CSVData_Comma []byte
|
||||
|
||||
//go:embed .testdata/import.tsv
|
||||
CSVData_Tab []byte
|
||||
)
|
||||
|
||||
func TestSheet_Read(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
data []byte
|
||||
want []ExportTSVRow
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "minimal import",
|
||||
data: minimalImportCSV,
|
||||
want: []ExportTSVRow{
|
||||
{Location: LocationString{"loc"}, Name: "Item 1", Quantity: 1, Description: "Description 1"},
|
||||
{Location: LocationString{"loc"}, Name: "Item 2", Quantity: 2, Description: "Description 2"},
|
||||
{Location: LocationString{"loc"}, Name: "Item 3", Quantity: 3, Description: "Description 3"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "custom field import",
|
||||
data: customFieldImportCSV,
|
||||
want: []ExportTSVRow{
|
||||
{
|
||||
Location: LocationString{"loc"}, Name: "Item 1", Quantity: 1, Description: "Description 1",
|
||||
Fields: []ExportItemFields{
|
||||
{Name: "Custom Field 1", Value: "Value 1[1]"},
|
||||
{Name: "Custom Field 2", Value: "Value 1[2]"},
|
||||
{Name: "Custom Field 3", Value: "Value 1[3]"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Location: LocationString{"loc"}, Name: "Item 2", Quantity: 2, Description: "Description 2",
|
||||
Fields: []ExportItemFields{
|
||||
{Name: "Custom Field 1", Value: "Value 2[1]"},
|
||||
{Name: "Custom Field 2", Value: "Value 2[2]"},
|
||||
{Name: "Custom Field 3", Value: "Value 2[3]"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Location: LocationString{"loc"}, Name: "Item 3", Quantity: 3, Description: "Description 3",
|
||||
Fields: []ExportItemFields{
|
||||
{Name: "Custom Field 1", Value: "Value 3[1]"},
|
||||
{Name: "Custom Field 2", Value: "Value 3[2]"},
|
||||
{Name: "Custom Field 3", Value: "Value 3[3]"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "custom types import",
|
||||
data: customTypesImportCSV,
|
||||
want: []ExportTSVRow{
|
||||
{
|
||||
Name: "Item 1",
|
||||
AssetID: repo.AssetID(1),
|
||||
Location: LocationString{"Path", "To", "Location 1"},
|
||||
LabelStr: LabelString{"L1", "L2", "L3"},
|
||||
},
|
||||
{
|
||||
Name: "Item 2",
|
||||
AssetID: repo.AssetID(2),
|
||||
Location: LocationString{"Path", "To", "Location 2"},
|
||||
LabelStr: LabelString{"L1", "L2", "L3"},
|
||||
},
|
||||
{
|
||||
Name: "Item 3",
|
||||
AssetID: repo.AssetID(1000003),
|
||||
Location: LocationString{"Path", "To", "Location 3"},
|
||||
LabelStr: LabelString{"L1", "L2", "L3"},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
reader := bytes.NewReader(tt.data)
|
||||
|
||||
sheet := &IOSheet{}
|
||||
err := sheet.Read(reader)
|
||||
|
||||
switch {
|
||||
case tt.wantErr:
|
||||
assert.Error(t, err)
|
||||
default:
|
||||
assert.NoError(t, err)
|
||||
assert.ElementsMatch(t, tt.want, sheet.Rows)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_parseHeaders(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
rawHeaders []string
|
||||
wantHbHeaders map[string]int
|
||||
wantFieldHeaders []string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "no hombox headers",
|
||||
rawHeaders: []string{"Header 1", "Header 2", "Header 3"},
|
||||
wantHbHeaders: nil,
|
||||
wantFieldHeaders: nil,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "field headers only",
|
||||
rawHeaders: []string{"HB.location", "HB.name", "HB.field.1", "HB.field.2", "HB.field.3"},
|
||||
wantHbHeaders: map[string]int{
|
||||
"HB.location": 0,
|
||||
"HB.name": 1,
|
||||
"HB.field.1": 2,
|
||||
"HB.field.2": 3,
|
||||
"HB.field.3": 4,
|
||||
},
|
||||
wantFieldHeaders: []string{"HB.field.1", "HB.field.2", "HB.field.3"},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "mixed headers",
|
||||
rawHeaders: []string{"Header 1", "HB.name", "Header 2", "HB.field.2", "Header 3", "HB.field.3", "HB.location"},
|
||||
wantHbHeaders: map[string]int{
|
||||
"HB.name": 1,
|
||||
"HB.field.2": 3,
|
||||
"HB.field.3": 5,
|
||||
"HB.location": 6,
|
||||
},
|
||||
wantFieldHeaders: []string{"HB.field.2", "HB.field.3"},
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gotHbHeaders, gotFieldHeaders, err := parseHeaders(tt.rawHeaders)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("parseHeaders() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(gotHbHeaders, tt.wantHbHeaders) {
|
||||
t.Errorf("parseHeaders() gotHbHeaders = %v, want %v", gotHbHeaders, tt.wantHbHeaders)
|
||||
}
|
||||
if !reflect.DeepEqual(gotFieldHeaders, tt.wantFieldHeaders) {
|
||||
t.Errorf("parseHeaders() gotFieldHeaders = %v, want %v", gotFieldHeaders, tt.wantFieldHeaders)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_determineSeparator(t *testing.T) {
|
||||
type args struct {
|
||||
data []byte
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want rune
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "comma",
|
||||
args: args{
|
||||
data: CSVData_Comma,
|
||||
},
|
||||
want: ',',
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "tab",
|
||||
args: args{
|
||||
data: CSVData_Tab,
|
||||
},
|
||||
want: '\t',
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "invalid",
|
||||
args: args{
|
||||
data: []byte("a;b;c"),
|
||||
},
|
||||
want: 0,
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := determineSeparator(tt.args.data)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("determineSeparator() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if got != tt.want {
|
||||
t.Errorf("determineSeparator() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
38
backend/internal/core/services/reporting/value_parsers.go
Normal file
38
backend/internal/core/services/reporting/value_parsers.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package reporting
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func parseSeparatedString(s string, sep string) ([]string, error) {
|
||||
list := strings.Split(s, sep)
|
||||
|
||||
csf := make([]string, 0, len(list))
|
||||
for _, s := range list {
|
||||
trimmed := strings.TrimSpace(s)
|
||||
if trimmed != "" {
|
||||
csf = append(csf, trimmed)
|
||||
}
|
||||
}
|
||||
|
||||
return csf, nil
|
||||
}
|
||||
|
||||
func parseFloat(s string) float64 {
|
||||
if s == "" {
|
||||
return 0
|
||||
}
|
||||
f, _ := strconv.ParseFloat(s, 64)
|
||||
return f
|
||||
}
|
||||
|
||||
func parseBool(s string) bool {
|
||||
b, _ := strconv.ParseBool(s)
|
||||
return b
|
||||
}
|
||||
|
||||
func parseInt(s string) int {
|
||||
i, _ := strconv.Atoi(s)
|
||||
return i
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package reporting
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_parseSeparatedString(t *testing.T) {
|
||||
type args struct {
|
||||
s string
|
||||
sep string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want []string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "comma",
|
||||
args: args{
|
||||
s: "a,b,c",
|
||||
sep: ",",
|
||||
},
|
||||
want: []string{"a", "b", "c"},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "trimmed comma",
|
||||
args: args{
|
||||
s: "a, b, c",
|
||||
sep: ",",
|
||||
},
|
||||
want: []string{"a", "b", "c"},
|
||||
},
|
||||
{
|
||||
name: "excessive whitespace",
|
||||
args: args{
|
||||
s: " a, b, c ",
|
||||
sep: ",",
|
||||
},
|
||||
want: []string{"a", "b", "c"},
|
||||
},
|
||||
{
|
||||
name: "empty",
|
||||
args: args{
|
||||
s: "",
|
||||
sep: ",",
|
||||
},
|
||||
want: []string{},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := parseSeparatedString(tt.args.s, tt.args.sep)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("parseSeparatedString() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("parseSeparatedString() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,13 @@ package services
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/core/services/reporting"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -18,179 +21,332 @@ type ItemService struct {
|
||||
repo *repo.AllRepos
|
||||
|
||||
filepath string
|
||||
// at is a map of tokens to attachment IDs. This is used to store the attachment ID
|
||||
// for issued URLs
|
||||
at attachmentTokens
|
||||
|
||||
autoIncrementAssetID bool
|
||||
}
|
||||
|
||||
func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data [][]string) (int, error) {
|
||||
loaded := []csvRow{}
|
||||
|
||||
// Skip first row
|
||||
for _, row := range data[1:] {
|
||||
// Skip empty rows
|
||||
if len(row) == 0 {
|
||||
continue
|
||||
func (svc *ItemService) Create(ctx Context, item repo.ItemCreate) (repo.ItemOut, error) {
|
||||
if svc.autoIncrementAssetID {
|
||||
highest, err := svc.repo.Items.GetHighestAssetID(ctx, ctx.GID)
|
||||
if err != nil {
|
||||
return repo.ItemOut{}, err
|
||||
}
|
||||
|
||||
if len(row) != NumOfCols {
|
||||
return 0, ErrInvalidCsv
|
||||
}
|
||||
|
||||
r := newCsvRow(row)
|
||||
loaded = append(loaded, r)
|
||||
item.AssetID = repo.AssetID(highest + 1)
|
||||
}
|
||||
|
||||
// validate rows
|
||||
var errMap = map[int][]error{}
|
||||
var hasErr bool
|
||||
for i, r := range loaded {
|
||||
return svc.repo.Items.Create(ctx, ctx.GID, item)
|
||||
}
|
||||
|
||||
errs := r.validate()
|
||||
|
||||
if len(errs) > 0 {
|
||||
hasErr = true
|
||||
lineNum := i + 2
|
||||
|
||||
errMap[lineNum] = errs
|
||||
}
|
||||
}
|
||||
|
||||
if hasErr {
|
||||
for lineNum, errs := range errMap {
|
||||
for _, err := range errs {
|
||||
log.Error().Err(err).Int("line", lineNum).Msg("csv import error")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Bootstrap the locations and labels so we can reuse the created IDs for the items
|
||||
locations := map[string]uuid.UUID{}
|
||||
existingLocation, err := svc.repo.Locations.GetAll(ctx, GID, repo.LocationQuery{})
|
||||
func (svc *ItemService) EnsureAssetID(ctx context.Context, GID uuid.UUID) (int, error) {
|
||||
items, err := svc.repo.Items.GetAllZeroAssetID(ctx, GID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
for _, loc := range existingLocation {
|
||||
locations[loc.Name] = loc.ID
|
||||
}
|
||||
|
||||
labels := map[string]uuid.UUID{}
|
||||
existingLabels, err := svc.repo.Labels.GetAll(ctx, GID)
|
||||
highest, err := svc.repo.Items.GetHighestAssetID(ctx, GID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
for _, label := range existingLabels {
|
||||
labels[label.Name] = label.ID
|
||||
}
|
||||
|
||||
for _, row := range loaded {
|
||||
finished := 0
|
||||
for _, item := range items {
|
||||
highest++
|
||||
|
||||
// Locations
|
||||
if _, exists := locations[row.Location]; !exists {
|
||||
result, err := svc.repo.Locations.Create(ctx, GID, repo.LocationCreate{
|
||||
Name: row.Location,
|
||||
Description: "",
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
locations[row.Location] = result.ID
|
||||
err = svc.repo.Items.SetAssetID(ctx, GID, item.ID, repo.AssetID(highest))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// Labels
|
||||
finished++
|
||||
}
|
||||
|
||||
for _, label := range row.getLabels() {
|
||||
if _, exists := labels[label]; exists {
|
||||
continue
|
||||
}
|
||||
result, err := svc.repo.Labels.Create(ctx, GID, repo.LabelCreate{
|
||||
Name: label,
|
||||
Description: "",
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
labels[label] = result.ID
|
||||
return finished, nil
|
||||
}
|
||||
|
||||
func (svc *ItemService) EnsureImportRef(ctx context.Context, GID uuid.UUID) (int, error) {
|
||||
ids, err := svc.repo.Items.GetAllZeroImportRef(ctx, GID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
finished := 0
|
||||
for _, itemID := range ids {
|
||||
ref := uuid.New().String()[0:8]
|
||||
|
||||
err = svc.repo.Items.Patch(ctx, GID, itemID, repo.ItemPatch{ImportRef: &ref})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
finished++
|
||||
}
|
||||
|
||||
return finished, nil
|
||||
}
|
||||
|
||||
func serializeLocation[T ~[]string](location T) string {
|
||||
return strings.Join(location, "/")
|
||||
}
|
||||
|
||||
// CsvImport imports items from a CSV file. using the standard defined format.
|
||||
//
|
||||
// CsvImport applies the following rules/operations
|
||||
//
|
||||
// 1. If the item does not exist, it is created.
|
||||
// 2. If the item has a ImportRef and it exists it is skipped
|
||||
// 3. Locations and Labels are created if they do not exist.
|
||||
func (svc *ItemService) CsvImport(ctx context.Context, GID uuid.UUID, data io.Reader) (int, error) {
|
||||
sheet := reporting.IOSheet{}
|
||||
|
||||
err := sheet.Read(data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// Labels
|
||||
|
||||
labelMap := make(map[string]uuid.UUID)
|
||||
{
|
||||
labels, err := svc.repo.Labels.GetAll(ctx, GID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
for _, label := range labels {
|
||||
labelMap[label.Name] = label.ID
|
||||
}
|
||||
}
|
||||
|
||||
// Create the items
|
||||
var count int
|
||||
for _, row := range loaded {
|
||||
// Check Import Ref
|
||||
if row.Item.ImportRef != "" {
|
||||
exists, err := svc.repo.Items.CheckRef(ctx, GID, row.Item.ImportRef)
|
||||
// ========================================
|
||||
// Locations
|
||||
|
||||
locationMap := make(map[string]uuid.UUID)
|
||||
{
|
||||
locations, err := svc.repo.Locations.Tree(ctx, GID, repo.TreeQuery{WithItems: false})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// Traverse the tree and build a map of location full paths to IDs
|
||||
// where the full path is the location name joined by slashes.
|
||||
var traverse func(location *repo.TreeItem, path []string)
|
||||
traverse = func(location *repo.TreeItem, path []string) {
|
||||
path = append(path, location.Name)
|
||||
|
||||
locationMap[serializeLocation(path)] = location.ID
|
||||
|
||||
for _, child := range location.Children {
|
||||
traverse(child, path)
|
||||
}
|
||||
}
|
||||
|
||||
for _, location := range locations {
|
||||
traverse(&location, []string{})
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// Import items
|
||||
|
||||
// Asset ID Pre-Check
|
||||
highestAID := repo.AssetID(-1)
|
||||
if svc.autoIncrementAssetID {
|
||||
highestAID, err = svc.repo.Items.GetHighestAssetID(ctx, GID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
finished := 0
|
||||
|
||||
for i := range sheet.Rows {
|
||||
row := sheet.Rows[i]
|
||||
|
||||
createRequired := true
|
||||
|
||||
// ========================================
|
||||
// Preflight check for existing item
|
||||
if row.ImportRef != "" {
|
||||
exists, err := svc.repo.Items.CheckRef(ctx, GID, row.ImportRef)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("error checking for existing item with ref %q: %w", row.ImportRef, err)
|
||||
}
|
||||
|
||||
if exists {
|
||||
continue
|
||||
createRequired = false
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// Pre-Create Labels as necessary
|
||||
labelIds := make([]uuid.UUID, len(row.LabelStr))
|
||||
|
||||
for j := range row.LabelStr {
|
||||
label := row.LabelStr[j]
|
||||
|
||||
id, ok := labelMap[label]
|
||||
if !ok {
|
||||
newLabel, err := svc.repo.Labels.Create(ctx, GID, repo.LabelCreate{Name: label})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
id = newLabel.ID
|
||||
}
|
||||
|
||||
labelIds[j] = id
|
||||
labelMap[label] = id
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// Pre-Create Locations as necessary
|
||||
path := serializeLocation(row.Location)
|
||||
|
||||
locationID, ok := locationMap[path]
|
||||
if !ok { // Traverse the path of LocationStr and check each path element to see if it exists already, if not create it.
|
||||
paths := []string{}
|
||||
for i, pathElement := range row.Location {
|
||||
paths = append(paths, pathElement)
|
||||
path := serializeLocation(paths)
|
||||
|
||||
locationID, ok = locationMap[path]
|
||||
if !ok {
|
||||
parentID := uuid.Nil
|
||||
|
||||
// Get the parent ID
|
||||
if i > 0 {
|
||||
parentPath := serializeLocation(row.Location[:i])
|
||||
parentID = locationMap[parentPath]
|
||||
}
|
||||
|
||||
newLocation, err := svc.repo.Locations.Create(ctx, GID, repo.LocationCreate{
|
||||
ParentID: parentID,
|
||||
Name: pathElement,
|
||||
})
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
locationID = newLocation.ID
|
||||
}
|
||||
|
||||
locationMap[path] = locationID
|
||||
}
|
||||
|
||||
locationID, ok = locationMap[path]
|
||||
if !ok {
|
||||
return 0, errors.New("failed to create location")
|
||||
}
|
||||
}
|
||||
|
||||
var effAID repo.AssetID
|
||||
if svc.autoIncrementAssetID && row.AssetID.Nil() {
|
||||
effAID = highestAID + 1
|
||||
highestAID++
|
||||
} else {
|
||||
effAID = row.AssetID
|
||||
}
|
||||
|
||||
// ========================================
|
||||
// Create Item
|
||||
var item repo.ItemOut
|
||||
switch {
|
||||
case createRequired:
|
||||
newItem := repo.ItemCreate{
|
||||
ImportRef: row.ImportRef,
|
||||
Name: row.Name,
|
||||
Description: row.Description,
|
||||
AssetID: effAID,
|
||||
LocationID: locationID,
|
||||
LabelIDs: labelIds,
|
||||
}
|
||||
|
||||
item, err = svc.repo.Items.Create(ctx, GID, newItem)
|
||||
if err != nil {
|
||||
log.Err(err).Msg("error checking import ref")
|
||||
return 0, err
|
||||
}
|
||||
default:
|
||||
item, err = svc.repo.Items.GetByRef(ctx, GID, row.ImportRef)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
|
||||
locationID := locations[row.Location]
|
||||
labelIDs := []uuid.UUID{}
|
||||
for _, label := range row.getLabels() {
|
||||
labelIDs = append(labelIDs, labels[label])
|
||||
if item.ID == uuid.Nil {
|
||||
panic("item ID is nil on import - this should never happen")
|
||||
}
|
||||
|
||||
log.Info().
|
||||
Str("name", row.Item.Name).
|
||||
Str("location", row.Location).
|
||||
Msgf("Creating Item: %s", row.Item.Name)
|
||||
|
||||
result, err := svc.repo.Items.Create(ctx, GID, repo.ItemCreate{
|
||||
ImportRef: row.Item.ImportRef,
|
||||
Name: row.Item.Name,
|
||||
Description: row.Item.Description,
|
||||
LabelIDs: labelIDs,
|
||||
LocationID: locationID,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return count, err
|
||||
fields := make([]repo.ItemField, len(row.Fields))
|
||||
for i := range row.Fields {
|
||||
fields[i] = repo.ItemField{
|
||||
Name: row.Fields[i].Name,
|
||||
Type: "text",
|
||||
TextValue: row.Fields[i].Value,
|
||||
}
|
||||
}
|
||||
|
||||
// Update the item with the rest of the data
|
||||
_, err = svc.repo.Items.UpdateByGroup(ctx, GID, repo.ItemUpdate{
|
||||
// Edges
|
||||
updateItem := repo.ItemUpdate{
|
||||
ID: item.ID,
|
||||
LabelIDs: labelIds,
|
||||
LocationID: locationID,
|
||||
LabelIDs: labelIDs,
|
||||
|
||||
// General Fields
|
||||
ID: result.ID,
|
||||
Name: result.Name,
|
||||
Description: result.Description,
|
||||
Insured: row.Item.Insured,
|
||||
Notes: row.Item.Notes,
|
||||
Quantity: row.Item.Quantity,
|
||||
Name: row.Name,
|
||||
Description: row.Description,
|
||||
AssetID: effAID,
|
||||
Insured: row.Insured,
|
||||
Quantity: row.Quantity,
|
||||
Archived: row.Archived,
|
||||
|
||||
// Identifies the item as imported
|
||||
SerialNumber: row.Item.SerialNumber,
|
||||
ModelNumber: row.Item.ModelNumber,
|
||||
Manufacturer: row.Item.Manufacturer,
|
||||
PurchasePrice: row.PurchasePrice,
|
||||
PurchaseFrom: row.PurchaseFrom,
|
||||
PurchaseTime: row.PurchaseTime,
|
||||
|
||||
// Purchase
|
||||
PurchaseFrom: row.Item.PurchaseFrom,
|
||||
PurchasePrice: row.Item.PurchasePrice,
|
||||
PurchaseTime: row.Item.PurchaseTime,
|
||||
Manufacturer: row.Manufacturer,
|
||||
ModelNumber: row.ModelNumber,
|
||||
SerialNumber: row.SerialNumber,
|
||||
|
||||
// Warranty
|
||||
LifetimeWarranty: row.Item.LifetimeWarranty,
|
||||
WarrantyExpires: row.Item.WarrantyExpires,
|
||||
WarrantyDetails: row.Item.WarrantyDetails,
|
||||
LifetimeWarranty: row.LifetimeWarranty,
|
||||
WarrantyExpires: row.WarrantyExpires,
|
||||
WarrantyDetails: row.WarrantyDetails,
|
||||
|
||||
SoldTo: row.Item.SoldTo,
|
||||
SoldPrice: row.Item.SoldPrice,
|
||||
SoldTime: row.Item.SoldTime,
|
||||
SoldNotes: row.Item.SoldNotes,
|
||||
})
|
||||
SoldTo: row.SoldTo,
|
||||
SoldTime: row.SoldTime,
|
||||
SoldPrice: row.SoldPrice,
|
||||
SoldNotes: row.SoldNotes,
|
||||
|
||||
if err != nil {
|
||||
return count, err
|
||||
Notes: row.Notes,
|
||||
Fields: fields,
|
||||
}
|
||||
|
||||
count++
|
||||
item, err = svc.repo.Items.UpdateByGroup(ctx, GID, updateItem)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
finished++
|
||||
}
|
||||
return count, nil
|
||||
|
||||
return finished, nil
|
||||
}
|
||||
|
||||
func (svc *ItemService) ExportTSV(ctx context.Context, GID uuid.UUID) ([][]string, error) {
|
||||
items, err := svc.repo.Items.GetAll(ctx, GID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sheet := reporting.IOSheet{}
|
||||
|
||||
sheet.ReadItems(items)
|
||||
|
||||
return sheet.TSV()
|
||||
}
|
||||
|
||||
func (svc *ItemService) ExportBillOfMaterialsTSV(ctx context.Context, GID uuid.UUID) ([]byte, error) {
|
||||
items, err := svc.repo.Items.GetAll(ctx, GID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return reporting.BillOfMaterialsTSV(items)
|
||||
}
|
||||
|
||||
@@ -4,71 +4,15 @@ import (
|
||||
"context"
|
||||
"io"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
"github.com/hay-kot/homebox/backend/pkgs/hasher"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
// TODO: this isn't a scalable solution, tokens should be stored in the database
|
||||
type attachmentTokens map[string]uuid.UUID
|
||||
|
||||
func (at attachmentTokens) Add(token string, id uuid.UUID) {
|
||||
at[token] = id
|
||||
|
||||
log.Debug().Str("token", token).Str("uuid", id.String()).Msg("added token")
|
||||
|
||||
go func() {
|
||||
ch := time.After(1 * time.Minute)
|
||||
<-ch
|
||||
at.Delete(token)
|
||||
log.Debug().Str("token", token).Msg("deleted token")
|
||||
}()
|
||||
}
|
||||
|
||||
func (at attachmentTokens) Get(token string) (uuid.UUID, bool) {
|
||||
id, ok := at[token]
|
||||
return id, ok
|
||||
}
|
||||
|
||||
func (at attachmentTokens) Delete(token string) {
|
||||
delete(at, token)
|
||||
}
|
||||
|
||||
func (svc *ItemService) AttachmentToken(ctx Context, itemId, attachmentId uuid.UUID) (string, error) {
|
||||
_, err := svc.repo.Items.GetOneByGroup(ctx, ctx.GID, itemId)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
token := hasher.GenerateToken()
|
||||
|
||||
// Ensure that the file exists
|
||||
attachment, err := svc.repo.Attachments.Get(ctx, attachmentId)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if _, err := os.Stat(attachment.Edges.Document.Path); os.IsNotExist(err) {
|
||||
_ = svc.AttachmentDelete(ctx, ctx.GID, itemId, attachmentId)
|
||||
return "", ErrNotFound
|
||||
}
|
||||
|
||||
svc.at.Add(token.Raw, attachmentId)
|
||||
|
||||
return token.Raw, nil
|
||||
}
|
||||
|
||||
func (svc *ItemService) AttachmentPath(ctx context.Context, token string) (*ent.Document, error) {
|
||||
attachmentId, ok := svc.at.Get(token)
|
||||
if !ok {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
|
||||
func (svc *ItemService) AttachmentPath(ctx context.Context, attachmentId uuid.UUID) (*ent.Document, error) {
|
||||
attachment, err := svc.repo.Attachments.Get(ctx, attachmentId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -58,5 +58,4 @@ func TestItemService_AddAttachment(t *testing.T) {
|
||||
bts, err := os.ReadFile(storedPath)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, contents, string(bts))
|
||||
|
||||
}
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
)
|
||||
|
||||
var ErrInvalidCsv = errors.New("invalid csv")
|
||||
|
||||
const NumOfCols = 21
|
||||
|
||||
func parseFloat(s string) float64 {
|
||||
if s == "" {
|
||||
return 0
|
||||
}
|
||||
f, _ := strconv.ParseFloat(s, 64)
|
||||
return f
|
||||
}
|
||||
|
||||
func parseDate(s string) time.Time {
|
||||
if s == "" {
|
||||
return time.Time{}
|
||||
}
|
||||
|
||||
p, _ := time.Parse("01/02/2006", s)
|
||||
return p
|
||||
}
|
||||
|
||||
func parseBool(s string) bool {
|
||||
switch strings.ToLower(s) {
|
||||
case "true", "yes", "1":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func parseInt(s string) int {
|
||||
i, _ := strconv.Atoi(s)
|
||||
return i
|
||||
}
|
||||
|
||||
type csvRow struct {
|
||||
Item repo.ItemOut
|
||||
Location string
|
||||
LabelStr string
|
||||
}
|
||||
|
||||
func newCsvRow(row []string) csvRow {
|
||||
return csvRow{
|
||||
Location: row[1],
|
||||
LabelStr: row[2],
|
||||
Item: repo.ItemOut{
|
||||
ItemSummary: repo.ItemSummary{
|
||||
ImportRef: row[0],
|
||||
Quantity: parseInt(row[3]),
|
||||
Name: row[4],
|
||||
Description: row[5],
|
||||
Insured: parseBool(row[6]),
|
||||
},
|
||||
SerialNumber: row[7],
|
||||
ModelNumber: row[8],
|
||||
Manufacturer: row[9],
|
||||
Notes: row[10],
|
||||
PurchaseFrom: row[11],
|
||||
PurchasePrice: parseFloat(row[12]),
|
||||
PurchaseTime: parseDate(row[13]),
|
||||
LifetimeWarranty: parseBool(row[14]),
|
||||
WarrantyExpires: parseDate(row[15]),
|
||||
WarrantyDetails: row[16],
|
||||
SoldTo: row[17],
|
||||
SoldPrice: parseFloat(row[18]),
|
||||
SoldTime: parseDate(row[19]),
|
||||
SoldNotes: row[20],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (c csvRow) getLabels() []string {
|
||||
split := strings.Split(c.LabelStr, ";")
|
||||
|
||||
// Trim each
|
||||
for i, s := range split {
|
||||
split[i] = strings.TrimSpace(s)
|
||||
}
|
||||
|
||||
// Remove empty
|
||||
for i, s := range split {
|
||||
if s == "" {
|
||||
split = append(split[:i], split[i+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
return split
|
||||
}
|
||||
|
||||
func (c csvRow) validate() []error {
|
||||
var errs []error
|
||||
|
||||
add := func(err error) {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
|
||||
required := func(s string, name string) {
|
||||
if s == "" {
|
||||
add(errors.New(name + " is required"))
|
||||
}
|
||||
}
|
||||
|
||||
required(c.Location, "Location")
|
||||
required(c.Item.Name, "Name")
|
||||
|
||||
return errs
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/csv"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
const CSV_DATA = `
|
||||
Import Ref,Location,Labels,Quantity,Name,Description,Insured,Serial Number,Mode Number,Manufacturer,Notes,Purchase From,Purchased Price,Purchased Time,Lifetime Warranty,Warranty Expires,Warranty Details,Sold To,Sold Price,Sold Time,Sold Notes
|
||||
A,Garage,IOT;Home Assistant; Z-Wave,1,Zooz Universal Relay ZEN17,Description 1,TRUE,,ZEN17,Zooz,,Amazon,39.95,10/13/2021,,10/13/2021,,,,10/13/2021,
|
||||
B,Living Room,IOT;Home Assistant; Z-Wave,1,Zooz Motion Sensor,Description 2,FALSE,,ZSE18,Zooz,,Amazon,29.95,10/15/2021,,10/15/2021,,,,10/15/2021,
|
||||
C,Office,IOT;Home Assistant; Z-Wave,1,Zooz 110v Power Switch,Description 3,TRUE,,ZEN15,Zooz,,Amazon,39.95,10/13/2021,,10/13/2021,,,,10/13/2021,
|
||||
D,Downstairs,IOT;Home Assistant; Z-Wave,1,Ecolink Z-Wave PIR Motion Sensor,Description 4,FALSE,,PIRZWAVE2.5-ECO,Ecolink,,Amazon,35.58,10/21/2020,,10/21/2020,,,,10/21/2020,
|
||||
E,Entry,IOT;Home Assistant; Z-Wave,1,Yale Security Touchscreen Deadbolt,Description 5,TRUE,,YRD226ZW2619,Yale,,Amazon,120.39,10/14/2020,,10/14/2020,,,,10/14/2020,
|
||||
F,Kitchen,IOT;Home Assistant; Z-Wave,1,Smart Rocker Light Dimmer,Description 6,FALSE,,39351,Honeywell,,Amazon,65.98,09/30/2020,,09/30/2020,,,,09/30/2020,`
|
||||
|
||||
func loadcsv() [][]string {
|
||||
reader := csv.NewReader(bytes.NewBuffer([]byte(CSV_DATA)))
|
||||
|
||||
records, err := reader.ReadAll()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return records
|
||||
}
|
||||
|
||||
func Test_CorrectDateParsing(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
expected := []time.Time{
|
||||
time.Date(2021, 10, 13, 0, 0, 0, 0, time.UTC),
|
||||
time.Date(2021, 10, 15, 0, 0, 0, 0, time.UTC),
|
||||
time.Date(2021, 10, 13, 0, 0, 0, 0, time.UTC),
|
||||
time.Date(2020, 10, 21, 0, 0, 0, 0, time.UTC),
|
||||
time.Date(2020, 10, 14, 0, 0, 0, 0, time.UTC),
|
||||
time.Date(2020, 9, 30, 0, 0, 0, 0, time.UTC),
|
||||
}
|
||||
|
||||
records := loadcsv()
|
||||
|
||||
for i, record := range records {
|
||||
if i == 0 {
|
||||
continue
|
||||
}
|
||||
entity := newCsvRow(record)
|
||||
expected := expected[i-1]
|
||||
|
||||
assert.Equal(t, expected, entity.Item.PurchaseTime, fmt.Sprintf("Failed on row %d", i))
|
||||
assert.Equal(t, expected, entity.Item.WarrantyExpires, fmt.Sprintf("Failed on row %d", i))
|
||||
assert.Equal(t, expected, entity.Item.SoldTime, fmt.Sprintf("Failed on row %d", i))
|
||||
}
|
||||
}
|
||||
|
||||
func Test_csvRow_getLabels(t *testing.T) {
|
||||
type fields struct {
|
||||
LabelStr string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
want []string
|
||||
}{
|
||||
{
|
||||
name: "basic test",
|
||||
fields: fields{
|
||||
LabelStr: "IOT;Home Assistant;Z-Wave",
|
||||
},
|
||||
want: []string{"IOT", "Home Assistant", "Z-Wave"},
|
||||
},
|
||||
{
|
||||
name: "no labels",
|
||||
fields: fields{
|
||||
LabelStr: "",
|
||||
},
|
||||
want: []string{},
|
||||
},
|
||||
{
|
||||
name: "single label",
|
||||
fields: fields{
|
||||
LabelStr: "IOT",
|
||||
},
|
||||
want: []string{"IOT"},
|
||||
},
|
||||
{
|
||||
name: "trailing semicolon",
|
||||
fields: fields{
|
||||
LabelStr: "IOT;",
|
||||
},
|
||||
want: []string{"IOT"},
|
||||
},
|
||||
|
||||
{
|
||||
name: "whitespace",
|
||||
fields: fields{
|
||||
LabelStr: " IOT; Home Assistant; Z-Wave ",
|
||||
},
|
||||
want: []string{"IOT", "Home Assistant", "Z-Wave"},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
c := csvRow{
|
||||
LabelStr: tt.fields.LabelStr,
|
||||
}
|
||||
if got := c.getLabels(); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("csvRow.getLabels() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestItemService_CsvImport(t *testing.T) {
|
||||
data := loadcsv()
|
||||
svc := &ItemService{
|
||||
repo: tRepos,
|
||||
}
|
||||
count, err := svc.CsvImport(context.Background(), tGroup.ID, data)
|
||||
assert.Equal(t, 6, count)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Check import refs are deduplicated
|
||||
count, err = svc.CsvImport(context.Background(), tGroup.ID, data)
|
||||
assert.Equal(t, 0, count)
|
||||
assert.NoError(t, err)
|
||||
|
||||
items, err := svc.repo.Items.GetAll(context.Background(), tGroup.ID)
|
||||
assert.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
for _, item := range items {
|
||||
err := svc.repo.Items.Delete(context.Background(), item.ID)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
})
|
||||
|
||||
assert.Equal(t, len(items), 6)
|
||||
|
||||
dataCsv := []csvRow{}
|
||||
for _, item := range data {
|
||||
dataCsv = append(dataCsv, newCsvRow(item))
|
||||
}
|
||||
|
||||
allLocation, err := tRepos.Locations.GetAll(context.Background(), tGroup.ID, repo.LocationQuery{})
|
||||
assert.NoError(t, err)
|
||||
locNames := []string{}
|
||||
for _, loc := range allLocation {
|
||||
locNames = append(locNames, loc.Name)
|
||||
}
|
||||
|
||||
allLabels, err := tRepos.Labels.GetAll(context.Background(), tGroup.ID)
|
||||
assert.NoError(t, err)
|
||||
labelNames := []string{}
|
||||
for _, label := range allLabels {
|
||||
labelNames = append(labelNames, label.Name)
|
||||
}
|
||||
|
||||
ids := []uuid.UUID{}
|
||||
t.Cleanup((func() {
|
||||
for _, id := range ids {
|
||||
err := svc.repo.Items.Delete(context.Background(), id)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
}))
|
||||
|
||||
for _, item := range items {
|
||||
assert.Contains(t, locNames, item.Location.Name)
|
||||
for _, label := range item.Labels {
|
||||
assert.Contains(t, labelNames, label.Name)
|
||||
}
|
||||
|
||||
for _, csvRow := range dataCsv {
|
||||
if csvRow.Item.Name == item.Name {
|
||||
assert.Equal(t, csvRow.Item.Description, item.Description)
|
||||
assert.Equal(t, csvRow.Item.Quantity, item.Quantity)
|
||||
assert.Equal(t, csvRow.Item.Insured, item.Insured)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/repo"
|
||||
"github.com/hay-kot/homebox/backend/pkgs/hasher"
|
||||
"github.com/rs/zerolog/log"
|
||||
@@ -30,8 +31,9 @@ type (
|
||||
Password string `json:"password"`
|
||||
}
|
||||
UserAuthTokenDetail struct {
|
||||
Raw string `json:"raw"`
|
||||
ExpiresAt time.Time `json:"expiresAt"`
|
||||
Raw string `json:"raw"`
|
||||
AttachmentToken string `json:"attachmentToken"`
|
||||
ExpiresAt time.Time `json:"expiresAt"`
|
||||
}
|
||||
LoginForm struct {
|
||||
Username string `json:"username"`
|
||||
@@ -49,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")
|
||||
@@ -79,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)
|
||||
@@ -87,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 {
|
||||
@@ -131,21 +138,40 @@ func (svc *UserService) UpdateSelf(ctx context.Context, ID uuid.UUID, data repo.
|
||||
// ============================================================================
|
||||
// User Authentication
|
||||
|
||||
func (svc *UserService) createToken(ctx context.Context, userId uuid.UUID) (UserAuthTokenDetail, error) {
|
||||
newToken := hasher.GenerateToken()
|
||||
|
||||
created, err := svc.repos.AuthTokens.CreateToken(ctx, repo.UserAuthTokenCreate{
|
||||
func (svc *UserService) createSessionToken(ctx context.Context, userId uuid.UUID) (UserAuthTokenDetail, error) {
|
||||
attachmentToken := hasher.GenerateToken()
|
||||
attachmentData := repo.UserAuthTokenCreate{
|
||||
UserID: userId,
|
||||
TokenHash: newToken.Hash,
|
||||
TokenHash: attachmentToken.Hash,
|
||||
ExpiresAt: time.Now().Add(oneWeek),
|
||||
})
|
||||
}
|
||||
|
||||
return UserAuthTokenDetail{Raw: newToken.Raw, ExpiresAt: created.ExpiresAt}, err
|
||||
_, err := svc.repos.AuthTokens.CreateToken(ctx, attachmentData, authroles.RoleAttachments)
|
||||
if err != nil {
|
||||
return UserAuthTokenDetail{}, err
|
||||
}
|
||||
|
||||
userToken := hasher.GenerateToken()
|
||||
data := repo.UserAuthTokenCreate{
|
||||
UserID: userId,
|
||||
TokenHash: userToken.Hash,
|
||||
ExpiresAt: time.Now().Add(oneWeek),
|
||||
}
|
||||
|
||||
created, err := svc.repos.AuthTokens.CreateToken(ctx, data, authroles.RoleUser)
|
||||
if err != nil {
|
||||
return UserAuthTokenDetail{}, err
|
||||
}
|
||||
|
||||
return UserAuthTokenDetail{
|
||||
Raw: userToken.Raw,
|
||||
ExpiresAt: created.ExpiresAt,
|
||||
AttachmentToken: attachmentToken.Raw,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (svc *UserService) Login(ctx context.Context, username, password string) (UserAuthTokenDetail, error) {
|
||||
usr, err := svc.repos.Users.GetOneEmail(ctx, username)
|
||||
|
||||
if err != nil {
|
||||
// SECURITY: Perform hash to ensure response times are the same
|
||||
hasher.CheckPasswordHash("not-a-real-password", "not-a-real-password")
|
||||
@@ -156,7 +182,7 @@ func (svc *UserService) Login(ctx context.Context, username, password string) (U
|
||||
return UserAuthTokenDetail{}, ErrorInvalidLogin
|
||||
}
|
||||
|
||||
return svc.createToken(ctx, usr.ID)
|
||||
return svc.createSessionToken(ctx, usr.ID)
|
||||
}
|
||||
|
||||
func (svc *UserService) Logout(ctx context.Context, token string) error {
|
||||
@@ -169,14 +195,11 @@ func (svc *UserService) RenewToken(ctx context.Context, token string) (UserAuthT
|
||||
hash := hasher.HashToken(token)
|
||||
|
||||
dbToken, err := svc.repos.AuthTokens.GetUserFromToken(ctx, hash)
|
||||
|
||||
if err != nil {
|
||||
return UserAuthTokenDetail{}, ErrorInvalidToken
|
||||
}
|
||||
|
||||
newToken, _ := svc.createToken(ctx, dbToken.ID)
|
||||
|
||||
return newToken, nil
|
||||
return svc.createSessionToken(ctx, dbToken.ID)
|
||||
}
|
||||
|
||||
// DeleteSelf deletes the user that is currently logged based of the provided UUID
|
||||
|
||||
@@ -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,
|
||||
@@ -189,9 +189,3 @@ func (a *Attachment) String() string {
|
||||
|
||||
// Attachments is a parsable slice of Attachment.
|
||||
type Attachments []*Attachment
|
||||
|
||||
func (a Attachments) config(cfg config) {
|
||||
for _i := range a {
|
||||
a[_i].config = cfg
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,251 +13,157 @@ import (
|
||||
|
||||
// ID filters vertices based on their ID field.
|
||||
func ID(id uuid.UUID) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDEQ applies the EQ predicate on the ID field.
|
||||
func IDEQ(id uuid.UUID) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDNEQ applies the NEQ predicate on the ID field.
|
||||
func IDNEQ(id uuid.UUID) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldNEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDIn applies the In predicate on the ID field.
|
||||
func IDIn(ids ...uuid.UUID) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
v := make([]any, len(ids))
|
||||
for i := range v {
|
||||
v[i] = ids[i]
|
||||
}
|
||||
s.Where(sql.In(s.C(FieldID), v...))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDNotIn applies the NotIn predicate on the ID field.
|
||||
func IDNotIn(ids ...uuid.UUID) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
v := make([]any, len(ids))
|
||||
for i := range v {
|
||||
v[i] = ids[i]
|
||||
}
|
||||
s.Where(sql.NotIn(s.C(FieldID), v...))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldNotIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDGT applies the GT predicate on the ID field.
|
||||
func IDGT(id uuid.UUID) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldGT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDGTE applies the GTE predicate on the ID field.
|
||||
func IDGTE(id uuid.UUID) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldGTE(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLT applies the LT predicate on the ID field.
|
||||
func IDLT(id uuid.UUID) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldLT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLTE applies the LTE predicate on the ID field.
|
||||
func IDLTE(id uuid.UUID) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldLTE(FieldID, id))
|
||||
}
|
||||
|
||||
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
|
||||
func CreatedAt(v time.Time) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
|
||||
func UpdatedAt(v time.Time) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
|
||||
func CreatedAtEQ(v time.Time) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
|
||||
func CreatedAtNEQ(v time.Time) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldNEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtIn applies the In predicate on the "created_at" field.
|
||||
func CreatedAtIn(vs ...time.Time) predicate.Attachment {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldCreatedAt), v...))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldIn(FieldCreatedAt, vs...))
|
||||
}
|
||||
|
||||
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
|
||||
func CreatedAtNotIn(vs ...time.Time) predicate.Attachment {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldCreatedAt), v...))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldNotIn(FieldCreatedAt, vs...))
|
||||
}
|
||||
|
||||
// CreatedAtGT applies the GT predicate on the "created_at" field.
|
||||
func CreatedAtGT(v time.Time) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldGT(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
|
||||
func CreatedAtGTE(v time.Time) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldGTE(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtLT applies the LT predicate on the "created_at" field.
|
||||
func CreatedAtLT(v time.Time) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldLT(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
|
||||
func CreatedAtLTE(v time.Time) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldLTE(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
|
||||
func UpdatedAtEQ(v time.Time) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
|
||||
func UpdatedAtNEQ(v time.Time) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldNEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtIn applies the In predicate on the "updated_at" field.
|
||||
func UpdatedAtIn(vs ...time.Time) predicate.Attachment {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldUpdatedAt), v...))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldIn(FieldUpdatedAt, vs...))
|
||||
}
|
||||
|
||||
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
|
||||
func UpdatedAtNotIn(vs ...time.Time) predicate.Attachment {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldUpdatedAt), v...))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldNotIn(FieldUpdatedAt, vs...))
|
||||
}
|
||||
|
||||
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
|
||||
func UpdatedAtGT(v time.Time) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldGT(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
|
||||
func UpdatedAtGTE(v time.Time) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldGTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
|
||||
func UpdatedAtLT(v time.Time) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldLT(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
|
||||
func UpdatedAtLTE(v time.Time) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldLTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// TypeEQ applies the EQ predicate on the "type" field.
|
||||
func TypeEQ(v Type) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldType), v))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldEQ(FieldType, v))
|
||||
}
|
||||
|
||||
// TypeNEQ applies the NEQ predicate on the "type" field.
|
||||
func TypeNEQ(v Type) predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldType), v))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldNEQ(FieldType, v))
|
||||
}
|
||||
|
||||
// TypeIn applies the In predicate on the "type" field.
|
||||
func TypeIn(vs ...Type) predicate.Attachment {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldType), v...))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldIn(FieldType, vs...))
|
||||
}
|
||||
|
||||
// TypeNotIn applies the NotIn predicate on the "type" field.
|
||||
func TypeNotIn(vs ...Type) predicate.Attachment {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldType), v...))
|
||||
})
|
||||
return predicate.Attachment(sql.FieldNotIn(FieldType, vs...))
|
||||
}
|
||||
|
||||
// HasItem applies the HasEdge predicate on the "item" edge.
|
||||
@@ -265,7 +171,6 @@ func HasItem() predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(ItemTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, ItemTable, ItemColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
@@ -293,7 +198,6 @@ func HasDocument() predicate.Attachment {
|
||||
return predicate.Attachment(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(DocumentTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, DocumentTable, DocumentColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
|
||||
@@ -108,50 +108,8 @@ func (ac *AttachmentCreate) Mutation() *AttachmentMutation {
|
||||
|
||||
// Save creates the Attachment in the database.
|
||||
func (ac *AttachmentCreate) Save(ctx context.Context) (*Attachment, error) {
|
||||
var (
|
||||
err error
|
||||
node *Attachment
|
||||
)
|
||||
ac.defaults()
|
||||
if len(ac.hooks) == 0 {
|
||||
if err = ac.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node, err = ac.sqlSave(ctx)
|
||||
} else {
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*AttachmentMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
if err = ac.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ac.mutation = mutation
|
||||
if node, err = ac.sqlSave(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mutation.id = &node.ID
|
||||
mutation.done = true
|
||||
return node, err
|
||||
})
|
||||
for i := len(ac.hooks) - 1; i >= 0; i-- {
|
||||
if ac.hooks[i] == nil {
|
||||
return nil, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = ac.hooks[i](mut)
|
||||
}
|
||||
v, err := mut.Mutate(ctx, ac.mutation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nv, ok := v.(*Attachment)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected node type %T returned from AttachmentMutation", v)
|
||||
}
|
||||
node = nv
|
||||
}
|
||||
return node, err
|
||||
return withHooks[*Attachment, AttachmentMutation](ctx, ac.sqlSave, ac.mutation, ac.hooks)
|
||||
}
|
||||
|
||||
// SaveX calls Save and panics if Save returns an error.
|
||||
@@ -222,6 +180,9 @@ func (ac *AttachmentCreate) check() error {
|
||||
}
|
||||
|
||||
func (ac *AttachmentCreate) sqlSave(ctx context.Context) (*Attachment, error) {
|
||||
if err := ac.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_node, _spec := ac.createSpec()
|
||||
if err := sqlgraph.CreateNode(ctx, ac.driver, _spec); err != nil {
|
||||
if sqlgraph.IsConstraintError(err) {
|
||||
@@ -236,46 +197,30 @@ func (ac *AttachmentCreate) sqlSave(ctx context.Context) (*Attachment, error) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
ac.mutation.id = &_node.ID
|
||||
ac.mutation.done = true
|
||||
return _node, nil
|
||||
}
|
||||
|
||||
func (ac *AttachmentCreate) createSpec() (*Attachment, *sqlgraph.CreateSpec) {
|
||||
var (
|
||||
_node = &Attachment{config: ac.config}
|
||||
_spec = &sqlgraph.CreateSpec{
|
||||
Table: attachment.Table,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: attachment.FieldID,
|
||||
},
|
||||
}
|
||||
_spec = sqlgraph.NewCreateSpec(attachment.Table, sqlgraph.NewFieldSpec(attachment.FieldID, field.TypeUUID))
|
||||
)
|
||||
if id, ok := ac.mutation.ID(); ok {
|
||||
_node.ID = id
|
||||
_spec.ID.Value = &id
|
||||
}
|
||||
if value, ok := ac.mutation.CreatedAt(); ok {
|
||||
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: attachment.FieldCreatedAt,
|
||||
})
|
||||
_spec.SetField(attachment.FieldCreatedAt, field.TypeTime, value)
|
||||
_node.CreatedAt = value
|
||||
}
|
||||
if value, ok := ac.mutation.UpdatedAt(); ok {
|
||||
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: attachment.FieldUpdatedAt,
|
||||
})
|
||||
_spec.SetField(attachment.FieldUpdatedAt, field.TypeTime, value)
|
||||
_node.UpdatedAt = value
|
||||
}
|
||||
if value, ok := ac.mutation.GetType(); ok {
|
||||
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeEnum,
|
||||
Value: value,
|
||||
Column: attachment.FieldType,
|
||||
})
|
||||
_spec.SetField(attachment.FieldType, field.TypeEnum, value)
|
||||
_node.Type = value
|
||||
}
|
||||
if nodes := ac.mutation.ItemIDs(); len(nodes) > 0 {
|
||||
|
||||
@@ -4,7 +4,6 @@ package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
@@ -28,34 +27,7 @@ func (ad *AttachmentDelete) Where(ps ...predicate.Attachment) *AttachmentDelete
|
||||
|
||||
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||
func (ad *AttachmentDelete) Exec(ctx context.Context) (int, error) {
|
||||
var (
|
||||
err error
|
||||
affected int
|
||||
)
|
||||
if len(ad.hooks) == 0 {
|
||||
affected, err = ad.sqlExec(ctx)
|
||||
} else {
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*AttachmentMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
ad.mutation = mutation
|
||||
affected, err = ad.sqlExec(ctx)
|
||||
mutation.done = true
|
||||
return affected, err
|
||||
})
|
||||
for i := len(ad.hooks) - 1; i >= 0; i-- {
|
||||
if ad.hooks[i] == nil {
|
||||
return 0, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = ad.hooks[i](mut)
|
||||
}
|
||||
if _, err := mut.Mutate(ctx, ad.mutation); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
return affected, err
|
||||
return withHooks[int, AttachmentMutation](ctx, ad.sqlExec, ad.mutation, ad.hooks)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
@@ -68,15 +40,7 @@ func (ad *AttachmentDelete) ExecX(ctx context.Context) int {
|
||||
}
|
||||
|
||||
func (ad *AttachmentDelete) sqlExec(ctx context.Context) (int, error) {
|
||||
_spec := &sqlgraph.DeleteSpec{
|
||||
Node: &sqlgraph.NodeSpec{
|
||||
Table: attachment.Table,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: attachment.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
_spec := sqlgraph.NewDeleteSpec(attachment.Table, sqlgraph.NewFieldSpec(attachment.FieldID, field.TypeUUID))
|
||||
if ps := ad.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
@@ -88,6 +52,7 @@ func (ad *AttachmentDelete) sqlExec(ctx context.Context) (int, error) {
|
||||
if err != nil && sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
ad.mutation.done = true
|
||||
return affected, err
|
||||
}
|
||||
|
||||
@@ -96,6 +61,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)
|
||||
@@ -111,5 +82,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,9 @@ 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
|
||||
withDocument *DocumentQuery
|
||||
@@ -40,26 +38,26 @@ func (aq *AttachmentQuery) Where(ps ...predicate.Attachment) *AttachmentQuery {
|
||||
return aq
|
||||
}
|
||||
|
||||
// Limit adds a limit step to the query.
|
||||
// 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 adds an offset step to the query.
|
||||
// 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
|
||||
}
|
||||
|
||||
// Order adds an order step to the query.
|
||||
// Order specifies how the records should be ordered.
|
||||
func (aq *AttachmentQuery) Order(o ...OrderFunc) *AttachmentQuery {
|
||||
aq.order = append(aq.order, o...)
|
||||
return aq
|
||||
@@ -67,7 +65,7 @@ func (aq *AttachmentQuery) Order(o ...OrderFunc) *AttachmentQuery {
|
||||
|
||||
// QueryItem chains the current query on the "item" edge.
|
||||
func (aq *AttachmentQuery) QueryItem() *ItemQuery {
|
||||
query := &ItemQuery{config: aq.config}
|
||||
query := (&ItemClient{config: aq.config}).Query()
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := aq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
@@ -89,7 +87,7 @@ func (aq *AttachmentQuery) QueryItem() *ItemQuery {
|
||||
|
||||
// QueryDocument chains the current query on the "document" edge.
|
||||
func (aq *AttachmentQuery) QueryDocument() *DocumentQuery {
|
||||
query := &DocumentQuery{config: aq.config}
|
||||
query := (&DocumentClient{config: aq.config}).Query()
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := aq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
@@ -112,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(ctx)
|
||||
nodes, err := aq.Limit(1).All(setContextOp(ctx, aq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -135,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(ctx); err != nil {
|
||||
if ids, err = aq.Limit(1).IDs(setContextOp(ctx, aq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -158,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(ctx)
|
||||
nodes, err := aq.Limit(2).All(setContextOp(ctx, aq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -186,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(ctx); err != nil {
|
||||
if ids, err = aq.Limit(2).IDs(setContextOp(ctx, aq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -211,10 +209,12 @@ 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 = setContextOp(ctx, aq.ctx, "All")
|
||||
if err := aq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return aq.sqlAll(ctx)
|
||||
qr := querierAll[[]*Attachment, *AttachmentQuery]()
|
||||
return withInterceptors[[]*Attachment](ctx, aq, qr, aq.inters)
|
||||
}
|
||||
|
||||
// AllX is like All, but panics if an error occurs.
|
||||
@@ -227,9 +227,12 @@ 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
|
||||
if err := aq.Select(attachment.FieldID).Scan(ctx, &ids); err != nil {
|
||||
func (aq *AttachmentQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error) {
|
||||
if aq.ctx.Unique == nil && aq.path != nil {
|
||||
aq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, aq.ctx, "IDs")
|
||||
if err = aq.Select(attachment.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ids, nil
|
||||
@@ -246,10 +249,11 @@ 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 = setContextOp(ctx, aq.ctx, "Count")
|
||||
if err := aq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return aq.sqlCount(ctx)
|
||||
return withInterceptors[int](ctx, aq, querierCount[*AttachmentQuery](), aq.inters)
|
||||
}
|
||||
|
||||
// CountX is like Count, but panics if an error occurs.
|
||||
@@ -263,10 +267,15 @@ 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) {
|
||||
if err := aq.prepareQuery(ctx); err != nil {
|
||||
return false, err
|
||||
ctx = setContextOp(ctx, aq.ctx, "Exist")
|
||||
switch _, err := aq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
case err != nil:
|
||||
return false, fmt.Errorf("ent: check existence: %w", err)
|
||||
default:
|
||||
return true, nil
|
||||
}
|
||||
return aq.sqlExist(ctx)
|
||||
}
|
||||
|
||||
// ExistX is like Exist, but panics if an error occurs.
|
||||
@@ -286,23 +295,22 @@ 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,
|
||||
}
|
||||
}
|
||||
|
||||
// WithItem tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "item" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (aq *AttachmentQuery) WithItem(opts ...func(*ItemQuery)) *AttachmentQuery {
|
||||
query := &ItemQuery{config: aq.config}
|
||||
query := (&ItemClient{config: aq.config}).Query()
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
@@ -313,7 +321,7 @@ func (aq *AttachmentQuery) WithItem(opts ...func(*ItemQuery)) *AttachmentQuery {
|
||||
// WithDocument tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "document" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (aq *AttachmentQuery) WithDocument(opts ...func(*DocumentQuery)) *AttachmentQuery {
|
||||
query := &DocumentQuery{config: aq.config}
|
||||
query := (&DocumentClient{config: aq.config}).Query()
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
@@ -336,16 +344,11 @@ func (aq *AttachmentQuery) WithDocument(opts ...func(*DocumentQuery)) *Attachmen
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (aq *AttachmentQuery) GroupBy(field string, fields ...string) *AttachmentGroupBy {
|
||||
grbuild := &AttachmentGroupBy{config: aq.config}
|
||||
grbuild.fields = append([]string{field}, fields...)
|
||||
grbuild.path = func(ctx context.Context) (prev *sql.Selector, err error) {
|
||||
if err := aq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return aq.sqlQuery(ctx), nil
|
||||
}
|
||||
aq.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &AttachmentGroupBy{build: aq}
|
||||
grbuild.flds = &aq.ctx.Fields
|
||||
grbuild.label = attachment.Label
|
||||
grbuild.flds, grbuild.scan = &grbuild.fields, grbuild.Scan
|
||||
grbuild.scan = grbuild.Scan
|
||||
return grbuild
|
||||
}
|
||||
|
||||
@@ -362,15 +365,30 @@ 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...)
|
||||
selbuild := &AttachmentSelect{AttachmentQuery: aq}
|
||||
selbuild.label = attachment.Label
|
||||
selbuild.flds, selbuild.scan = &aq.fields, selbuild.Scan
|
||||
return selbuild
|
||||
aq.ctx.Fields = append(aq.ctx.Fields, fields...)
|
||||
sbuild := &AttachmentSelect{AttachmentQuery: aq}
|
||||
sbuild.label = attachment.Label
|
||||
sbuild.flds, sbuild.scan = &aq.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
// Aggregate returns a AttachmentSelect configured with the given aggregations.
|
||||
func (aq *AttachmentQuery) Aggregate(fns ...AggregateFunc) *AttachmentSelect {
|
||||
return aq.Select().Aggregate(fns...)
|
||||
}
|
||||
|
||||
func (aq *AttachmentQuery) prepareQuery(ctx context.Context) error {
|
||||
for _, f := range aq.fields {
|
||||
for _, inter := range aq.inters {
|
||||
if inter == nil {
|
||||
return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
|
||||
}
|
||||
if trv, ok := inter.(Traverser); ok {
|
||||
if err := trv.Traverse(ctx, aq); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range aq.ctx.Fields {
|
||||
if !attachment.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
@@ -447,6 +465,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 {
|
||||
@@ -476,6 +497,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 {
|
||||
@@ -495,41 +519,22 @@ 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)
|
||||
}
|
||||
|
||||
func (aq *AttachmentQuery) sqlExist(ctx context.Context) (bool, error) {
|
||||
switch _, err := aq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
case err != nil:
|
||||
return false, fmt.Errorf("ent: check existence: %w", err)
|
||||
default:
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (aq *AttachmentQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
_spec := &sqlgraph.QuerySpec{
|
||||
Node: &sqlgraph.NodeSpec{
|
||||
Table: attachment.Table,
|
||||
Columns: attachment.Columns,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: attachment.FieldID,
|
||||
},
|
||||
},
|
||||
From: aq.sql,
|
||||
Unique: true,
|
||||
}
|
||||
if unique := aq.unique; unique != nil {
|
||||
_spec := sqlgraph.NewQuerySpec(attachment.Table, attachment.Columns, sqlgraph.NewFieldSpec(attachment.FieldID, field.TypeUUID))
|
||||
_spec.From = aq.sql
|
||||
if unique := aq.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
} else if aq.path != nil {
|
||||
_spec.Unique = true
|
||||
}
|
||||
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 {
|
||||
@@ -545,10 +550,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 {
|
||||
@@ -564,7 +569,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
|
||||
}
|
||||
@@ -573,7 +578,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 {
|
||||
@@ -582,12 +587,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
|
||||
@@ -595,13 +600,8 @@ func (aq *AttachmentQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
|
||||
// AttachmentGroupBy is the group-by builder for Attachment entities.
|
||||
type AttachmentGroupBy struct {
|
||||
config
|
||||
selector
|
||||
fields []string
|
||||
fns []AggregateFunc
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
build *AttachmentQuery
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the group-by query.
|
||||
@@ -610,74 +610,77 @@ func (agb *AttachmentGroupBy) Aggregate(fns ...AggregateFunc) *AttachmentGroupBy
|
||||
return agb
|
||||
}
|
||||
|
||||
// Scan applies the group-by query and scans the result into the given value.
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (agb *AttachmentGroupBy) Scan(ctx context.Context, v any) error {
|
||||
query, err := agb.path(ctx)
|
||||
if err != nil {
|
||||
ctx = setContextOp(ctx, agb.build.ctx, "GroupBy")
|
||||
if err := agb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
agb.sql = query
|
||||
return agb.sqlScan(ctx, v)
|
||||
return scanWithInterceptors[*AttachmentQuery, *AttachmentGroupBy](ctx, agb.build, agb, agb.build.inters, v)
|
||||
}
|
||||
|
||||
func (agb *AttachmentGroupBy) sqlScan(ctx context.Context, v any) error {
|
||||
for _, f := range agb.fields {
|
||||
if !attachment.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("invalid field %q for group-by", f)}
|
||||
}
|
||||
}
|
||||
selector := agb.sqlQuery()
|
||||
if err := selector.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := agb.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
func (agb *AttachmentGroupBy) sqlQuery() *sql.Selector {
|
||||
selector := agb.sql.Select()
|
||||
func (agb *AttachmentGroupBy) sqlScan(ctx context.Context, root *AttachmentQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx).Select()
|
||||
aggregation := make([]string, 0, len(agb.fns))
|
||||
for _, fn := range agb.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
// If no columns were selected in a custom aggregation function, the default
|
||||
// selection is the fields used for "group-by", and the aggregation functions.
|
||||
if len(selector.SelectedColumns()) == 0 {
|
||||
columns := make([]string, 0, len(agb.fields)+len(agb.fns))
|
||||
for _, f := range agb.fields {
|
||||
columns := make([]string, 0, len(*agb.flds)+len(agb.fns))
|
||||
for _, f := range *agb.flds {
|
||||
columns = append(columns, selector.C(f))
|
||||
}
|
||||
columns = append(columns, aggregation...)
|
||||
selector.Select(columns...)
|
||||
}
|
||||
return selector.GroupBy(selector.Columns(agb.fields...)...)
|
||||
selector.GroupBy(selector.Columns(*agb.flds...)...)
|
||||
if err := selector.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := agb.build.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
// AttachmentSelect is the builder for selecting fields of Attachment entities.
|
||||
type AttachmentSelect struct {
|
||||
*AttachmentQuery
|
||||
selector
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the selector query.
|
||||
func (as *AttachmentSelect) Aggregate(fns ...AggregateFunc) *AttachmentSelect {
|
||||
as.fns = append(as.fns, fns...)
|
||||
return as
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (as *AttachmentSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, as.ctx, "Select")
|
||||
if err := as.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
as.sql = as.AttachmentQuery.sqlQuery(ctx)
|
||||
return as.sqlScan(ctx, v)
|
||||
return scanWithInterceptors[*AttachmentQuery, *AttachmentSelect](ctx, as.AttachmentQuery, as, as.inters, v)
|
||||
}
|
||||
|
||||
func (as *AttachmentSelect) sqlScan(ctx context.Context, v any) error {
|
||||
func (as *AttachmentSelect) sqlScan(ctx context.Context, root *AttachmentQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx)
|
||||
aggregation := make([]string, 0, len(as.fns))
|
||||
for _, fn := range as.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
switch n := len(*as.selector.flds); {
|
||||
case n == 0 && len(aggregation) > 0:
|
||||
selector.Select(aggregation...)
|
||||
case n != 0 && len(aggregation) > 0:
|
||||
selector.AppendSelect(aggregation...)
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := as.sql.Query()
|
||||
query, args := selector.Query()
|
||||
if err := as.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -92,41 +92,8 @@ func (au *AttachmentUpdate) ClearDocument() *AttachmentUpdate {
|
||||
|
||||
// Save executes the query and returns the number of nodes affected by the update operation.
|
||||
func (au *AttachmentUpdate) Save(ctx context.Context) (int, error) {
|
||||
var (
|
||||
err error
|
||||
affected int
|
||||
)
|
||||
au.defaults()
|
||||
if len(au.hooks) == 0 {
|
||||
if err = au.check(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
affected, err = au.sqlSave(ctx)
|
||||
} else {
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*AttachmentMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
if err = au.check(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
au.mutation = mutation
|
||||
affected, err = au.sqlSave(ctx)
|
||||
mutation.done = true
|
||||
return affected, err
|
||||
})
|
||||
for i := len(au.hooks) - 1; i >= 0; i-- {
|
||||
if au.hooks[i] == nil {
|
||||
return 0, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = au.hooks[i](mut)
|
||||
}
|
||||
if _, err := mut.Mutate(ctx, au.mutation); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
return affected, err
|
||||
return withHooks[int, AttachmentMutation](ctx, au.sqlSave, au.mutation, au.hooks)
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
@@ -176,16 +143,10 @@ func (au *AttachmentUpdate) check() error {
|
||||
}
|
||||
|
||||
func (au *AttachmentUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
_spec := &sqlgraph.UpdateSpec{
|
||||
Node: &sqlgraph.NodeSpec{
|
||||
Table: attachment.Table,
|
||||
Columns: attachment.Columns,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: attachment.FieldID,
|
||||
},
|
||||
},
|
||||
if err := au.check(); err != nil {
|
||||
return n, err
|
||||
}
|
||||
_spec := sqlgraph.NewUpdateSpec(attachment.Table, attachment.Columns, sqlgraph.NewFieldSpec(attachment.FieldID, field.TypeUUID))
|
||||
if ps := au.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
@@ -194,18 +155,10 @@ func (au *AttachmentUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
}
|
||||
}
|
||||
if value, ok := au.mutation.UpdatedAt(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: attachment.FieldUpdatedAt,
|
||||
})
|
||||
_spec.SetField(attachment.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if value, ok := au.mutation.GetType(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeEnum,
|
||||
Value: value,
|
||||
Column: attachment.FieldType,
|
||||
})
|
||||
_spec.SetField(attachment.FieldType, field.TypeEnum, value)
|
||||
}
|
||||
if au.mutation.ItemCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
@@ -285,6 +238,7 @@ func (au *AttachmentUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
au.mutation.done = true
|
||||
return n, nil
|
||||
}
|
||||
|
||||
@@ -355,6 +309,12 @@ func (auo *AttachmentUpdateOne) ClearDocument() *AttachmentUpdateOne {
|
||||
return auo
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the AttachmentUpdate builder.
|
||||
func (auo *AttachmentUpdateOne) Where(ps ...predicate.Attachment) *AttachmentUpdateOne {
|
||||
auo.mutation.Where(ps...)
|
||||
return auo
|
||||
}
|
||||
|
||||
// Select allows selecting one or more fields (columns) of the returned entity.
|
||||
// The default is selecting all fields defined in the entity schema.
|
||||
func (auo *AttachmentUpdateOne) Select(field string, fields ...string) *AttachmentUpdateOne {
|
||||
@@ -364,47 +324,8 @@ func (auo *AttachmentUpdateOne) Select(field string, fields ...string) *Attachme
|
||||
|
||||
// Save executes the query and returns the updated Attachment entity.
|
||||
func (auo *AttachmentUpdateOne) Save(ctx context.Context) (*Attachment, error) {
|
||||
var (
|
||||
err error
|
||||
node *Attachment
|
||||
)
|
||||
auo.defaults()
|
||||
if len(auo.hooks) == 0 {
|
||||
if err = auo.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node, err = auo.sqlSave(ctx)
|
||||
} else {
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*AttachmentMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
if err = auo.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
auo.mutation = mutation
|
||||
node, err = auo.sqlSave(ctx)
|
||||
mutation.done = true
|
||||
return node, err
|
||||
})
|
||||
for i := len(auo.hooks) - 1; i >= 0; i-- {
|
||||
if auo.hooks[i] == nil {
|
||||
return nil, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = auo.hooks[i](mut)
|
||||
}
|
||||
v, err := mut.Mutate(ctx, auo.mutation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nv, ok := v.(*Attachment)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected node type %T returned from AttachmentMutation", v)
|
||||
}
|
||||
node = nv
|
||||
}
|
||||
return node, err
|
||||
return withHooks[*Attachment, AttachmentMutation](ctx, auo.sqlSave, auo.mutation, auo.hooks)
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
@@ -454,16 +375,10 @@ func (auo *AttachmentUpdateOne) check() error {
|
||||
}
|
||||
|
||||
func (auo *AttachmentUpdateOne) sqlSave(ctx context.Context) (_node *Attachment, err error) {
|
||||
_spec := &sqlgraph.UpdateSpec{
|
||||
Node: &sqlgraph.NodeSpec{
|
||||
Table: attachment.Table,
|
||||
Columns: attachment.Columns,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: attachment.FieldID,
|
||||
},
|
||||
},
|
||||
if err := auo.check(); err != nil {
|
||||
return _node, err
|
||||
}
|
||||
_spec := sqlgraph.NewUpdateSpec(attachment.Table, attachment.Columns, sqlgraph.NewFieldSpec(attachment.FieldID, field.TypeUUID))
|
||||
id, ok := auo.mutation.ID()
|
||||
if !ok {
|
||||
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "Attachment.id" for update`)}
|
||||
@@ -489,18 +404,10 @@ func (auo *AttachmentUpdateOne) sqlSave(ctx context.Context) (_node *Attachment,
|
||||
}
|
||||
}
|
||||
if value, ok := auo.mutation.UpdatedAt(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: attachment.FieldUpdatedAt,
|
||||
})
|
||||
_spec.SetField(attachment.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if value, ok := auo.mutation.GetType(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeEnum,
|
||||
Value: value,
|
||||
Column: attachment.FieldType,
|
||||
})
|
||||
_spec.SetField(attachment.FieldType, field.TypeEnum, value)
|
||||
}
|
||||
if auo.mutation.ItemCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
@@ -583,5 +490,6 @@ func (auo *AttachmentUpdateOne) sqlSave(ctx context.Context) (_node *Attachment,
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
auo.mutation.done = true
|
||||
return _node, nil
|
||||
}
|
||||
|
||||
135
backend/internal/data/ent/authroles.go
Normal file
135
backend/internal/data/ent/authroles.go
Normal file
@@ -0,0 +1,135 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
)
|
||||
|
||||
// AuthRoles is the model entity for the AuthRoles schema.
|
||||
type AuthRoles struct {
|
||||
config `json:"-"`
|
||||
// ID of the ent.
|
||||
ID int `json:"id,omitempty"`
|
||||
// Role holds the value of the "role" field.
|
||||
Role authroles.Role `json:"role,omitempty"`
|
||||
// Edges holds the relations/edges for other nodes in the graph.
|
||||
// The values are being populated by the AuthRolesQuery when eager-loading is set.
|
||||
Edges AuthRolesEdges `json:"edges"`
|
||||
auth_tokens_roles *uuid.UUID
|
||||
}
|
||||
|
||||
// AuthRolesEdges holds the relations/edges for other nodes in the graph.
|
||||
type AuthRolesEdges struct {
|
||||
// Token holds the value of the token edge.
|
||||
Token *AuthTokens `json:"token,omitempty"`
|
||||
// loadedTypes holds the information for reporting if a
|
||||
// type was loaded (or requested) in eager-loading or not.
|
||||
loadedTypes [1]bool
|
||||
}
|
||||
|
||||
// TokenOrErr returns the Token value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e AuthRolesEdges) TokenOrErr() (*AuthTokens, error) {
|
||||
if e.loadedTypes[0] {
|
||||
if e.Token == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: authtokens.Label}
|
||||
}
|
||||
return e.Token, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "token"}
|
||||
}
|
||||
|
||||
// scanValues returns the types for scanning values from sql.Rows.
|
||||
func (*AuthRoles) scanValues(columns []string) ([]any, error) {
|
||||
values := make([]any, len(columns))
|
||||
for i := range columns {
|
||||
switch columns[i] {
|
||||
case authroles.FieldID:
|
||||
values[i] = new(sql.NullInt64)
|
||||
case authroles.FieldRole:
|
||||
values[i] = new(sql.NullString)
|
||||
case authroles.ForeignKeys[0]: // auth_tokens_roles
|
||||
values[i] = &sql.NullScanner{S: new(uuid.UUID)}
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected column %q for type AuthRoles", columns[i])
|
||||
}
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// assignValues assigns the values that were returned from sql.Rows (after scanning)
|
||||
// to the AuthRoles fields.
|
||||
func (ar *AuthRoles) assignValues(columns []string, values []any) error {
|
||||
if m, n := len(values), len(columns); m < n {
|
||||
return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
|
||||
}
|
||||
for i := range columns {
|
||||
switch columns[i] {
|
||||
case authroles.FieldID:
|
||||
value, ok := values[i].(*sql.NullInt64)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field id", value)
|
||||
}
|
||||
ar.ID = int(value.Int64)
|
||||
case authroles.FieldRole:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field role", values[i])
|
||||
} else if value.Valid {
|
||||
ar.Role = authroles.Role(value.String)
|
||||
}
|
||||
case authroles.ForeignKeys[0]:
|
||||
if value, ok := values[i].(*sql.NullScanner); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field auth_tokens_roles", values[i])
|
||||
} else if value.Valid {
|
||||
ar.auth_tokens_roles = new(uuid.UUID)
|
||||
*ar.auth_tokens_roles = *value.S.(*uuid.UUID)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// QueryToken queries the "token" edge of the AuthRoles entity.
|
||||
func (ar *AuthRoles) QueryToken() *AuthTokensQuery {
|
||||
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 NewAuthRolesClient(ar.config).UpdateOne(ar)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the AuthRoles entity that was returned from a transaction after it was closed,
|
||||
// so that all future queries will be executed through the driver which created the transaction.
|
||||
func (ar *AuthRoles) Unwrap() *AuthRoles {
|
||||
_tx, ok := ar.config.driver.(*txDriver)
|
||||
if !ok {
|
||||
panic("ent: AuthRoles is not a transactional entity")
|
||||
}
|
||||
ar.config.driver = _tx.drv
|
||||
return ar
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer.
|
||||
func (ar *AuthRoles) String() string {
|
||||
var builder strings.Builder
|
||||
builder.WriteString("AuthRoles(")
|
||||
builder.WriteString(fmt.Sprintf("id=%v, ", ar.ID))
|
||||
builder.WriteString("role=")
|
||||
builder.WriteString(fmt.Sprintf("%v", ar.Role))
|
||||
builder.WriteByte(')')
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
// AuthRolesSlice is a parsable slice of AuthRoles.
|
||||
type AuthRolesSlice []*AuthRoles
|
||||
81
backend/internal/data/ent/authroles/authroles.go
Normal file
81
backend/internal/data/ent/authroles/authroles.go
Normal file
@@ -0,0 +1,81 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package authroles
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
const (
|
||||
// Label holds the string label denoting the authroles type in the database.
|
||||
Label = "auth_roles"
|
||||
// FieldID holds the string denoting the id field in the database.
|
||||
FieldID = "id"
|
||||
// FieldRole holds the string denoting the role field in the database.
|
||||
FieldRole = "role"
|
||||
// EdgeToken holds the string denoting the token edge name in mutations.
|
||||
EdgeToken = "token"
|
||||
// Table holds the table name of the authroles in the database.
|
||||
Table = "auth_roles"
|
||||
// TokenTable is the table that holds the token relation/edge.
|
||||
TokenTable = "auth_roles"
|
||||
// TokenInverseTable is the table name for the AuthTokens entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "authtokens" package.
|
||||
TokenInverseTable = "auth_tokens"
|
||||
// TokenColumn is the table column denoting the token relation/edge.
|
||||
TokenColumn = "auth_tokens_roles"
|
||||
)
|
||||
|
||||
// Columns holds all SQL columns for authroles fields.
|
||||
var Columns = []string{
|
||||
FieldID,
|
||||
FieldRole,
|
||||
}
|
||||
|
||||
// ForeignKeys holds the SQL foreign-keys that are owned by the "auth_roles"
|
||||
// table and are not defined as standalone fields in the schema.
|
||||
var ForeignKeys = []string{
|
||||
"auth_tokens_roles",
|
||||
}
|
||||
|
||||
// ValidColumn reports if the column name is valid (part of the table columns).
|
||||
func ValidColumn(column string) bool {
|
||||
for i := range Columns {
|
||||
if column == Columns[i] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for i := range ForeignKeys {
|
||||
if column == ForeignKeys[i] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Role defines the type for the "role" enum field.
|
||||
type Role string
|
||||
|
||||
// RoleUser is the default value of the Role enum.
|
||||
const DefaultRole = RoleUser
|
||||
|
||||
// Role values.
|
||||
const (
|
||||
RoleAdmin Role = "admin"
|
||||
RoleUser Role = "user"
|
||||
RoleAttachments Role = "attachments"
|
||||
)
|
||||
|
||||
func (r Role) String() string {
|
||||
return string(r)
|
||||
}
|
||||
|
||||
// RoleValidator is a validator for the "role" field enum values. It is called by the builders before save.
|
||||
func RoleValidator(r Role) error {
|
||||
switch r {
|
||||
case RoleAdmin, RoleUser, RoleAttachments:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("authroles: invalid enum value for role field: %q", r)
|
||||
}
|
||||
}
|
||||
133
backend/internal/data/ent/authroles/where.go
Normal file
133
backend/internal/data/ent/authroles/where.go
Normal file
@@ -0,0 +1,133 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package authroles
|
||||
|
||||
import (
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||
)
|
||||
|
||||
// ID filters vertices based on their ID field.
|
||||
func ID(id int) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDEQ applies the EQ predicate on the ID field.
|
||||
func IDEQ(id int) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDNEQ applies the NEQ predicate on the ID field.
|
||||
func IDNEQ(id int) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(sql.FieldNEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDIn applies the In predicate on the ID field.
|
||||
func IDIn(ids ...int) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(sql.FieldIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDNotIn applies the NotIn predicate on the ID field.
|
||||
func IDNotIn(ids ...int) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(sql.FieldNotIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDGT applies the GT predicate on the ID field.
|
||||
func IDGT(id int) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(sql.FieldGT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDGTE applies the GTE predicate on the ID field.
|
||||
func IDGTE(id int) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(sql.FieldGTE(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLT applies the LT predicate on the ID field.
|
||||
func IDLT(id int) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(sql.FieldLT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLTE applies the LTE predicate on the ID field.
|
||||
func IDLTE(id int) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(sql.FieldLTE(FieldID, id))
|
||||
}
|
||||
|
||||
// RoleEQ applies the EQ predicate on the "role" field.
|
||||
func RoleEQ(v Role) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(sql.FieldEQ(FieldRole, v))
|
||||
}
|
||||
|
||||
// RoleNEQ applies the NEQ predicate on the "role" field.
|
||||
func RoleNEQ(v Role) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(sql.FieldNEQ(FieldRole, v))
|
||||
}
|
||||
|
||||
// RoleIn applies the In predicate on the "role" field.
|
||||
func RoleIn(vs ...Role) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(sql.FieldIn(FieldRole, vs...))
|
||||
}
|
||||
|
||||
// RoleNotIn applies the NotIn predicate on the "role" field.
|
||||
func RoleNotIn(vs ...Role) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(sql.FieldNotIn(FieldRole, vs...))
|
||||
}
|
||||
|
||||
// HasToken applies the HasEdge predicate on the "token" edge.
|
||||
func HasToken() predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2O, true, TokenTable, TokenColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasTokenWith applies the HasEdge predicate on the "token" edge with a given conditions (other predicates).
|
||||
func HasTokenWith(preds ...predicate.AuthTokens) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(TokenInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2O, true, TokenTable, TokenColumn),
|
||||
)
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// And groups predicates with the AND operator between them.
|
||||
func And(predicates ...predicate.AuthRoles) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
s1 := s.Clone().SetP(nil)
|
||||
for _, p := range predicates {
|
||||
p(s1)
|
||||
}
|
||||
s.Where(s1.P())
|
||||
})
|
||||
}
|
||||
|
||||
// Or groups predicates with the OR operator between them.
|
||||
func Or(predicates ...predicate.AuthRoles) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
s1 := s.Clone().SetP(nil)
|
||||
for i, p := range predicates {
|
||||
if i > 0 {
|
||||
s1.Or()
|
||||
}
|
||||
p(s1)
|
||||
}
|
||||
s.Where(s1.P())
|
||||
})
|
||||
}
|
||||
|
||||
// Not applies the not operator on the given predicate.
|
||||
func Not(p predicate.AuthRoles) predicate.AuthRoles {
|
||||
return predicate.AuthRoles(func(s *sql.Selector) {
|
||||
p(s.Not())
|
||||
})
|
||||
}
|
||||
243
backend/internal/data/ent/authroles_create.go
Normal file
243
backend/internal/data/ent/authroles_create.go
Normal file
@@ -0,0 +1,243 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
)
|
||||
|
||||
// AuthRolesCreate is the builder for creating a AuthRoles entity.
|
||||
type AuthRolesCreate struct {
|
||||
config
|
||||
mutation *AuthRolesMutation
|
||||
hooks []Hook
|
||||
}
|
||||
|
||||
// SetRole sets the "role" field.
|
||||
func (arc *AuthRolesCreate) SetRole(a authroles.Role) *AuthRolesCreate {
|
||||
arc.mutation.SetRole(a)
|
||||
return arc
|
||||
}
|
||||
|
||||
// SetNillableRole sets the "role" field if the given value is not nil.
|
||||
func (arc *AuthRolesCreate) SetNillableRole(a *authroles.Role) *AuthRolesCreate {
|
||||
if a != nil {
|
||||
arc.SetRole(*a)
|
||||
}
|
||||
return arc
|
||||
}
|
||||
|
||||
// SetTokenID sets the "token" edge to the AuthTokens entity by ID.
|
||||
func (arc *AuthRolesCreate) SetTokenID(id uuid.UUID) *AuthRolesCreate {
|
||||
arc.mutation.SetTokenID(id)
|
||||
return arc
|
||||
}
|
||||
|
||||
// SetNillableTokenID sets the "token" edge to the AuthTokens entity by ID if the given value is not nil.
|
||||
func (arc *AuthRolesCreate) SetNillableTokenID(id *uuid.UUID) *AuthRolesCreate {
|
||||
if id != nil {
|
||||
arc = arc.SetTokenID(*id)
|
||||
}
|
||||
return arc
|
||||
}
|
||||
|
||||
// SetToken sets the "token" edge to the AuthTokens entity.
|
||||
func (arc *AuthRolesCreate) SetToken(a *AuthTokens) *AuthRolesCreate {
|
||||
return arc.SetTokenID(a.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the AuthRolesMutation object of the builder.
|
||||
func (arc *AuthRolesCreate) Mutation() *AuthRolesMutation {
|
||||
return arc.mutation
|
||||
}
|
||||
|
||||
// Save creates the AuthRoles in the database.
|
||||
func (arc *AuthRolesCreate) Save(ctx context.Context) (*AuthRoles, error) {
|
||||
arc.defaults()
|
||||
return withHooks[*AuthRoles, AuthRolesMutation](ctx, arc.sqlSave, arc.mutation, arc.hooks)
|
||||
}
|
||||
|
||||
// SaveX calls Save and panics if Save returns an error.
|
||||
func (arc *AuthRolesCreate) SaveX(ctx context.Context) *AuthRoles {
|
||||
v, err := arc.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (arc *AuthRolesCreate) Exec(ctx context.Context) error {
|
||||
_, err := arc.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (arc *AuthRolesCreate) ExecX(ctx context.Context) {
|
||||
if err := arc.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (arc *AuthRolesCreate) defaults() {
|
||||
if _, ok := arc.mutation.Role(); !ok {
|
||||
v := authroles.DefaultRole
|
||||
arc.mutation.SetRole(v)
|
||||
}
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (arc *AuthRolesCreate) check() error {
|
||||
if _, ok := arc.mutation.Role(); !ok {
|
||||
return &ValidationError{Name: "role", err: errors.New(`ent: missing required field "AuthRoles.role"`)}
|
||||
}
|
||||
if v, ok := arc.mutation.Role(); ok {
|
||||
if err := authroles.RoleValidator(v); err != nil {
|
||||
return &ValidationError{Name: "role", err: fmt.Errorf(`ent: validator failed for field "AuthRoles.role": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (arc *AuthRolesCreate) sqlSave(ctx context.Context) (*AuthRoles, error) {
|
||||
if err := arc.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_node, _spec := arc.createSpec()
|
||||
if err := sqlgraph.CreateNode(ctx, arc.driver, _spec); err != nil {
|
||||
if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
id := _spec.ID.Value.(int64)
|
||||
_node.ID = int(id)
|
||||
arc.mutation.id = &_node.ID
|
||||
arc.mutation.done = true
|
||||
return _node, nil
|
||||
}
|
||||
|
||||
func (arc *AuthRolesCreate) createSpec() (*AuthRoles, *sqlgraph.CreateSpec) {
|
||||
var (
|
||||
_node = &AuthRoles{config: arc.config}
|
||||
_spec = sqlgraph.NewCreateSpec(authroles.Table, sqlgraph.NewFieldSpec(authroles.FieldID, field.TypeInt))
|
||||
)
|
||||
if value, ok := arc.mutation.Role(); ok {
|
||||
_spec.SetField(authroles.FieldRole, field.TypeEnum, value)
|
||||
_node.Role = value
|
||||
}
|
||||
if nodes := arc.mutation.TokenIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2O,
|
||||
Inverse: true,
|
||||
Table: authroles.TokenTable,
|
||||
Columns: []string{authroles.TokenColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: authtokens.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_node.auth_tokens_roles = &nodes[0]
|
||||
_spec.Edges = append(_spec.Edges, edge)
|
||||
}
|
||||
return _node, _spec
|
||||
}
|
||||
|
||||
// AuthRolesCreateBulk is the builder for creating many AuthRoles entities in bulk.
|
||||
type AuthRolesCreateBulk struct {
|
||||
config
|
||||
builders []*AuthRolesCreate
|
||||
}
|
||||
|
||||
// Save creates the AuthRoles entities in the database.
|
||||
func (arcb *AuthRolesCreateBulk) Save(ctx context.Context) ([]*AuthRoles, error) {
|
||||
specs := make([]*sqlgraph.CreateSpec, len(arcb.builders))
|
||||
nodes := make([]*AuthRoles, len(arcb.builders))
|
||||
mutators := make([]Mutator, len(arcb.builders))
|
||||
for i := range arcb.builders {
|
||||
func(i int, root context.Context) {
|
||||
builder := arcb.builders[i]
|
||||
builder.defaults()
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*AuthRolesMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
if err := builder.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
builder.mutation = mutation
|
||||
nodes[i], specs[i] = builder.createSpec()
|
||||
var err error
|
||||
if i < len(mutators)-1 {
|
||||
_, err = mutators[i+1].Mutate(root, arcb.builders[i+1].mutation)
|
||||
} else {
|
||||
spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
|
||||
// Invoke the actual operation on the latest mutation in the chain.
|
||||
if err = sqlgraph.BatchCreate(ctx, arcb.driver, spec); err != nil {
|
||||
if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mutation.id = &nodes[i].ID
|
||||
if specs[i].ID.Value != nil {
|
||||
id := specs[i].ID.Value.(int64)
|
||||
nodes[i].ID = int(id)
|
||||
}
|
||||
mutation.done = true
|
||||
return nodes[i], nil
|
||||
})
|
||||
for i := len(builder.hooks) - 1; i >= 0; i-- {
|
||||
mut = builder.hooks[i](mut)
|
||||
}
|
||||
mutators[i] = mut
|
||||
}(i, ctx)
|
||||
}
|
||||
if len(mutators) > 0 {
|
||||
if _, err := mutators[0].Mutate(ctx, arcb.builders[0].mutation); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (arcb *AuthRolesCreateBulk) SaveX(ctx context.Context) []*AuthRoles {
|
||||
v, err := arcb.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (arcb *AuthRolesCreateBulk) Exec(ctx context.Context) error {
|
||||
_, err := arcb.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (arcb *AuthRolesCreateBulk) ExecX(ctx context.Context) {
|
||||
if err := arcb.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
88
backend/internal/data/ent/authroles_delete.go
Normal file
88
backend/internal/data/ent/authroles_delete.go
Normal file
@@ -0,0 +1,88 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||
)
|
||||
|
||||
// AuthRolesDelete is the builder for deleting a AuthRoles entity.
|
||||
type AuthRolesDelete struct {
|
||||
config
|
||||
hooks []Hook
|
||||
mutation *AuthRolesMutation
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the AuthRolesDelete builder.
|
||||
func (ard *AuthRolesDelete) Where(ps ...predicate.AuthRoles) *AuthRolesDelete {
|
||||
ard.mutation.Where(ps...)
|
||||
return ard
|
||||
}
|
||||
|
||||
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||
func (ard *AuthRolesDelete) Exec(ctx context.Context) (int, error) {
|
||||
return withHooks[int, AuthRolesMutation](ctx, ard.sqlExec, ard.mutation, ard.hooks)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (ard *AuthRolesDelete) ExecX(ctx context.Context) int {
|
||||
n, err := ard.Exec(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (ard *AuthRolesDelete) sqlExec(ctx context.Context) (int, error) {
|
||||
_spec := sqlgraph.NewDeleteSpec(authroles.Table, sqlgraph.NewFieldSpec(authroles.FieldID, field.TypeInt))
|
||||
if ps := ard.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
affected, err := sqlgraph.DeleteNodes(ctx, ard.driver, _spec)
|
||||
if err != nil && sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
ard.mutation.done = true
|
||||
return affected, err
|
||||
}
|
||||
|
||||
// AuthRolesDeleteOne is the builder for deleting a single AuthRoles entity.
|
||||
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)
|
||||
switch {
|
||||
case err != nil:
|
||||
return err
|
||||
case n == 0:
|
||||
return &NotFoundError{authroles.Label}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (ardo *AuthRolesDeleteOne) ExecX(ctx context.Context) {
|
||||
if err := ardo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
614
backend/internal/data/ent/authroles_query.go
Normal file
614
backend/internal/data/ent/authroles_query.go
Normal file
@@ -0,0 +1,614 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||
)
|
||||
|
||||
// AuthRolesQuery is the builder for querying AuthRoles entities.
|
||||
type AuthRolesQuery struct {
|
||||
config
|
||||
ctx *QueryContext
|
||||
order []OrderFunc
|
||||
inters []Interceptor
|
||||
predicates []predicate.AuthRoles
|
||||
withToken *AuthTokensQuery
|
||||
withFKs bool
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the AuthRolesQuery builder.
|
||||
func (arq *AuthRolesQuery) Where(ps ...predicate.AuthRoles) *AuthRolesQuery {
|
||||
arq.predicates = append(arq.predicates, ps...)
|
||||
return arq
|
||||
}
|
||||
|
||||
// Limit the number of records to be returned by this query.
|
||||
func (arq *AuthRolesQuery) Limit(limit int) *AuthRolesQuery {
|
||||
arq.ctx.Limit = &limit
|
||||
return arq
|
||||
}
|
||||
|
||||
// Offset to start from.
|
||||
func (arq *AuthRolesQuery) Offset(offset int) *AuthRolesQuery {
|
||||
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.ctx.Unique = &unique
|
||||
return arq
|
||||
}
|
||||
|
||||
// Order specifies how the records should be ordered.
|
||||
func (arq *AuthRolesQuery) Order(o ...OrderFunc) *AuthRolesQuery {
|
||||
arq.order = append(arq.order, o...)
|
||||
return arq
|
||||
}
|
||||
|
||||
// QueryToken chains the current query on the "token" edge.
|
||||
func (arq *AuthRolesQuery) QueryToken() *AuthTokensQuery {
|
||||
query := (&AuthTokensClient{config: arq.config}).Query()
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := arq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector := arq.sqlQuery(ctx)
|
||||
if err := selector.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(authroles.Table, authroles.FieldID, selector),
|
||||
sqlgraph.To(authtokens.Table, authtokens.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2O, true, authroles.TokenTable, authroles.TokenColumn),
|
||||
)
|
||||
fromU = sqlgraph.SetNeighbors(arq.driver.Dialect(), step)
|
||||
return fromU, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// 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(setContextOp(ctx, arq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nil, &NotFoundError{authroles.Label}
|
||||
}
|
||||
return nodes[0], nil
|
||||
}
|
||||
|
||||
// FirstX is like First, but panics if an error occurs.
|
||||
func (arq *AuthRolesQuery) FirstX(ctx context.Context) *AuthRoles {
|
||||
node, err := arq.First(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// FirstID returns the first AuthRoles ID from the query.
|
||||
// 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(setContextOp(ctx, arq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
err = &NotFoundError{authroles.Label}
|
||||
return
|
||||
}
|
||||
return ids[0], nil
|
||||
}
|
||||
|
||||
// FirstIDX is like FirstID, but panics if an error occurs.
|
||||
func (arq *AuthRolesQuery) FirstIDX(ctx context.Context) int {
|
||||
id, err := arq.FirstID(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// Only returns a single AuthRoles entity found by the query, ensuring it only returns one.
|
||||
// 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(setContextOp(ctx, arq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch len(nodes) {
|
||||
case 1:
|
||||
return nodes[0], nil
|
||||
case 0:
|
||||
return nil, &NotFoundError{authroles.Label}
|
||||
default:
|
||||
return nil, &NotSingularError{authroles.Label}
|
||||
}
|
||||
}
|
||||
|
||||
// OnlyX is like Only, but panics if an error occurs.
|
||||
func (arq *AuthRolesQuery) OnlyX(ctx context.Context) *AuthRoles {
|
||||
node, err := arq.Only(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// OnlyID is like Only, but returns the only AuthRoles ID in the query.
|
||||
// Returns a *NotSingularError when more than one AuthRoles ID is found.
|
||||
// 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(setContextOp(ctx, arq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
case 1:
|
||||
id = ids[0]
|
||||
case 0:
|
||||
err = &NotFoundError{authroles.Label}
|
||||
default:
|
||||
err = &NotSingularError{authroles.Label}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// OnlyIDX is like OnlyID, but panics if an error occurs.
|
||||
func (arq *AuthRolesQuery) OnlyIDX(ctx context.Context) int {
|
||||
id, err := arq.OnlyID(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// All executes the query and returns a list of AuthRolesSlice.
|
||||
func (arq *AuthRolesQuery) All(ctx context.Context) ([]*AuthRoles, error) {
|
||||
ctx = setContextOp(ctx, arq.ctx, "All")
|
||||
if err := arq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
qr := querierAll[[]*AuthRoles, *AuthRolesQuery]()
|
||||
return withInterceptors[[]*AuthRoles](ctx, arq, qr, arq.inters)
|
||||
}
|
||||
|
||||
// AllX is like All, but panics if an error occurs.
|
||||
func (arq *AuthRolesQuery) AllX(ctx context.Context) []*AuthRoles {
|
||||
nodes, err := arq.All(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
// IDs executes the query and returns a list of AuthRoles IDs.
|
||||
func (arq *AuthRolesQuery) IDs(ctx context.Context) (ids []int, err error) {
|
||||
if arq.ctx.Unique == nil && arq.path != nil {
|
||||
arq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, arq.ctx, "IDs")
|
||||
if err = arq.Select(authroles.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
// IDsX is like IDs, but panics if an error occurs.
|
||||
func (arq *AuthRolesQuery) IDsX(ctx context.Context) []int {
|
||||
ids, err := arq.IDs(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (arq *AuthRolesQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, arq.ctx, "Count")
|
||||
if err := arq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return withInterceptors[int](ctx, arq, querierCount[*AuthRolesQuery](), arq.inters)
|
||||
}
|
||||
|
||||
// CountX is like Count, but panics if an error occurs.
|
||||
func (arq *AuthRolesQuery) CountX(ctx context.Context) int {
|
||||
count, err := arq.Count(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (arq *AuthRolesQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, arq.ctx, "Exist")
|
||||
switch _, err := arq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
case err != nil:
|
||||
return false, fmt.Errorf("ent: check existence: %w", err)
|
||||
default:
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
// ExistX is like Exist, but panics if an error occurs.
|
||||
func (arq *AuthRolesQuery) ExistX(ctx context.Context) bool {
|
||||
exist, err := arq.Exist(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return exist
|
||||
}
|
||||
|
||||
// Clone returns a duplicate of the AuthRolesQuery builder, including all associated steps. It can be
|
||||
// used to prepare common query builders and use them differently after the clone is made.
|
||||
func (arq *AuthRolesQuery) Clone() *AuthRolesQuery {
|
||||
if arq == nil {
|
||||
return nil
|
||||
}
|
||||
return &AuthRolesQuery{
|
||||
config: arq.config,
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
// WithToken tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "token" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (arq *AuthRolesQuery) WithToken(opts ...func(*AuthTokensQuery)) *AuthRolesQuery {
|
||||
query := (&AuthTokensClient{config: arq.config}).Query()
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
arq.withToken = query
|
||||
return arq
|
||||
}
|
||||
|
||||
// GroupBy is used to group vertices by one or more fields/columns.
|
||||
// It is often used with aggregate functions, like: count, max, mean, min, sum.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// var v []struct {
|
||||
// Role authroles.Role `json:"role,omitempty"`
|
||||
// Count int `json:"count,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.AuthRoles.Query().
|
||||
// GroupBy(authroles.FieldRole).
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (arq *AuthRolesQuery) GroupBy(field string, fields ...string) *AuthRolesGroupBy {
|
||||
arq.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &AuthRolesGroupBy{build: arq}
|
||||
grbuild.flds = &arq.ctx.Fields
|
||||
grbuild.label = authroles.Label
|
||||
grbuild.scan = grbuild.Scan
|
||||
return grbuild
|
||||
}
|
||||
|
||||
// Select allows the selection one or more fields/columns for the given query,
|
||||
// instead of selecting all fields in the entity.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// var v []struct {
|
||||
// Role authroles.Role `json:"role,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.AuthRoles.Query().
|
||||
// Select(authroles.FieldRole).
|
||||
// Scan(ctx, &v)
|
||||
func (arq *AuthRolesQuery) Select(fields ...string) *AuthRolesSelect {
|
||||
arq.ctx.Fields = append(arq.ctx.Fields, fields...)
|
||||
sbuild := &AuthRolesSelect{AuthRolesQuery: arq}
|
||||
sbuild.label = authroles.Label
|
||||
sbuild.flds, sbuild.scan = &arq.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
// Aggregate returns a AuthRolesSelect configured with the given aggregations.
|
||||
func (arq *AuthRolesQuery) Aggregate(fns ...AggregateFunc) *AuthRolesSelect {
|
||||
return arq.Select().Aggregate(fns...)
|
||||
}
|
||||
|
||||
func (arq *AuthRolesQuery) prepareQuery(ctx context.Context) error {
|
||||
for _, inter := range arq.inters {
|
||||
if inter == nil {
|
||||
return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
|
||||
}
|
||||
if trv, ok := inter.(Traverser); ok {
|
||||
if err := trv.Traverse(ctx, arq); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range arq.ctx.Fields {
|
||||
if !authroles.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
}
|
||||
if arq.path != nil {
|
||||
prev, err := arq.path(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
arq.sql = prev
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (arq *AuthRolesQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*AuthRoles, error) {
|
||||
var (
|
||||
nodes = []*AuthRoles{}
|
||||
withFKs = arq.withFKs
|
||||
_spec = arq.querySpec()
|
||||
loadedTypes = [1]bool{
|
||||
arq.withToken != nil,
|
||||
}
|
||||
)
|
||||
if arq.withToken != nil {
|
||||
withFKs = true
|
||||
}
|
||||
if withFKs {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, authroles.ForeignKeys...)
|
||||
}
|
||||
_spec.ScanValues = func(columns []string) ([]any, error) {
|
||||
return (*AuthRoles).scanValues(nil, columns)
|
||||
}
|
||||
_spec.Assign = func(columns []string, values []any) error {
|
||||
node := &AuthRoles{config: arq.config}
|
||||
nodes = append(nodes, node)
|
||||
node.Edges.loadedTypes = loadedTypes
|
||||
return node.assignValues(columns, values)
|
||||
}
|
||||
for i := range hooks {
|
||||
hooks[i](ctx, _spec)
|
||||
}
|
||||
if err := sqlgraph.QueryNodes(ctx, arq.driver, _spec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nodes, nil
|
||||
}
|
||||
if query := arq.withToken; query != nil {
|
||||
if err := arq.loadToken(ctx, query, nodes, nil,
|
||||
func(n *AuthRoles, e *AuthTokens) { n.Edges.Token = e }); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
func (arq *AuthRolesQuery) loadToken(ctx context.Context, query *AuthTokensQuery, nodes []*AuthRoles, init func(*AuthRoles), assign func(*AuthRoles, *AuthTokens)) error {
|
||||
ids := make([]uuid.UUID, 0, len(nodes))
|
||||
nodeids := make(map[uuid.UUID][]*AuthRoles)
|
||||
for i := range nodes {
|
||||
if nodes[i].auth_tokens_roles == nil {
|
||||
continue
|
||||
}
|
||||
fk := *nodes[i].auth_tokens_roles
|
||||
if _, ok := nodeids[fk]; !ok {
|
||||
ids = append(ids, fk)
|
||||
}
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
for _, n := range neighbors {
|
||||
nodes, ok := nodeids[n.ID]
|
||||
if !ok {
|
||||
return fmt.Errorf(`unexpected foreign-key "auth_tokens_roles" returned %v`, n.ID)
|
||||
}
|
||||
for i := range nodes {
|
||||
assign(nodes[i], n)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (arq *AuthRolesQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := arq.querySpec()
|
||||
_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)
|
||||
}
|
||||
|
||||
func (arq *AuthRolesQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
_spec := sqlgraph.NewQuerySpec(authroles.Table, authroles.Columns, sqlgraph.NewFieldSpec(authroles.FieldID, field.TypeInt))
|
||||
_spec.From = arq.sql
|
||||
if unique := arq.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
} else if arq.path != nil {
|
||||
_spec.Unique = true
|
||||
}
|
||||
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 {
|
||||
if fields[i] != authroles.FieldID {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
if ps := arq.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := arq.ctx.Limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := arq.ctx.Offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := arq.order; len(ps) > 0 {
|
||||
_spec.Order = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
return _spec
|
||||
}
|
||||
|
||||
func (arq *AuthRolesQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(arq.driver.Dialect())
|
||||
t1 := builder.Table(authroles.Table)
|
||||
columns := arq.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = authroles.Columns
|
||||
}
|
||||
selector := builder.Select(t1.Columns(columns...)...).From(t1)
|
||||
if arq.sql != nil {
|
||||
selector = arq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if arq.ctx.Unique != nil && *arq.ctx.Unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, p := range arq.predicates {
|
||||
p(selector)
|
||||
}
|
||||
for _, p := range arq.order {
|
||||
p(selector)
|
||||
}
|
||||
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.ctx.Limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
}
|
||||
|
||||
// AuthRolesGroupBy is the group-by builder for AuthRoles entities.
|
||||
type AuthRolesGroupBy struct {
|
||||
selector
|
||||
build *AuthRolesQuery
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the group-by query.
|
||||
func (argb *AuthRolesGroupBy) Aggregate(fns ...AggregateFunc) *AuthRolesGroupBy {
|
||||
argb.fns = append(argb.fns, fns...)
|
||||
return argb
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (argb *AuthRolesGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, argb.build.ctx, "GroupBy")
|
||||
if err := argb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return scanWithInterceptors[*AuthRolesQuery, *AuthRolesGroupBy](ctx, argb.build, argb, argb.build.inters, v)
|
||||
}
|
||||
|
||||
func (argb *AuthRolesGroupBy) sqlScan(ctx context.Context, root *AuthRolesQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx).Select()
|
||||
aggregation := make([]string, 0, len(argb.fns))
|
||||
for _, fn := range argb.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
if len(selector.SelectedColumns()) == 0 {
|
||||
columns := make([]string, 0, len(*argb.flds)+len(argb.fns))
|
||||
for _, f := range *argb.flds {
|
||||
columns = append(columns, selector.C(f))
|
||||
}
|
||||
columns = append(columns, aggregation...)
|
||||
selector.Select(columns...)
|
||||
}
|
||||
selector.GroupBy(selector.Columns(*argb.flds...)...)
|
||||
if err := selector.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := argb.build.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
// AuthRolesSelect is the builder for selecting fields of AuthRoles entities.
|
||||
type AuthRolesSelect struct {
|
||||
*AuthRolesQuery
|
||||
selector
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the selector query.
|
||||
func (ars *AuthRolesSelect) Aggregate(fns ...AggregateFunc) *AuthRolesSelect {
|
||||
ars.fns = append(ars.fns, fns...)
|
||||
return ars
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ars *AuthRolesSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, ars.ctx, "Select")
|
||||
if err := ars.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return scanWithInterceptors[*AuthRolesQuery, *AuthRolesSelect](ctx, ars.AuthRolesQuery, ars, ars.inters, v)
|
||||
}
|
||||
|
||||
func (ars *AuthRolesSelect) sqlScan(ctx context.Context, root *AuthRolesQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx)
|
||||
aggregation := make([]string, 0, len(ars.fns))
|
||||
for _, fn := range ars.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
switch n := len(*ars.selector.flds); {
|
||||
case n == 0 && len(aggregation) > 0:
|
||||
selector.Select(aggregation...)
|
||||
case n != 0 && len(aggregation) > 0:
|
||||
selector.AppendSelect(aggregation...)
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := ars.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
357
backend/internal/data/ent/authroles_update.go
Normal file
357
backend/internal/data/ent/authroles_update.go
Normal file
@@ -0,0 +1,357 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||
)
|
||||
|
||||
// AuthRolesUpdate is the builder for updating AuthRoles entities.
|
||||
type AuthRolesUpdate struct {
|
||||
config
|
||||
hooks []Hook
|
||||
mutation *AuthRolesMutation
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the AuthRolesUpdate builder.
|
||||
func (aru *AuthRolesUpdate) Where(ps ...predicate.AuthRoles) *AuthRolesUpdate {
|
||||
aru.mutation.Where(ps...)
|
||||
return aru
|
||||
}
|
||||
|
||||
// SetRole sets the "role" field.
|
||||
func (aru *AuthRolesUpdate) SetRole(a authroles.Role) *AuthRolesUpdate {
|
||||
aru.mutation.SetRole(a)
|
||||
return aru
|
||||
}
|
||||
|
||||
// SetNillableRole sets the "role" field if the given value is not nil.
|
||||
func (aru *AuthRolesUpdate) SetNillableRole(a *authroles.Role) *AuthRolesUpdate {
|
||||
if a != nil {
|
||||
aru.SetRole(*a)
|
||||
}
|
||||
return aru
|
||||
}
|
||||
|
||||
// SetTokenID sets the "token" edge to the AuthTokens entity by ID.
|
||||
func (aru *AuthRolesUpdate) SetTokenID(id uuid.UUID) *AuthRolesUpdate {
|
||||
aru.mutation.SetTokenID(id)
|
||||
return aru
|
||||
}
|
||||
|
||||
// SetNillableTokenID sets the "token" edge to the AuthTokens entity by ID if the given value is not nil.
|
||||
func (aru *AuthRolesUpdate) SetNillableTokenID(id *uuid.UUID) *AuthRolesUpdate {
|
||||
if id != nil {
|
||||
aru = aru.SetTokenID(*id)
|
||||
}
|
||||
return aru
|
||||
}
|
||||
|
||||
// SetToken sets the "token" edge to the AuthTokens entity.
|
||||
func (aru *AuthRolesUpdate) SetToken(a *AuthTokens) *AuthRolesUpdate {
|
||||
return aru.SetTokenID(a.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the AuthRolesMutation object of the builder.
|
||||
func (aru *AuthRolesUpdate) Mutation() *AuthRolesMutation {
|
||||
return aru.mutation
|
||||
}
|
||||
|
||||
// ClearToken clears the "token" edge to the AuthTokens entity.
|
||||
func (aru *AuthRolesUpdate) ClearToken() *AuthRolesUpdate {
|
||||
aru.mutation.ClearToken()
|
||||
return aru
|
||||
}
|
||||
|
||||
// Save executes the query and returns the number of nodes affected by the update operation.
|
||||
func (aru *AuthRolesUpdate) Save(ctx context.Context) (int, error) {
|
||||
return withHooks[int, AuthRolesMutation](ctx, aru.sqlSave, aru.mutation, aru.hooks)
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (aru *AuthRolesUpdate) SaveX(ctx context.Context) int {
|
||||
affected, err := aru.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return affected
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (aru *AuthRolesUpdate) Exec(ctx context.Context) error {
|
||||
_, err := aru.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (aru *AuthRolesUpdate) ExecX(ctx context.Context) {
|
||||
if err := aru.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (aru *AuthRolesUpdate) check() error {
|
||||
if v, ok := aru.mutation.Role(); ok {
|
||||
if err := authroles.RoleValidator(v); err != nil {
|
||||
return &ValidationError{Name: "role", err: fmt.Errorf(`ent: validator failed for field "AuthRoles.role": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (aru *AuthRolesUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
if err := aru.check(); err != nil {
|
||||
return n, err
|
||||
}
|
||||
_spec := sqlgraph.NewUpdateSpec(authroles.Table, authroles.Columns, sqlgraph.NewFieldSpec(authroles.FieldID, field.TypeInt))
|
||||
if ps := aru.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if value, ok := aru.mutation.Role(); ok {
|
||||
_spec.SetField(authroles.FieldRole, field.TypeEnum, value)
|
||||
}
|
||||
if aru.mutation.TokenCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2O,
|
||||
Inverse: true,
|
||||
Table: authroles.TokenTable,
|
||||
Columns: []string{authroles.TokenColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: authtokens.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := aru.mutation.TokenIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2O,
|
||||
Inverse: true,
|
||||
Table: authroles.TokenTable,
|
||||
Columns: []string{authroles.TokenColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: authtokens.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if n, err = sqlgraph.UpdateNodes(ctx, aru.driver, _spec); err != nil {
|
||||
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||
err = &NotFoundError{authroles.Label}
|
||||
} else if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
aru.mutation.done = true
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// AuthRolesUpdateOne is the builder for updating a single AuthRoles entity.
|
||||
type AuthRolesUpdateOne struct {
|
||||
config
|
||||
fields []string
|
||||
hooks []Hook
|
||||
mutation *AuthRolesMutation
|
||||
}
|
||||
|
||||
// SetRole sets the "role" field.
|
||||
func (aruo *AuthRolesUpdateOne) SetRole(a authroles.Role) *AuthRolesUpdateOne {
|
||||
aruo.mutation.SetRole(a)
|
||||
return aruo
|
||||
}
|
||||
|
||||
// SetNillableRole sets the "role" field if the given value is not nil.
|
||||
func (aruo *AuthRolesUpdateOne) SetNillableRole(a *authroles.Role) *AuthRolesUpdateOne {
|
||||
if a != nil {
|
||||
aruo.SetRole(*a)
|
||||
}
|
||||
return aruo
|
||||
}
|
||||
|
||||
// SetTokenID sets the "token" edge to the AuthTokens entity by ID.
|
||||
func (aruo *AuthRolesUpdateOne) SetTokenID(id uuid.UUID) *AuthRolesUpdateOne {
|
||||
aruo.mutation.SetTokenID(id)
|
||||
return aruo
|
||||
}
|
||||
|
||||
// SetNillableTokenID sets the "token" edge to the AuthTokens entity by ID if the given value is not nil.
|
||||
func (aruo *AuthRolesUpdateOne) SetNillableTokenID(id *uuid.UUID) *AuthRolesUpdateOne {
|
||||
if id != nil {
|
||||
aruo = aruo.SetTokenID(*id)
|
||||
}
|
||||
return aruo
|
||||
}
|
||||
|
||||
// SetToken sets the "token" edge to the AuthTokens entity.
|
||||
func (aruo *AuthRolesUpdateOne) SetToken(a *AuthTokens) *AuthRolesUpdateOne {
|
||||
return aruo.SetTokenID(a.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the AuthRolesMutation object of the builder.
|
||||
func (aruo *AuthRolesUpdateOne) Mutation() *AuthRolesMutation {
|
||||
return aruo.mutation
|
||||
}
|
||||
|
||||
// ClearToken clears the "token" edge to the AuthTokens entity.
|
||||
func (aruo *AuthRolesUpdateOne) ClearToken() *AuthRolesUpdateOne {
|
||||
aruo.mutation.ClearToken()
|
||||
return aruo
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the AuthRolesUpdate builder.
|
||||
func (aruo *AuthRolesUpdateOne) Where(ps ...predicate.AuthRoles) *AuthRolesUpdateOne {
|
||||
aruo.mutation.Where(ps...)
|
||||
return aruo
|
||||
}
|
||||
|
||||
// Select allows selecting one or more fields (columns) of the returned entity.
|
||||
// The default is selecting all fields defined in the entity schema.
|
||||
func (aruo *AuthRolesUpdateOne) Select(field string, fields ...string) *AuthRolesUpdateOne {
|
||||
aruo.fields = append([]string{field}, fields...)
|
||||
return aruo
|
||||
}
|
||||
|
||||
// Save executes the query and returns the updated AuthRoles entity.
|
||||
func (aruo *AuthRolesUpdateOne) Save(ctx context.Context) (*AuthRoles, error) {
|
||||
return withHooks[*AuthRoles, AuthRolesMutation](ctx, aruo.sqlSave, aruo.mutation, aruo.hooks)
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (aruo *AuthRolesUpdateOne) SaveX(ctx context.Context) *AuthRoles {
|
||||
node, err := aruo.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// Exec executes the query on the entity.
|
||||
func (aruo *AuthRolesUpdateOne) Exec(ctx context.Context) error {
|
||||
_, err := aruo.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (aruo *AuthRolesUpdateOne) ExecX(ctx context.Context) {
|
||||
if err := aruo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (aruo *AuthRolesUpdateOne) check() error {
|
||||
if v, ok := aruo.mutation.Role(); ok {
|
||||
if err := authroles.RoleValidator(v); err != nil {
|
||||
return &ValidationError{Name: "role", err: fmt.Errorf(`ent: validator failed for field "AuthRoles.role": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (aruo *AuthRolesUpdateOne) sqlSave(ctx context.Context) (_node *AuthRoles, err error) {
|
||||
if err := aruo.check(); err != nil {
|
||||
return _node, err
|
||||
}
|
||||
_spec := sqlgraph.NewUpdateSpec(authroles.Table, authroles.Columns, sqlgraph.NewFieldSpec(authroles.FieldID, field.TypeInt))
|
||||
id, ok := aruo.mutation.ID()
|
||||
if !ok {
|
||||
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "AuthRoles.id" for update`)}
|
||||
}
|
||||
_spec.Node.ID.Value = id
|
||||
if fields := aruo.fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, authroles.FieldID)
|
||||
for _, f := range fields {
|
||||
if !authroles.ValidColumn(f) {
|
||||
return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
if f != authroles.FieldID {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
if ps := aruo.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if value, ok := aruo.mutation.Role(); ok {
|
||||
_spec.SetField(authroles.FieldRole, field.TypeEnum, value)
|
||||
}
|
||||
if aruo.mutation.TokenCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2O,
|
||||
Inverse: true,
|
||||
Table: authroles.TokenTable,
|
||||
Columns: []string{authroles.TokenColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: authtokens.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := aruo.mutation.TokenIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2O,
|
||||
Inverse: true,
|
||||
Table: authroles.TokenTable,
|
||||
Columns: []string{authroles.TokenColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: authtokens.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
_node = &AuthRoles{config: aruo.config}
|
||||
_spec.Assign = _node.assignValues
|
||||
_spec.ScanValues = _node.scanValues
|
||||
if err = sqlgraph.UpdateNode(ctx, aruo.driver, _spec); err != nil {
|
||||
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||
err = &NotFoundError{authroles.Label}
|
||||
} else if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
aruo.mutation.done = true
|
||||
return _node, nil
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
||||
)
|
||||
@@ -36,9 +37,11 @@ type AuthTokens struct {
|
||||
type AuthTokensEdges struct {
|
||||
// User holds the value of the user edge.
|
||||
User *User `json:"user,omitempty"`
|
||||
// Roles holds the value of the roles edge.
|
||||
Roles *AuthRoles `json:"roles,omitempty"`
|
||||
// loadedTypes holds the information for reporting if a
|
||||
// type was loaded (or requested) in eager-loading or not.
|
||||
loadedTypes [1]bool
|
||||
loadedTypes [2]bool
|
||||
}
|
||||
|
||||
// UserOrErr returns the User value or an error if the edge
|
||||
@@ -54,6 +57,19 @@ func (e AuthTokensEdges) UserOrErr() (*User, error) {
|
||||
return nil, &NotLoadedError{edge: "user"}
|
||||
}
|
||||
|
||||
// RolesOrErr returns the Roles value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e AuthTokensEdges) RolesOrErr() (*AuthRoles, error) {
|
||||
if e.loadedTypes[1] {
|
||||
if e.Roles == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: authroles.Label}
|
||||
}
|
||||
return e.Roles, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "roles"}
|
||||
}
|
||||
|
||||
// scanValues returns the types for scanning values from sql.Rows.
|
||||
func (*AuthTokens) scanValues(columns []string) ([]any, error) {
|
||||
values := make([]any, len(columns))
|
||||
@@ -126,14 +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 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,
|
||||
@@ -169,9 +190,3 @@ func (at *AuthTokens) String() string {
|
||||
|
||||
// AuthTokensSlice is a parsable slice of AuthTokens.
|
||||
type AuthTokensSlice []*AuthTokens
|
||||
|
||||
func (at AuthTokensSlice) config(cfg config) {
|
||||
for _i := range at {
|
||||
at[_i].config = cfg
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ const (
|
||||
FieldExpiresAt = "expires_at"
|
||||
// EdgeUser holds the string denoting the user edge name in mutations.
|
||||
EdgeUser = "user"
|
||||
// EdgeRoles holds the string denoting the roles edge name in mutations.
|
||||
EdgeRoles = "roles"
|
||||
// Table holds the table name of the authtokens in the database.
|
||||
Table = "auth_tokens"
|
||||
// UserTable is the table that holds the user relation/edge.
|
||||
@@ -32,6 +34,13 @@ const (
|
||||
UserInverseTable = "users"
|
||||
// UserColumn is the table column denoting the user relation/edge.
|
||||
UserColumn = "user_auth_tokens"
|
||||
// RolesTable is the table that holds the roles relation/edge.
|
||||
RolesTable = "auth_roles"
|
||||
// RolesInverseTable is the table name for the AuthRoles entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "authroles" package.
|
||||
RolesInverseTable = "auth_roles"
|
||||
// RolesColumn is the table column denoting the roles relation/edge.
|
||||
RolesColumn = "auth_tokens_roles"
|
||||
)
|
||||
|
||||
// Columns holds all SQL columns for authtokens fields.
|
||||
|
||||
@@ -13,357 +13,227 @@ import (
|
||||
|
||||
// ID filters vertices based on their ID field.
|
||||
func ID(id uuid.UUID) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDEQ applies the EQ predicate on the ID field.
|
||||
func IDEQ(id uuid.UUID) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDNEQ applies the NEQ predicate on the ID field.
|
||||
func IDNEQ(id uuid.UUID) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldNEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDIn applies the In predicate on the ID field.
|
||||
func IDIn(ids ...uuid.UUID) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
v := make([]any, len(ids))
|
||||
for i := range v {
|
||||
v[i] = ids[i]
|
||||
}
|
||||
s.Where(sql.In(s.C(FieldID), v...))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDNotIn applies the NotIn predicate on the ID field.
|
||||
func IDNotIn(ids ...uuid.UUID) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
v := make([]any, len(ids))
|
||||
for i := range v {
|
||||
v[i] = ids[i]
|
||||
}
|
||||
s.Where(sql.NotIn(s.C(FieldID), v...))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldNotIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDGT applies the GT predicate on the ID field.
|
||||
func IDGT(id uuid.UUID) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldGT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDGTE applies the GTE predicate on the ID field.
|
||||
func IDGTE(id uuid.UUID) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldGTE(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLT applies the LT predicate on the ID field.
|
||||
func IDLT(id uuid.UUID) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldLT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLTE applies the LTE predicate on the ID field.
|
||||
func IDLTE(id uuid.UUID) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldLTE(FieldID, id))
|
||||
}
|
||||
|
||||
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
|
||||
func CreatedAt(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
|
||||
func UpdatedAt(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// Token applies equality check predicate on the "token" field. It's identical to TokenEQ.
|
||||
func Token(v []byte) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldToken), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldEQ(FieldToken, v))
|
||||
}
|
||||
|
||||
// ExpiresAt applies equality check predicate on the "expires_at" field. It's identical to ExpiresAtEQ.
|
||||
func ExpiresAt(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldExpiresAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldEQ(FieldExpiresAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
|
||||
func CreatedAtEQ(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
|
||||
func CreatedAtNEQ(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldNEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtIn applies the In predicate on the "created_at" field.
|
||||
func CreatedAtIn(vs ...time.Time) predicate.AuthTokens {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldCreatedAt), v...))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldIn(FieldCreatedAt, vs...))
|
||||
}
|
||||
|
||||
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
|
||||
func CreatedAtNotIn(vs ...time.Time) predicate.AuthTokens {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldCreatedAt), v...))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldNotIn(FieldCreatedAt, vs...))
|
||||
}
|
||||
|
||||
// CreatedAtGT applies the GT predicate on the "created_at" field.
|
||||
func CreatedAtGT(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldGT(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
|
||||
func CreatedAtGTE(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldGTE(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtLT applies the LT predicate on the "created_at" field.
|
||||
func CreatedAtLT(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldLT(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
|
||||
func CreatedAtLTE(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldLTE(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
|
||||
func UpdatedAtEQ(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
|
||||
func UpdatedAtNEQ(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldNEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtIn applies the In predicate on the "updated_at" field.
|
||||
func UpdatedAtIn(vs ...time.Time) predicate.AuthTokens {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldUpdatedAt), v...))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldIn(FieldUpdatedAt, vs...))
|
||||
}
|
||||
|
||||
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
|
||||
func UpdatedAtNotIn(vs ...time.Time) predicate.AuthTokens {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldUpdatedAt), v...))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldNotIn(FieldUpdatedAt, vs...))
|
||||
}
|
||||
|
||||
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
|
||||
func UpdatedAtGT(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldGT(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
|
||||
func UpdatedAtGTE(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldGTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
|
||||
func UpdatedAtLT(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldLT(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
|
||||
func UpdatedAtLTE(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldLTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// TokenEQ applies the EQ predicate on the "token" field.
|
||||
func TokenEQ(v []byte) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldToken), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldEQ(FieldToken, v))
|
||||
}
|
||||
|
||||
// TokenNEQ applies the NEQ predicate on the "token" field.
|
||||
func TokenNEQ(v []byte) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldToken), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldNEQ(FieldToken, v))
|
||||
}
|
||||
|
||||
// TokenIn applies the In predicate on the "token" field.
|
||||
func TokenIn(vs ...[]byte) predicate.AuthTokens {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldToken), v...))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldIn(FieldToken, vs...))
|
||||
}
|
||||
|
||||
// TokenNotIn applies the NotIn predicate on the "token" field.
|
||||
func TokenNotIn(vs ...[]byte) predicate.AuthTokens {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldToken), v...))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldNotIn(FieldToken, vs...))
|
||||
}
|
||||
|
||||
// TokenGT applies the GT predicate on the "token" field.
|
||||
func TokenGT(v []byte) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldToken), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldGT(FieldToken, v))
|
||||
}
|
||||
|
||||
// TokenGTE applies the GTE predicate on the "token" field.
|
||||
func TokenGTE(v []byte) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldToken), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldGTE(FieldToken, v))
|
||||
}
|
||||
|
||||
// TokenLT applies the LT predicate on the "token" field.
|
||||
func TokenLT(v []byte) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldToken), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldLT(FieldToken, v))
|
||||
}
|
||||
|
||||
// TokenLTE applies the LTE predicate on the "token" field.
|
||||
func TokenLTE(v []byte) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldToken), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldLTE(FieldToken, v))
|
||||
}
|
||||
|
||||
// ExpiresAtEQ applies the EQ predicate on the "expires_at" field.
|
||||
func ExpiresAtEQ(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldExpiresAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldEQ(FieldExpiresAt, v))
|
||||
}
|
||||
|
||||
// ExpiresAtNEQ applies the NEQ predicate on the "expires_at" field.
|
||||
func ExpiresAtNEQ(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldExpiresAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldNEQ(FieldExpiresAt, v))
|
||||
}
|
||||
|
||||
// ExpiresAtIn applies the In predicate on the "expires_at" field.
|
||||
func ExpiresAtIn(vs ...time.Time) predicate.AuthTokens {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldExpiresAt), v...))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldIn(FieldExpiresAt, vs...))
|
||||
}
|
||||
|
||||
// ExpiresAtNotIn applies the NotIn predicate on the "expires_at" field.
|
||||
func ExpiresAtNotIn(vs ...time.Time) predicate.AuthTokens {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldExpiresAt), v...))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldNotIn(FieldExpiresAt, vs...))
|
||||
}
|
||||
|
||||
// ExpiresAtGT applies the GT predicate on the "expires_at" field.
|
||||
func ExpiresAtGT(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldExpiresAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldGT(FieldExpiresAt, v))
|
||||
}
|
||||
|
||||
// ExpiresAtGTE applies the GTE predicate on the "expires_at" field.
|
||||
func ExpiresAtGTE(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldExpiresAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldGTE(FieldExpiresAt, v))
|
||||
}
|
||||
|
||||
// ExpiresAtLT applies the LT predicate on the "expires_at" field.
|
||||
func ExpiresAtLT(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldExpiresAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldLT(FieldExpiresAt, v))
|
||||
}
|
||||
|
||||
// ExpiresAtLTE applies the LTE predicate on the "expires_at" field.
|
||||
func ExpiresAtLTE(v time.Time) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldExpiresAt), v))
|
||||
})
|
||||
return predicate.AuthTokens(sql.FieldLTE(FieldExpiresAt, v))
|
||||
}
|
||||
|
||||
// HasUser applies the HasEdge predicate on the "user" edge.
|
||||
@@ -371,7 +241,6 @@ func HasUser() predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(UserTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, UserTable, UserColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
@@ -394,6 +263,33 @@ func HasUserWith(preds ...predicate.User) predicate.AuthTokens {
|
||||
})
|
||||
}
|
||||
|
||||
// HasRoles applies the HasEdge predicate on the "roles" edge.
|
||||
func HasRoles() predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2O, false, RolesTable, RolesColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasRolesWith applies the HasEdge predicate on the "roles" edge with a given conditions (other predicates).
|
||||
func HasRolesWith(preds ...predicate.AuthRoles) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(RolesInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2O, false, RolesTable, RolesColumn),
|
||||
)
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// And groups predicates with the AND operator between them.
|
||||
func And(predicates ...predicate.AuthTokens) predicate.AuthTokens {
|
||||
return predicate.AuthTokens(func(s *sql.Selector) {
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
||||
)
|
||||
@@ -103,6 +104,25 @@ func (atc *AuthTokensCreate) SetUser(u *User) *AuthTokensCreate {
|
||||
return atc.SetUserID(u.ID)
|
||||
}
|
||||
|
||||
// SetRolesID sets the "roles" edge to the AuthRoles entity by ID.
|
||||
func (atc *AuthTokensCreate) SetRolesID(id int) *AuthTokensCreate {
|
||||
atc.mutation.SetRolesID(id)
|
||||
return atc
|
||||
}
|
||||
|
||||
// SetNillableRolesID sets the "roles" edge to the AuthRoles entity by ID if the given value is not nil.
|
||||
func (atc *AuthTokensCreate) SetNillableRolesID(id *int) *AuthTokensCreate {
|
||||
if id != nil {
|
||||
atc = atc.SetRolesID(*id)
|
||||
}
|
||||
return atc
|
||||
}
|
||||
|
||||
// SetRoles sets the "roles" edge to the AuthRoles entity.
|
||||
func (atc *AuthTokensCreate) SetRoles(a *AuthRoles) *AuthTokensCreate {
|
||||
return atc.SetRolesID(a.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the AuthTokensMutation object of the builder.
|
||||
func (atc *AuthTokensCreate) Mutation() *AuthTokensMutation {
|
||||
return atc.mutation
|
||||
@@ -110,50 +130,8 @@ func (atc *AuthTokensCreate) Mutation() *AuthTokensMutation {
|
||||
|
||||
// Save creates the AuthTokens in the database.
|
||||
func (atc *AuthTokensCreate) Save(ctx context.Context) (*AuthTokens, error) {
|
||||
var (
|
||||
err error
|
||||
node *AuthTokens
|
||||
)
|
||||
atc.defaults()
|
||||
if len(atc.hooks) == 0 {
|
||||
if err = atc.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node, err = atc.sqlSave(ctx)
|
||||
} else {
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*AuthTokensMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
if err = atc.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
atc.mutation = mutation
|
||||
if node, err = atc.sqlSave(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mutation.id = &node.ID
|
||||
mutation.done = true
|
||||
return node, err
|
||||
})
|
||||
for i := len(atc.hooks) - 1; i >= 0; i-- {
|
||||
if atc.hooks[i] == nil {
|
||||
return nil, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = atc.hooks[i](mut)
|
||||
}
|
||||
v, err := mut.Mutate(ctx, atc.mutation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nv, ok := v.(*AuthTokens)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected node type %T returned from AuthTokensMutation", v)
|
||||
}
|
||||
node = nv
|
||||
}
|
||||
return node, err
|
||||
return withHooks[*AuthTokens, AuthTokensMutation](ctx, atc.sqlSave, atc.mutation, atc.hooks)
|
||||
}
|
||||
|
||||
// SaveX calls Save and panics if Save returns an error.
|
||||
@@ -216,6 +194,9 @@ func (atc *AuthTokensCreate) check() error {
|
||||
}
|
||||
|
||||
func (atc *AuthTokensCreate) sqlSave(ctx context.Context) (*AuthTokens, error) {
|
||||
if err := atc.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_node, _spec := atc.createSpec()
|
||||
if err := sqlgraph.CreateNode(ctx, atc.driver, _spec); err != nil {
|
||||
if sqlgraph.IsConstraintError(err) {
|
||||
@@ -230,54 +211,34 @@ func (atc *AuthTokensCreate) sqlSave(ctx context.Context) (*AuthTokens, error) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
atc.mutation.id = &_node.ID
|
||||
atc.mutation.done = true
|
||||
return _node, nil
|
||||
}
|
||||
|
||||
func (atc *AuthTokensCreate) createSpec() (*AuthTokens, *sqlgraph.CreateSpec) {
|
||||
var (
|
||||
_node = &AuthTokens{config: atc.config}
|
||||
_spec = &sqlgraph.CreateSpec{
|
||||
Table: authtokens.Table,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: authtokens.FieldID,
|
||||
},
|
||||
}
|
||||
_spec = sqlgraph.NewCreateSpec(authtokens.Table, sqlgraph.NewFieldSpec(authtokens.FieldID, field.TypeUUID))
|
||||
)
|
||||
if id, ok := atc.mutation.ID(); ok {
|
||||
_node.ID = id
|
||||
_spec.ID.Value = &id
|
||||
}
|
||||
if value, ok := atc.mutation.CreatedAt(); ok {
|
||||
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: authtokens.FieldCreatedAt,
|
||||
})
|
||||
_spec.SetField(authtokens.FieldCreatedAt, field.TypeTime, value)
|
||||
_node.CreatedAt = value
|
||||
}
|
||||
if value, ok := atc.mutation.UpdatedAt(); ok {
|
||||
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: authtokens.FieldUpdatedAt,
|
||||
})
|
||||
_spec.SetField(authtokens.FieldUpdatedAt, field.TypeTime, value)
|
||||
_node.UpdatedAt = value
|
||||
}
|
||||
if value, ok := atc.mutation.Token(); ok {
|
||||
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeBytes,
|
||||
Value: value,
|
||||
Column: authtokens.FieldToken,
|
||||
})
|
||||
_spec.SetField(authtokens.FieldToken, field.TypeBytes, value)
|
||||
_node.Token = value
|
||||
}
|
||||
if value, ok := atc.mutation.ExpiresAt(); ok {
|
||||
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: authtokens.FieldExpiresAt,
|
||||
})
|
||||
_spec.SetField(authtokens.FieldExpiresAt, field.TypeTime, value)
|
||||
_node.ExpiresAt = value
|
||||
}
|
||||
if nodes := atc.mutation.UserIDs(); len(nodes) > 0 {
|
||||
@@ -300,6 +261,25 @@ func (atc *AuthTokensCreate) createSpec() (*AuthTokens, *sqlgraph.CreateSpec) {
|
||||
_node.user_auth_tokens = &nodes[0]
|
||||
_spec.Edges = append(_spec.Edges, edge)
|
||||
}
|
||||
if nodes := atc.mutation.RolesIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2O,
|
||||
Inverse: false,
|
||||
Table: authtokens.RolesTable,
|
||||
Columns: []string{authtokens.RolesColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeInt,
|
||||
Column: authroles.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges = append(_spec.Edges, edge)
|
||||
}
|
||||
return _node, _spec
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
@@ -28,34 +27,7 @@ func (atd *AuthTokensDelete) Where(ps ...predicate.AuthTokens) *AuthTokensDelete
|
||||
|
||||
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||
func (atd *AuthTokensDelete) Exec(ctx context.Context) (int, error) {
|
||||
var (
|
||||
err error
|
||||
affected int
|
||||
)
|
||||
if len(atd.hooks) == 0 {
|
||||
affected, err = atd.sqlExec(ctx)
|
||||
} else {
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*AuthTokensMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
atd.mutation = mutation
|
||||
affected, err = atd.sqlExec(ctx)
|
||||
mutation.done = true
|
||||
return affected, err
|
||||
})
|
||||
for i := len(atd.hooks) - 1; i >= 0; i-- {
|
||||
if atd.hooks[i] == nil {
|
||||
return 0, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = atd.hooks[i](mut)
|
||||
}
|
||||
if _, err := mut.Mutate(ctx, atd.mutation); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
return affected, err
|
||||
return withHooks[int, AuthTokensMutation](ctx, atd.sqlExec, atd.mutation, atd.hooks)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
@@ -68,15 +40,7 @@ func (atd *AuthTokensDelete) ExecX(ctx context.Context) int {
|
||||
}
|
||||
|
||||
func (atd *AuthTokensDelete) sqlExec(ctx context.Context) (int, error) {
|
||||
_spec := &sqlgraph.DeleteSpec{
|
||||
Node: &sqlgraph.NodeSpec{
|
||||
Table: authtokens.Table,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: authtokens.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
_spec := sqlgraph.NewDeleteSpec(authtokens.Table, sqlgraph.NewFieldSpec(authtokens.FieldID, field.TypeUUID))
|
||||
if ps := atd.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
@@ -88,6 +52,7 @@ func (atd *AuthTokensDelete) sqlExec(ctx context.Context) (int, error) {
|
||||
if err != nil && sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
atd.mutation.done = true
|
||||
return affected, err
|
||||
}
|
||||
|
||||
@@ -96,6 +61,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)
|
||||
@@ -111,5 +82,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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
@@ -11,6 +12,7 @@ import (
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
||||
@@ -19,13 +21,12 @@ 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
|
||||
withRoles *AuthRolesQuery
|
||||
withFKs bool
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
@@ -38,26 +39,26 @@ func (atq *AuthTokensQuery) Where(ps ...predicate.AuthTokens) *AuthTokensQuery {
|
||||
return atq
|
||||
}
|
||||
|
||||
// Limit adds a limit step to the query.
|
||||
// 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 adds an offset step to the query.
|
||||
// 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
|
||||
}
|
||||
|
||||
// Order adds an order step to the query.
|
||||
// Order specifies how the records should be ordered.
|
||||
func (atq *AuthTokensQuery) Order(o ...OrderFunc) *AuthTokensQuery {
|
||||
atq.order = append(atq.order, o...)
|
||||
return atq
|
||||
@@ -65,7 +66,7 @@ func (atq *AuthTokensQuery) Order(o ...OrderFunc) *AuthTokensQuery {
|
||||
|
||||
// QueryUser chains the current query on the "user" edge.
|
||||
func (atq *AuthTokensQuery) QueryUser() *UserQuery {
|
||||
query := &UserQuery{config: atq.config}
|
||||
query := (&UserClient{config: atq.config}).Query()
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := atq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
@@ -85,10 +86,32 @@ func (atq *AuthTokensQuery) QueryUser() *UserQuery {
|
||||
return query
|
||||
}
|
||||
|
||||
// QueryRoles chains the current query on the "roles" edge.
|
||||
func (atq *AuthTokensQuery) QueryRoles() *AuthRolesQuery {
|
||||
query := (&AuthRolesClient{config: atq.config}).Query()
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := atq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector := atq.sqlQuery(ctx)
|
||||
if err := selector.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(authtokens.Table, authtokens.FieldID, selector),
|
||||
sqlgraph.To(authroles.Table, authroles.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2O, false, authtokens.RolesTable, authtokens.RolesColumn),
|
||||
)
|
||||
fromU = sqlgraph.SetNeighbors(atq.driver.Dialect(), step)
|
||||
return fromU, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// 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(ctx)
|
||||
nodes, err := atq.Limit(1).All(setContextOp(ctx, atq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -111,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(ctx); err != nil {
|
||||
if ids, err = atq.Limit(1).IDs(setContextOp(ctx, atq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -134,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(ctx)
|
||||
nodes, err := atq.Limit(2).All(setContextOp(ctx, atq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -162,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(ctx); err != nil {
|
||||
if ids, err = atq.Limit(2).IDs(setContextOp(ctx, atq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -187,10 +210,12 @@ 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 = setContextOp(ctx, atq.ctx, "All")
|
||||
if err := atq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return atq.sqlAll(ctx)
|
||||
qr := querierAll[[]*AuthTokens, *AuthTokensQuery]()
|
||||
return withInterceptors[[]*AuthTokens](ctx, atq, qr, atq.inters)
|
||||
}
|
||||
|
||||
// AllX is like All, but panics if an error occurs.
|
||||
@@ -203,9 +228,12 @@ 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
|
||||
if err := atq.Select(authtokens.FieldID).Scan(ctx, &ids); err != nil {
|
||||
func (atq *AuthTokensQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error) {
|
||||
if atq.ctx.Unique == nil && atq.path != nil {
|
||||
atq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, atq.ctx, "IDs")
|
||||
if err = atq.Select(authtokens.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ids, nil
|
||||
@@ -222,10 +250,11 @@ 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 = setContextOp(ctx, atq.ctx, "Count")
|
||||
if err := atq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return atq.sqlCount(ctx)
|
||||
return withInterceptors[int](ctx, atq, querierCount[*AuthTokensQuery](), atq.inters)
|
||||
}
|
||||
|
||||
// CountX is like Count, but panics if an error occurs.
|
||||
@@ -239,10 +268,15 @@ 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) {
|
||||
if err := atq.prepareQuery(ctx); err != nil {
|
||||
return false, err
|
||||
ctx = setContextOp(ctx, atq.ctx, "Exist")
|
||||
switch _, err := atq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
case err != nil:
|
||||
return false, fmt.Errorf("ent: check existence: %w", err)
|
||||
default:
|
||||
return true, nil
|
||||
}
|
||||
return atq.sqlExist(ctx)
|
||||
}
|
||||
|
||||
// ExistX is like Exist, but panics if an error occurs.
|
||||
@@ -262,22 +296,22 @@ 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,
|
||||
}
|
||||
}
|
||||
|
||||
// WithUser tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "user" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (atq *AuthTokensQuery) WithUser(opts ...func(*UserQuery)) *AuthTokensQuery {
|
||||
query := &UserQuery{config: atq.config}
|
||||
query := (&UserClient{config: atq.config}).Query()
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
@@ -285,6 +319,17 @@ func (atq *AuthTokensQuery) WithUser(opts ...func(*UserQuery)) *AuthTokensQuery
|
||||
return atq
|
||||
}
|
||||
|
||||
// WithRoles tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "roles" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (atq *AuthTokensQuery) WithRoles(opts ...func(*AuthRolesQuery)) *AuthTokensQuery {
|
||||
query := (&AuthRolesClient{config: atq.config}).Query()
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
atq.withRoles = query
|
||||
return atq
|
||||
}
|
||||
|
||||
// GroupBy is used to group vertices by one or more fields/columns.
|
||||
// It is often used with aggregate functions, like: count, max, mean, min, sum.
|
||||
//
|
||||
@@ -300,16 +345,11 @@ func (atq *AuthTokensQuery) WithUser(opts ...func(*UserQuery)) *AuthTokensQuery
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (atq *AuthTokensQuery) GroupBy(field string, fields ...string) *AuthTokensGroupBy {
|
||||
grbuild := &AuthTokensGroupBy{config: atq.config}
|
||||
grbuild.fields = append([]string{field}, fields...)
|
||||
grbuild.path = func(ctx context.Context) (prev *sql.Selector, err error) {
|
||||
if err := atq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return atq.sqlQuery(ctx), nil
|
||||
}
|
||||
atq.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &AuthTokensGroupBy{build: atq}
|
||||
grbuild.flds = &atq.ctx.Fields
|
||||
grbuild.label = authtokens.Label
|
||||
grbuild.flds, grbuild.scan = &grbuild.fields, grbuild.Scan
|
||||
grbuild.scan = grbuild.Scan
|
||||
return grbuild
|
||||
}
|
||||
|
||||
@@ -326,15 +366,30 @@ 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...)
|
||||
selbuild := &AuthTokensSelect{AuthTokensQuery: atq}
|
||||
selbuild.label = authtokens.Label
|
||||
selbuild.flds, selbuild.scan = &atq.fields, selbuild.Scan
|
||||
return selbuild
|
||||
atq.ctx.Fields = append(atq.ctx.Fields, fields...)
|
||||
sbuild := &AuthTokensSelect{AuthTokensQuery: atq}
|
||||
sbuild.label = authtokens.Label
|
||||
sbuild.flds, sbuild.scan = &atq.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
// Aggregate returns a AuthTokensSelect configured with the given aggregations.
|
||||
func (atq *AuthTokensQuery) Aggregate(fns ...AggregateFunc) *AuthTokensSelect {
|
||||
return atq.Select().Aggregate(fns...)
|
||||
}
|
||||
|
||||
func (atq *AuthTokensQuery) prepareQuery(ctx context.Context) error {
|
||||
for _, f := range atq.fields {
|
||||
for _, inter := range atq.inters {
|
||||
if inter == nil {
|
||||
return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
|
||||
}
|
||||
if trv, ok := inter.(Traverser); ok {
|
||||
if err := trv.Traverse(ctx, atq); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range atq.ctx.Fields {
|
||||
if !authtokens.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
@@ -354,8 +409,9 @@ func (atq *AuthTokensQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*
|
||||
nodes = []*AuthTokens{}
|
||||
withFKs = atq.withFKs
|
||||
_spec = atq.querySpec()
|
||||
loadedTypes = [1]bool{
|
||||
loadedTypes = [2]bool{
|
||||
atq.withUser != nil,
|
||||
atq.withRoles != nil,
|
||||
}
|
||||
)
|
||||
if atq.withUser != nil {
|
||||
@@ -388,6 +444,12 @@ func (atq *AuthTokensQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if query := atq.withRoles; query != nil {
|
||||
if err := atq.loadRoles(ctx, query, nodes, nil,
|
||||
func(n *AuthTokens, e *AuthRoles) { n.Edges.Roles = e }); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
@@ -404,6 +466,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 {
|
||||
@@ -420,44 +485,53 @@ func (atq *AuthTokensQuery) loadUser(ctx context.Context, query *UserQuery, node
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (atq *AuthTokensQuery) loadRoles(ctx context.Context, query *AuthRolesQuery, nodes []*AuthTokens, init func(*AuthTokens), assign func(*AuthTokens, *AuthRoles)) error {
|
||||
fks := make([]driver.Value, 0, len(nodes))
|
||||
nodeids := make(map[uuid.UUID]*AuthTokens)
|
||||
for i := range nodes {
|
||||
fks = append(fks, nodes[i].ID)
|
||||
nodeids[nodes[i].ID] = nodes[i]
|
||||
}
|
||||
query.withFKs = true
|
||||
query.Where(predicate.AuthRoles(func(s *sql.Selector) {
|
||||
s.Where(sql.InValues(authtokens.RolesColumn, fks...))
|
||||
}))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, n := range neighbors {
|
||||
fk := n.auth_tokens_roles
|
||||
if fk == nil {
|
||||
return fmt.Errorf(`foreign-key "auth_tokens_roles" is nil for node %v`, n.ID)
|
||||
}
|
||||
node, ok := nodeids[*fk]
|
||||
if !ok {
|
||||
return fmt.Errorf(`unexpected foreign-key "auth_tokens_roles" returned %v for node %v`, *fk, n.ID)
|
||||
}
|
||||
assign(node, n)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
func (atq *AuthTokensQuery) sqlExist(ctx context.Context) (bool, error) {
|
||||
switch _, err := atq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
case err != nil:
|
||||
return false, fmt.Errorf("ent: check existence: %w", err)
|
||||
default:
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (atq *AuthTokensQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
_spec := &sqlgraph.QuerySpec{
|
||||
Node: &sqlgraph.NodeSpec{
|
||||
Table: authtokens.Table,
|
||||
Columns: authtokens.Columns,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: authtokens.FieldID,
|
||||
},
|
||||
},
|
||||
From: atq.sql,
|
||||
Unique: true,
|
||||
}
|
||||
if unique := atq.unique; unique != nil {
|
||||
_spec := sqlgraph.NewQuerySpec(authtokens.Table, authtokens.Columns, sqlgraph.NewFieldSpec(authtokens.FieldID, field.TypeUUID))
|
||||
_spec.From = atq.sql
|
||||
if unique := atq.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
} else if atq.path != nil {
|
||||
_spec.Unique = true
|
||||
}
|
||||
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 {
|
||||
@@ -473,10 +547,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 {
|
||||
@@ -492,7 +566,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
|
||||
}
|
||||
@@ -501,7 +575,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 {
|
||||
@@ -510,12 +584,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
|
||||
@@ -523,13 +597,8 @@ func (atq *AuthTokensQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
|
||||
// AuthTokensGroupBy is the group-by builder for AuthTokens entities.
|
||||
type AuthTokensGroupBy struct {
|
||||
config
|
||||
selector
|
||||
fields []string
|
||||
fns []AggregateFunc
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
build *AuthTokensQuery
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the group-by query.
|
||||
@@ -538,74 +607,77 @@ func (atgb *AuthTokensGroupBy) Aggregate(fns ...AggregateFunc) *AuthTokensGroupB
|
||||
return atgb
|
||||
}
|
||||
|
||||
// Scan applies the group-by query and scans the result into the given value.
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (atgb *AuthTokensGroupBy) Scan(ctx context.Context, v any) error {
|
||||
query, err := atgb.path(ctx)
|
||||
if err != nil {
|
||||
ctx = setContextOp(ctx, atgb.build.ctx, "GroupBy")
|
||||
if err := atgb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
atgb.sql = query
|
||||
return atgb.sqlScan(ctx, v)
|
||||
return scanWithInterceptors[*AuthTokensQuery, *AuthTokensGroupBy](ctx, atgb.build, atgb, atgb.build.inters, v)
|
||||
}
|
||||
|
||||
func (atgb *AuthTokensGroupBy) sqlScan(ctx context.Context, v any) error {
|
||||
for _, f := range atgb.fields {
|
||||
if !authtokens.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("invalid field %q for group-by", f)}
|
||||
}
|
||||
}
|
||||
selector := atgb.sqlQuery()
|
||||
if err := selector.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := atgb.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
func (atgb *AuthTokensGroupBy) sqlQuery() *sql.Selector {
|
||||
selector := atgb.sql.Select()
|
||||
func (atgb *AuthTokensGroupBy) sqlScan(ctx context.Context, root *AuthTokensQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx).Select()
|
||||
aggregation := make([]string, 0, len(atgb.fns))
|
||||
for _, fn := range atgb.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
// If no columns were selected in a custom aggregation function, the default
|
||||
// selection is the fields used for "group-by", and the aggregation functions.
|
||||
if len(selector.SelectedColumns()) == 0 {
|
||||
columns := make([]string, 0, len(atgb.fields)+len(atgb.fns))
|
||||
for _, f := range atgb.fields {
|
||||
columns := make([]string, 0, len(*atgb.flds)+len(atgb.fns))
|
||||
for _, f := range *atgb.flds {
|
||||
columns = append(columns, selector.C(f))
|
||||
}
|
||||
columns = append(columns, aggregation...)
|
||||
selector.Select(columns...)
|
||||
}
|
||||
return selector.GroupBy(selector.Columns(atgb.fields...)...)
|
||||
selector.GroupBy(selector.Columns(*atgb.flds...)...)
|
||||
if err := selector.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := atgb.build.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
// AuthTokensSelect is the builder for selecting fields of AuthTokens entities.
|
||||
type AuthTokensSelect struct {
|
||||
*AuthTokensQuery
|
||||
selector
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the selector query.
|
||||
func (ats *AuthTokensSelect) Aggregate(fns ...AggregateFunc) *AuthTokensSelect {
|
||||
ats.fns = append(ats.fns, fns...)
|
||||
return ats
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ats *AuthTokensSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, ats.ctx, "Select")
|
||||
if err := ats.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
ats.sql = ats.AuthTokensQuery.sqlQuery(ctx)
|
||||
return ats.sqlScan(ctx, v)
|
||||
return scanWithInterceptors[*AuthTokensQuery, *AuthTokensSelect](ctx, ats.AuthTokensQuery, ats, ats.inters, v)
|
||||
}
|
||||
|
||||
func (ats *AuthTokensSelect) sqlScan(ctx context.Context, v any) error {
|
||||
func (ats *AuthTokensSelect) sqlScan(ctx context.Context, root *AuthTokensQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx)
|
||||
aggregation := make([]string, 0, len(ats.fns))
|
||||
for _, fn := range ats.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
switch n := len(*ats.selector.flds); {
|
||||
case n == 0 && len(aggregation) > 0:
|
||||
selector.Select(aggregation...)
|
||||
case n != 0 && len(aggregation) > 0:
|
||||
selector.AppendSelect(aggregation...)
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := ats.sql.Query()
|
||||
query, args := selector.Query()
|
||||
if err := ats.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
||||
@@ -75,6 +76,25 @@ func (atu *AuthTokensUpdate) SetUser(u *User) *AuthTokensUpdate {
|
||||
return atu.SetUserID(u.ID)
|
||||
}
|
||||
|
||||
// SetRolesID sets the "roles" edge to the AuthRoles entity by ID.
|
||||
func (atu *AuthTokensUpdate) SetRolesID(id int) *AuthTokensUpdate {
|
||||
atu.mutation.SetRolesID(id)
|
||||
return atu
|
||||
}
|
||||
|
||||
// SetNillableRolesID sets the "roles" edge to the AuthRoles entity by ID if the given value is not nil.
|
||||
func (atu *AuthTokensUpdate) SetNillableRolesID(id *int) *AuthTokensUpdate {
|
||||
if id != nil {
|
||||
atu = atu.SetRolesID(*id)
|
||||
}
|
||||
return atu
|
||||
}
|
||||
|
||||
// SetRoles sets the "roles" edge to the AuthRoles entity.
|
||||
func (atu *AuthTokensUpdate) SetRoles(a *AuthRoles) *AuthTokensUpdate {
|
||||
return atu.SetRolesID(a.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the AuthTokensMutation object of the builder.
|
||||
func (atu *AuthTokensUpdate) Mutation() *AuthTokensMutation {
|
||||
return atu.mutation
|
||||
@@ -86,37 +106,16 @@ func (atu *AuthTokensUpdate) ClearUser() *AuthTokensUpdate {
|
||||
return atu
|
||||
}
|
||||
|
||||
// ClearRoles clears the "roles" edge to the AuthRoles entity.
|
||||
func (atu *AuthTokensUpdate) ClearRoles() *AuthTokensUpdate {
|
||||
atu.mutation.ClearRoles()
|
||||
return atu
|
||||
}
|
||||
|
||||
// Save executes the query and returns the number of nodes affected by the update operation.
|
||||
func (atu *AuthTokensUpdate) Save(ctx context.Context) (int, error) {
|
||||
var (
|
||||
err error
|
||||
affected int
|
||||
)
|
||||
atu.defaults()
|
||||
if len(atu.hooks) == 0 {
|
||||
affected, err = atu.sqlSave(ctx)
|
||||
} else {
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*AuthTokensMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
atu.mutation = mutation
|
||||
affected, err = atu.sqlSave(ctx)
|
||||
mutation.done = true
|
||||
return affected, err
|
||||
})
|
||||
for i := len(atu.hooks) - 1; i >= 0; i-- {
|
||||
if atu.hooks[i] == nil {
|
||||
return 0, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = atu.hooks[i](mut)
|
||||
}
|
||||
if _, err := mut.Mutate(ctx, atu.mutation); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
return affected, err
|
||||
return withHooks[int, AuthTokensMutation](ctx, atu.sqlSave, atu.mutation, atu.hooks)
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
@@ -150,16 +149,7 @@ func (atu *AuthTokensUpdate) defaults() {
|
||||
}
|
||||
|
||||
func (atu *AuthTokensUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
_spec := &sqlgraph.UpdateSpec{
|
||||
Node: &sqlgraph.NodeSpec{
|
||||
Table: authtokens.Table,
|
||||
Columns: authtokens.Columns,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: authtokens.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
_spec := sqlgraph.NewUpdateSpec(authtokens.Table, authtokens.Columns, sqlgraph.NewFieldSpec(authtokens.FieldID, field.TypeUUID))
|
||||
if ps := atu.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
@@ -168,25 +158,13 @@ func (atu *AuthTokensUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
}
|
||||
}
|
||||
if value, ok := atu.mutation.UpdatedAt(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: authtokens.FieldUpdatedAt,
|
||||
})
|
||||
_spec.SetField(authtokens.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if value, ok := atu.mutation.Token(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeBytes,
|
||||
Value: value,
|
||||
Column: authtokens.FieldToken,
|
||||
})
|
||||
_spec.SetField(authtokens.FieldToken, field.TypeBytes, value)
|
||||
}
|
||||
if value, ok := atu.mutation.ExpiresAt(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: authtokens.FieldExpiresAt,
|
||||
})
|
||||
_spec.SetField(authtokens.FieldExpiresAt, field.TypeTime, value)
|
||||
}
|
||||
if atu.mutation.UserCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
@@ -223,6 +201,41 @@ func (atu *AuthTokensUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if atu.mutation.RolesCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2O,
|
||||
Inverse: false,
|
||||
Table: authtokens.RolesTable,
|
||||
Columns: []string{authtokens.RolesColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeInt,
|
||||
Column: authroles.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := atu.mutation.RolesIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2O,
|
||||
Inverse: false,
|
||||
Table: authtokens.RolesTable,
|
||||
Columns: []string{authtokens.RolesColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeInt,
|
||||
Column: authroles.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if n, err = sqlgraph.UpdateNodes(ctx, atu.driver, _spec); err != nil {
|
||||
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||
err = &NotFoundError{authtokens.Label}
|
||||
@@ -231,6 +244,7 @@ func (atu *AuthTokensUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
atu.mutation.done = true
|
||||
return n, nil
|
||||
}
|
||||
|
||||
@@ -287,6 +301,25 @@ func (atuo *AuthTokensUpdateOne) SetUser(u *User) *AuthTokensUpdateOne {
|
||||
return atuo.SetUserID(u.ID)
|
||||
}
|
||||
|
||||
// SetRolesID sets the "roles" edge to the AuthRoles entity by ID.
|
||||
func (atuo *AuthTokensUpdateOne) SetRolesID(id int) *AuthTokensUpdateOne {
|
||||
atuo.mutation.SetRolesID(id)
|
||||
return atuo
|
||||
}
|
||||
|
||||
// SetNillableRolesID sets the "roles" edge to the AuthRoles entity by ID if the given value is not nil.
|
||||
func (atuo *AuthTokensUpdateOne) SetNillableRolesID(id *int) *AuthTokensUpdateOne {
|
||||
if id != nil {
|
||||
atuo = atuo.SetRolesID(*id)
|
||||
}
|
||||
return atuo
|
||||
}
|
||||
|
||||
// SetRoles sets the "roles" edge to the AuthRoles entity.
|
||||
func (atuo *AuthTokensUpdateOne) SetRoles(a *AuthRoles) *AuthTokensUpdateOne {
|
||||
return atuo.SetRolesID(a.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the AuthTokensMutation object of the builder.
|
||||
func (atuo *AuthTokensUpdateOne) Mutation() *AuthTokensMutation {
|
||||
return atuo.mutation
|
||||
@@ -298,6 +331,18 @@ func (atuo *AuthTokensUpdateOne) ClearUser() *AuthTokensUpdateOne {
|
||||
return atuo
|
||||
}
|
||||
|
||||
// ClearRoles clears the "roles" edge to the AuthRoles entity.
|
||||
func (atuo *AuthTokensUpdateOne) ClearRoles() *AuthTokensUpdateOne {
|
||||
atuo.mutation.ClearRoles()
|
||||
return atuo
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the AuthTokensUpdate builder.
|
||||
func (atuo *AuthTokensUpdateOne) Where(ps ...predicate.AuthTokens) *AuthTokensUpdateOne {
|
||||
atuo.mutation.Where(ps...)
|
||||
return atuo
|
||||
}
|
||||
|
||||
// Select allows selecting one or more fields (columns) of the returned entity.
|
||||
// The default is selecting all fields defined in the entity schema.
|
||||
func (atuo *AuthTokensUpdateOne) Select(field string, fields ...string) *AuthTokensUpdateOne {
|
||||
@@ -307,41 +352,8 @@ func (atuo *AuthTokensUpdateOne) Select(field string, fields ...string) *AuthTok
|
||||
|
||||
// Save executes the query and returns the updated AuthTokens entity.
|
||||
func (atuo *AuthTokensUpdateOne) Save(ctx context.Context) (*AuthTokens, error) {
|
||||
var (
|
||||
err error
|
||||
node *AuthTokens
|
||||
)
|
||||
atuo.defaults()
|
||||
if len(atuo.hooks) == 0 {
|
||||
node, err = atuo.sqlSave(ctx)
|
||||
} else {
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*AuthTokensMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
atuo.mutation = mutation
|
||||
node, err = atuo.sqlSave(ctx)
|
||||
mutation.done = true
|
||||
return node, err
|
||||
})
|
||||
for i := len(atuo.hooks) - 1; i >= 0; i-- {
|
||||
if atuo.hooks[i] == nil {
|
||||
return nil, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = atuo.hooks[i](mut)
|
||||
}
|
||||
v, err := mut.Mutate(ctx, atuo.mutation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nv, ok := v.(*AuthTokens)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected node type %T returned from AuthTokensMutation", v)
|
||||
}
|
||||
node = nv
|
||||
}
|
||||
return node, err
|
||||
return withHooks[*AuthTokens, AuthTokensMutation](ctx, atuo.sqlSave, atuo.mutation, atuo.hooks)
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
@@ -375,16 +387,7 @@ func (atuo *AuthTokensUpdateOne) defaults() {
|
||||
}
|
||||
|
||||
func (atuo *AuthTokensUpdateOne) sqlSave(ctx context.Context) (_node *AuthTokens, err error) {
|
||||
_spec := &sqlgraph.UpdateSpec{
|
||||
Node: &sqlgraph.NodeSpec{
|
||||
Table: authtokens.Table,
|
||||
Columns: authtokens.Columns,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: authtokens.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
_spec := sqlgraph.NewUpdateSpec(authtokens.Table, authtokens.Columns, sqlgraph.NewFieldSpec(authtokens.FieldID, field.TypeUUID))
|
||||
id, ok := atuo.mutation.ID()
|
||||
if !ok {
|
||||
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "AuthTokens.id" for update`)}
|
||||
@@ -410,25 +413,13 @@ func (atuo *AuthTokensUpdateOne) sqlSave(ctx context.Context) (_node *AuthTokens
|
||||
}
|
||||
}
|
||||
if value, ok := atuo.mutation.UpdatedAt(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: authtokens.FieldUpdatedAt,
|
||||
})
|
||||
_spec.SetField(authtokens.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if value, ok := atuo.mutation.Token(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeBytes,
|
||||
Value: value,
|
||||
Column: authtokens.FieldToken,
|
||||
})
|
||||
_spec.SetField(authtokens.FieldToken, field.TypeBytes, value)
|
||||
}
|
||||
if value, ok := atuo.mutation.ExpiresAt(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: authtokens.FieldExpiresAt,
|
||||
})
|
||||
_spec.SetField(authtokens.FieldExpiresAt, field.TypeTime, value)
|
||||
}
|
||||
if atuo.mutation.UserCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
@@ -465,6 +456,41 @@ func (atuo *AuthTokensUpdateOne) sqlSave(ctx context.Context) (_node *AuthTokens
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if atuo.mutation.RolesCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2O,
|
||||
Inverse: false,
|
||||
Table: authtokens.RolesTable,
|
||||
Columns: []string{authtokens.RolesColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeInt,
|
||||
Column: authroles.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := atuo.mutation.RolesIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2O,
|
||||
Inverse: false,
|
||||
Table: authtokens.RolesTable,
|
||||
Columns: []string{authtokens.RolesColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeInt,
|
||||
Column: authroles.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
_node = &AuthTokens{config: atuo.config}
|
||||
_spec.Assign = _node.assignValues
|
||||
_spec.ScanValues = _node.scanValues
|
||||
@@ -476,5 +502,6 @@ func (atuo *AuthTokensUpdateOne) sqlSave(ctx context.Context) (_node *AuthTokens
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
atuo.mutation.done = true
|
||||
return _node, nil
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,22 +20,43 @@ type config struct {
|
||||
log func(...any)
|
||||
// hooks to execute on mutations.
|
||||
hooks *hooks
|
||||
// interceptors to execute on queries.
|
||||
inters *inters
|
||||
}
|
||||
|
||||
// hooks per client, for fast access.
|
||||
type hooks struct {
|
||||
Attachment []ent.Hook
|
||||
AuthTokens []ent.Hook
|
||||
Document []ent.Hook
|
||||
DocumentToken []ent.Hook
|
||||
Group []ent.Hook
|
||||
GroupInvitationToken []ent.Hook
|
||||
Item []ent.Hook
|
||||
ItemField []ent.Hook
|
||||
Label []ent.Hook
|
||||
Location []ent.Hook
|
||||
User []ent.Hook
|
||||
}
|
||||
// hooks and interceptors per client, for fast access.
|
||||
type (
|
||||
hooks struct {
|
||||
Attachment []ent.Hook
|
||||
AuthRoles []ent.Hook
|
||||
AuthTokens []ent.Hook
|
||||
Document []ent.Hook
|
||||
Group []ent.Hook
|
||||
GroupInvitationToken []ent.Hook
|
||||
Item []ent.Hook
|
||||
ItemField []ent.Hook
|
||||
Label []ent.Hook
|
||||
Location []ent.Hook
|
||||
MaintenanceEntry []ent.Hook
|
||||
Notifier []ent.Hook
|
||||
User []ent.Hook
|
||||
}
|
||||
inters struct {
|
||||
Attachment []ent.Interceptor
|
||||
AuthRoles []ent.Interceptor
|
||||
AuthTokens []ent.Interceptor
|
||||
Document []ent.Interceptor
|
||||
Group []ent.Interceptor
|
||||
GroupInvitationToken []ent.Interceptor
|
||||
Item []ent.Interceptor
|
||||
ItemField []ent.Interceptor
|
||||
Label []ent.Interceptor
|
||||
Location []ent.Interceptor
|
||||
MaintenanceEntry []ent.Interceptor
|
||||
Notifier []ent.Interceptor
|
||||
User []ent.Interceptor
|
||||
}
|
||||
)
|
||||
|
||||
// Options applies the options on the config object.
|
||||
func (c *config) options(opts ...Option) {
|
||||
|
||||
@@ -36,13 +36,11 @@ type Document struct {
|
||||
type DocumentEdges struct {
|
||||
// Group holds the value of the group edge.
|
||||
Group *Group `json:"group,omitempty"`
|
||||
// DocumentTokens holds the value of the document_tokens edge.
|
||||
DocumentTokens []*DocumentToken `json:"document_tokens,omitempty"`
|
||||
// Attachments holds the value of the attachments edge.
|
||||
Attachments []*Attachment `json:"attachments,omitempty"`
|
||||
// loadedTypes holds the information for reporting if a
|
||||
// type was loaded (or requested) in eager-loading or not.
|
||||
loadedTypes [3]bool
|
||||
loadedTypes [2]bool
|
||||
}
|
||||
|
||||
// GroupOrErr returns the Group value or an error if the edge
|
||||
@@ -58,19 +56,10 @@ func (e DocumentEdges) GroupOrErr() (*Group, error) {
|
||||
return nil, &NotLoadedError{edge: "group"}
|
||||
}
|
||||
|
||||
// DocumentTokensOrErr returns the DocumentTokens value or an error if the edge
|
||||
// was not loaded in eager-loading.
|
||||
func (e DocumentEdges) DocumentTokensOrErr() ([]*DocumentToken, error) {
|
||||
if e.loadedTypes[1] {
|
||||
return e.DocumentTokens, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "document_tokens"}
|
||||
}
|
||||
|
||||
// AttachmentsOrErr returns the Attachments value or an error if the edge
|
||||
// was not loaded in eager-loading.
|
||||
func (e DocumentEdges) AttachmentsOrErr() ([]*Attachment, error) {
|
||||
if e.loadedTypes[2] {
|
||||
if e.loadedTypes[1] {
|
||||
return e.Attachments, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "attachments"}
|
||||
@@ -148,24 +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)
|
||||
}
|
||||
|
||||
// QueryDocumentTokens queries the "document_tokens" edge of the Document entity.
|
||||
func (d *Document) QueryDocumentTokens() *DocumentTokenQuery {
|
||||
return (&DocumentClient{config: d.config}).QueryDocumentTokens(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,
|
||||
@@ -201,9 +185,3 @@ func (d *Document) String() string {
|
||||
|
||||
// Documents is a parsable slice of Document.
|
||||
type Documents []*Document
|
||||
|
||||
func (d Documents) config(cfg config) {
|
||||
for _i := range d {
|
||||
d[_i].config = cfg
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,6 @@ const (
|
||||
FieldPath = "path"
|
||||
// EdgeGroup holds the string denoting the group edge name in mutations.
|
||||
EdgeGroup = "group"
|
||||
// EdgeDocumentTokens holds the string denoting the document_tokens edge name in mutations.
|
||||
EdgeDocumentTokens = "document_tokens"
|
||||
// EdgeAttachments holds the string denoting the attachments edge name in mutations.
|
||||
EdgeAttachments = "attachments"
|
||||
// Table holds the table name of the document in the database.
|
||||
@@ -36,13 +34,6 @@ const (
|
||||
GroupInverseTable = "groups"
|
||||
// GroupColumn is the table column denoting the group relation/edge.
|
||||
GroupColumn = "group_documents"
|
||||
// DocumentTokensTable is the table that holds the document_tokens relation/edge.
|
||||
DocumentTokensTable = "document_tokens"
|
||||
// DocumentTokensInverseTable is the table name for the DocumentToken entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "documenttoken" package.
|
||||
DocumentTokensInverseTable = "document_tokens"
|
||||
// DocumentTokensColumn is the table column denoting the document_tokens relation/edge.
|
||||
DocumentTokensColumn = "document_document_tokens"
|
||||
// AttachmentsTable is the table that holds the attachments relation/edge.
|
||||
AttachmentsTable = "attachments"
|
||||
// AttachmentsInverseTable is the table name for the Attachment entity.
|
||||
|
||||
@@ -13,427 +13,277 @@ import (
|
||||
|
||||
// ID filters vertices based on their ID field.
|
||||
func ID(id uuid.UUID) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Document(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDEQ applies the EQ predicate on the ID field.
|
||||
func IDEQ(id uuid.UUID) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Document(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDNEQ applies the NEQ predicate on the ID field.
|
||||
func IDNEQ(id uuid.UUID) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Document(sql.FieldNEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDIn applies the In predicate on the ID field.
|
||||
func IDIn(ids ...uuid.UUID) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
v := make([]any, len(ids))
|
||||
for i := range v {
|
||||
v[i] = ids[i]
|
||||
}
|
||||
s.Where(sql.In(s.C(FieldID), v...))
|
||||
})
|
||||
return predicate.Document(sql.FieldIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDNotIn applies the NotIn predicate on the ID field.
|
||||
func IDNotIn(ids ...uuid.UUID) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
v := make([]any, len(ids))
|
||||
for i := range v {
|
||||
v[i] = ids[i]
|
||||
}
|
||||
s.Where(sql.NotIn(s.C(FieldID), v...))
|
||||
})
|
||||
return predicate.Document(sql.FieldNotIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDGT applies the GT predicate on the ID field.
|
||||
func IDGT(id uuid.UUID) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Document(sql.FieldGT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDGTE applies the GTE predicate on the ID field.
|
||||
func IDGTE(id uuid.UUID) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Document(sql.FieldGTE(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLT applies the LT predicate on the ID field.
|
||||
func IDLT(id uuid.UUID) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Document(sql.FieldLT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLTE applies the LTE predicate on the ID field.
|
||||
func IDLTE(id uuid.UUID) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Document(sql.FieldLTE(FieldID, id))
|
||||
}
|
||||
|
||||
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
|
||||
func CreatedAt(v time.Time) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
|
||||
func UpdatedAt(v time.Time) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// Title applies equality check predicate on the "title" field. It's identical to TitleEQ.
|
||||
func Title(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldTitle), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldEQ(FieldTitle, v))
|
||||
}
|
||||
|
||||
// Path applies equality check predicate on the "path" field. It's identical to PathEQ.
|
||||
func Path(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldPath), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldEQ(FieldPath, v))
|
||||
}
|
||||
|
||||
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
|
||||
func CreatedAtEQ(v time.Time) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
|
||||
func CreatedAtNEQ(v time.Time) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldNEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtIn applies the In predicate on the "created_at" field.
|
||||
func CreatedAtIn(vs ...time.Time) predicate.Document {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldCreatedAt), v...))
|
||||
})
|
||||
return predicate.Document(sql.FieldIn(FieldCreatedAt, vs...))
|
||||
}
|
||||
|
||||
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
|
||||
func CreatedAtNotIn(vs ...time.Time) predicate.Document {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldCreatedAt), v...))
|
||||
})
|
||||
return predicate.Document(sql.FieldNotIn(FieldCreatedAt, vs...))
|
||||
}
|
||||
|
||||
// CreatedAtGT applies the GT predicate on the "created_at" field.
|
||||
func CreatedAtGT(v time.Time) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldGT(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
|
||||
func CreatedAtGTE(v time.Time) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldGTE(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtLT applies the LT predicate on the "created_at" field.
|
||||
func CreatedAtLT(v time.Time) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldLT(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
|
||||
func CreatedAtLTE(v time.Time) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldLTE(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
|
||||
func UpdatedAtEQ(v time.Time) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
|
||||
func UpdatedAtNEQ(v time.Time) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldNEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtIn applies the In predicate on the "updated_at" field.
|
||||
func UpdatedAtIn(vs ...time.Time) predicate.Document {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldUpdatedAt), v...))
|
||||
})
|
||||
return predicate.Document(sql.FieldIn(FieldUpdatedAt, vs...))
|
||||
}
|
||||
|
||||
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
|
||||
func UpdatedAtNotIn(vs ...time.Time) predicate.Document {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldUpdatedAt), v...))
|
||||
})
|
||||
return predicate.Document(sql.FieldNotIn(FieldUpdatedAt, vs...))
|
||||
}
|
||||
|
||||
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
|
||||
func UpdatedAtGT(v time.Time) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldGT(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
|
||||
func UpdatedAtGTE(v time.Time) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldGTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
|
||||
func UpdatedAtLT(v time.Time) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldLT(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
|
||||
func UpdatedAtLTE(v time.Time) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldLTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// TitleEQ applies the EQ predicate on the "title" field.
|
||||
func TitleEQ(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldTitle), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldEQ(FieldTitle, v))
|
||||
}
|
||||
|
||||
// TitleNEQ applies the NEQ predicate on the "title" field.
|
||||
func TitleNEQ(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldTitle), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldNEQ(FieldTitle, v))
|
||||
}
|
||||
|
||||
// TitleIn applies the In predicate on the "title" field.
|
||||
func TitleIn(vs ...string) predicate.Document {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldTitle), v...))
|
||||
})
|
||||
return predicate.Document(sql.FieldIn(FieldTitle, vs...))
|
||||
}
|
||||
|
||||
// TitleNotIn applies the NotIn predicate on the "title" field.
|
||||
func TitleNotIn(vs ...string) predicate.Document {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldTitle), v...))
|
||||
})
|
||||
return predicate.Document(sql.FieldNotIn(FieldTitle, vs...))
|
||||
}
|
||||
|
||||
// TitleGT applies the GT predicate on the "title" field.
|
||||
func TitleGT(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldTitle), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldGT(FieldTitle, v))
|
||||
}
|
||||
|
||||
// TitleGTE applies the GTE predicate on the "title" field.
|
||||
func TitleGTE(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldTitle), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldGTE(FieldTitle, v))
|
||||
}
|
||||
|
||||
// TitleLT applies the LT predicate on the "title" field.
|
||||
func TitleLT(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldTitle), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldLT(FieldTitle, v))
|
||||
}
|
||||
|
||||
// TitleLTE applies the LTE predicate on the "title" field.
|
||||
func TitleLTE(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldTitle), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldLTE(FieldTitle, v))
|
||||
}
|
||||
|
||||
// TitleContains applies the Contains predicate on the "title" field.
|
||||
func TitleContains(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.Contains(s.C(FieldTitle), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldContains(FieldTitle, v))
|
||||
}
|
||||
|
||||
// TitleHasPrefix applies the HasPrefix predicate on the "title" field.
|
||||
func TitleHasPrefix(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.HasPrefix(s.C(FieldTitle), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldHasPrefix(FieldTitle, v))
|
||||
}
|
||||
|
||||
// TitleHasSuffix applies the HasSuffix predicate on the "title" field.
|
||||
func TitleHasSuffix(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.HasSuffix(s.C(FieldTitle), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldHasSuffix(FieldTitle, v))
|
||||
}
|
||||
|
||||
// TitleEqualFold applies the EqualFold predicate on the "title" field.
|
||||
func TitleEqualFold(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.EqualFold(s.C(FieldTitle), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldEqualFold(FieldTitle, v))
|
||||
}
|
||||
|
||||
// TitleContainsFold applies the ContainsFold predicate on the "title" field.
|
||||
func TitleContainsFold(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.ContainsFold(s.C(FieldTitle), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldContainsFold(FieldTitle, v))
|
||||
}
|
||||
|
||||
// PathEQ applies the EQ predicate on the "path" field.
|
||||
func PathEQ(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldPath), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldEQ(FieldPath, v))
|
||||
}
|
||||
|
||||
// PathNEQ applies the NEQ predicate on the "path" field.
|
||||
func PathNEQ(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldPath), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldNEQ(FieldPath, v))
|
||||
}
|
||||
|
||||
// PathIn applies the In predicate on the "path" field.
|
||||
func PathIn(vs ...string) predicate.Document {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldPath), v...))
|
||||
})
|
||||
return predicate.Document(sql.FieldIn(FieldPath, vs...))
|
||||
}
|
||||
|
||||
// PathNotIn applies the NotIn predicate on the "path" field.
|
||||
func PathNotIn(vs ...string) predicate.Document {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldPath), v...))
|
||||
})
|
||||
return predicate.Document(sql.FieldNotIn(FieldPath, vs...))
|
||||
}
|
||||
|
||||
// PathGT applies the GT predicate on the "path" field.
|
||||
func PathGT(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldPath), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldGT(FieldPath, v))
|
||||
}
|
||||
|
||||
// PathGTE applies the GTE predicate on the "path" field.
|
||||
func PathGTE(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldPath), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldGTE(FieldPath, v))
|
||||
}
|
||||
|
||||
// PathLT applies the LT predicate on the "path" field.
|
||||
func PathLT(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldPath), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldLT(FieldPath, v))
|
||||
}
|
||||
|
||||
// PathLTE applies the LTE predicate on the "path" field.
|
||||
func PathLTE(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldPath), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldLTE(FieldPath, v))
|
||||
}
|
||||
|
||||
// PathContains applies the Contains predicate on the "path" field.
|
||||
func PathContains(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.Contains(s.C(FieldPath), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldContains(FieldPath, v))
|
||||
}
|
||||
|
||||
// PathHasPrefix applies the HasPrefix predicate on the "path" field.
|
||||
func PathHasPrefix(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.HasPrefix(s.C(FieldPath), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldHasPrefix(FieldPath, v))
|
||||
}
|
||||
|
||||
// PathHasSuffix applies the HasSuffix predicate on the "path" field.
|
||||
func PathHasSuffix(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.HasSuffix(s.C(FieldPath), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldHasSuffix(FieldPath, v))
|
||||
}
|
||||
|
||||
// PathEqualFold applies the EqualFold predicate on the "path" field.
|
||||
func PathEqualFold(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.EqualFold(s.C(FieldPath), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldEqualFold(FieldPath, v))
|
||||
}
|
||||
|
||||
// PathContainsFold applies the ContainsFold predicate on the "path" field.
|
||||
func PathContainsFold(v string) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
s.Where(sql.ContainsFold(s.C(FieldPath), v))
|
||||
})
|
||||
return predicate.Document(sql.FieldContainsFold(FieldPath, v))
|
||||
}
|
||||
|
||||
// HasGroup applies the HasEdge predicate on the "group" edge.
|
||||
@@ -441,7 +291,6 @@ func HasGroup() predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(GroupTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, GroupTable, GroupColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
@@ -464,40 +313,11 @@ func HasGroupWith(preds ...predicate.Group) predicate.Document {
|
||||
})
|
||||
}
|
||||
|
||||
// HasDocumentTokens applies the HasEdge predicate on the "document_tokens" edge.
|
||||
func HasDocumentTokens() predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(DocumentTokensTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, DocumentTokensTable, DocumentTokensColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasDocumentTokensWith applies the HasEdge predicate on the "document_tokens" edge with a given conditions (other predicates).
|
||||
func HasDocumentTokensWith(preds ...predicate.DocumentToken) predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(DocumentTokensInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, DocumentTokensTable, DocumentTokensColumn),
|
||||
)
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// HasAttachments applies the HasEdge predicate on the "attachments" edge.
|
||||
func HasAttachments() predicate.Document {
|
||||
return predicate.Document(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(AttachmentsTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, AttachmentsTable, AttachmentsColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/document"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/documenttoken"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/group"
|
||||
)
|
||||
|
||||
@@ -89,21 +88,6 @@ func (dc *DocumentCreate) SetGroup(g *Group) *DocumentCreate {
|
||||
return dc.SetGroupID(g.ID)
|
||||
}
|
||||
|
||||
// AddDocumentTokenIDs adds the "document_tokens" edge to the DocumentToken entity by IDs.
|
||||
func (dc *DocumentCreate) AddDocumentTokenIDs(ids ...uuid.UUID) *DocumentCreate {
|
||||
dc.mutation.AddDocumentTokenIDs(ids...)
|
||||
return dc
|
||||
}
|
||||
|
||||
// AddDocumentTokens adds the "document_tokens" edges to the DocumentToken entity.
|
||||
func (dc *DocumentCreate) AddDocumentTokens(d ...*DocumentToken) *DocumentCreate {
|
||||
ids := make([]uuid.UUID, len(d))
|
||||
for i := range d {
|
||||
ids[i] = d[i].ID
|
||||
}
|
||||
return dc.AddDocumentTokenIDs(ids...)
|
||||
}
|
||||
|
||||
// AddAttachmentIDs adds the "attachments" edge to the Attachment entity by IDs.
|
||||
func (dc *DocumentCreate) AddAttachmentIDs(ids ...uuid.UUID) *DocumentCreate {
|
||||
dc.mutation.AddAttachmentIDs(ids...)
|
||||
@@ -126,50 +110,8 @@ func (dc *DocumentCreate) Mutation() *DocumentMutation {
|
||||
|
||||
// Save creates the Document in the database.
|
||||
func (dc *DocumentCreate) Save(ctx context.Context) (*Document, error) {
|
||||
var (
|
||||
err error
|
||||
node *Document
|
||||
)
|
||||
dc.defaults()
|
||||
if len(dc.hooks) == 0 {
|
||||
if err = dc.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node, err = dc.sqlSave(ctx)
|
||||
} else {
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*DocumentMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
if err = dc.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dc.mutation = mutation
|
||||
if node, err = dc.sqlSave(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mutation.id = &node.ID
|
||||
mutation.done = true
|
||||
return node, err
|
||||
})
|
||||
for i := len(dc.hooks) - 1; i >= 0; i-- {
|
||||
if dc.hooks[i] == nil {
|
||||
return nil, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = dc.hooks[i](mut)
|
||||
}
|
||||
v, err := mut.Mutate(ctx, dc.mutation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nv, ok := v.(*Document)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected node type %T returned from DocumentMutation", v)
|
||||
}
|
||||
node = nv
|
||||
}
|
||||
return node, err
|
||||
return withHooks[*Document, DocumentMutation](ctx, dc.sqlSave, dc.mutation, dc.hooks)
|
||||
}
|
||||
|
||||
// SaveX calls Save and panics if Save returns an error.
|
||||
@@ -241,6 +183,9 @@ func (dc *DocumentCreate) check() error {
|
||||
}
|
||||
|
||||
func (dc *DocumentCreate) sqlSave(ctx context.Context) (*Document, error) {
|
||||
if err := dc.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_node, _spec := dc.createSpec()
|
||||
if err := sqlgraph.CreateNode(ctx, dc.driver, _spec); err != nil {
|
||||
if sqlgraph.IsConstraintError(err) {
|
||||
@@ -255,54 +200,34 @@ func (dc *DocumentCreate) sqlSave(ctx context.Context) (*Document, error) {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
dc.mutation.id = &_node.ID
|
||||
dc.mutation.done = true
|
||||
return _node, nil
|
||||
}
|
||||
|
||||
func (dc *DocumentCreate) createSpec() (*Document, *sqlgraph.CreateSpec) {
|
||||
var (
|
||||
_node = &Document{config: dc.config}
|
||||
_spec = &sqlgraph.CreateSpec{
|
||||
Table: document.Table,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: document.FieldID,
|
||||
},
|
||||
}
|
||||
_spec = sqlgraph.NewCreateSpec(document.Table, sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID))
|
||||
)
|
||||
if id, ok := dc.mutation.ID(); ok {
|
||||
_node.ID = id
|
||||
_spec.ID.Value = &id
|
||||
}
|
||||
if value, ok := dc.mutation.CreatedAt(); ok {
|
||||
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: document.FieldCreatedAt,
|
||||
})
|
||||
_spec.SetField(document.FieldCreatedAt, field.TypeTime, value)
|
||||
_node.CreatedAt = value
|
||||
}
|
||||
if value, ok := dc.mutation.UpdatedAt(); ok {
|
||||
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: document.FieldUpdatedAt,
|
||||
})
|
||||
_spec.SetField(document.FieldUpdatedAt, field.TypeTime, value)
|
||||
_node.UpdatedAt = value
|
||||
}
|
||||
if value, ok := dc.mutation.Title(); ok {
|
||||
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeString,
|
||||
Value: value,
|
||||
Column: document.FieldTitle,
|
||||
})
|
||||
_spec.SetField(document.FieldTitle, field.TypeString, value)
|
||||
_node.Title = value
|
||||
}
|
||||
if value, ok := dc.mutation.Path(); ok {
|
||||
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeString,
|
||||
Value: value,
|
||||
Column: document.FieldPath,
|
||||
})
|
||||
_spec.SetField(document.FieldPath, field.TypeString, value)
|
||||
_node.Path = value
|
||||
}
|
||||
if nodes := dc.mutation.GroupIDs(); len(nodes) > 0 {
|
||||
@@ -325,25 +250,6 @@ func (dc *DocumentCreate) createSpec() (*Document, *sqlgraph.CreateSpec) {
|
||||
_node.group_documents = &nodes[0]
|
||||
_spec.Edges = append(_spec.Edges, edge)
|
||||
}
|
||||
if nodes := dc.mutation.DocumentTokensIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: document.DocumentTokensTable,
|
||||
Columns: []string{document.DocumentTokensColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: documenttoken.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges = append(_spec.Edges, edge)
|
||||
}
|
||||
if nodes := dc.mutation.AttachmentsIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
|
||||
@@ -4,7 +4,6 @@ package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
@@ -28,34 +27,7 @@ func (dd *DocumentDelete) Where(ps ...predicate.Document) *DocumentDelete {
|
||||
|
||||
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||
func (dd *DocumentDelete) Exec(ctx context.Context) (int, error) {
|
||||
var (
|
||||
err error
|
||||
affected int
|
||||
)
|
||||
if len(dd.hooks) == 0 {
|
||||
affected, err = dd.sqlExec(ctx)
|
||||
} else {
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*DocumentMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
dd.mutation = mutation
|
||||
affected, err = dd.sqlExec(ctx)
|
||||
mutation.done = true
|
||||
return affected, err
|
||||
})
|
||||
for i := len(dd.hooks) - 1; i >= 0; i-- {
|
||||
if dd.hooks[i] == nil {
|
||||
return 0, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = dd.hooks[i](mut)
|
||||
}
|
||||
if _, err := mut.Mutate(ctx, dd.mutation); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
return affected, err
|
||||
return withHooks[int, DocumentMutation](ctx, dd.sqlExec, dd.mutation, dd.hooks)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
@@ -68,15 +40,7 @@ func (dd *DocumentDelete) ExecX(ctx context.Context) int {
|
||||
}
|
||||
|
||||
func (dd *DocumentDelete) sqlExec(ctx context.Context) (int, error) {
|
||||
_spec := &sqlgraph.DeleteSpec{
|
||||
Node: &sqlgraph.NodeSpec{
|
||||
Table: document.Table,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: document.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
_spec := sqlgraph.NewDeleteSpec(document.Table, sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID))
|
||||
if ps := dd.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
@@ -88,6 +52,7 @@ func (dd *DocumentDelete) sqlExec(ctx context.Context) (int, error) {
|
||||
if err != nil && sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
dd.mutation.done = true
|
||||
return affected, err
|
||||
}
|
||||
|
||||
@@ -96,6 +61,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)
|
||||
@@ -111,5 +82,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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/document"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/documenttoken"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/group"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||
)
|
||||
@@ -22,16 +21,13 @@ import (
|
||||
// DocumentQuery is the builder for querying Document entities.
|
||||
type DocumentQuery struct {
|
||||
config
|
||||
limit *int
|
||||
offset *int
|
||||
unique *bool
|
||||
order []OrderFunc
|
||||
fields []string
|
||||
predicates []predicate.Document
|
||||
withGroup *GroupQuery
|
||||
withDocumentTokens *DocumentTokenQuery
|
||||
withAttachments *AttachmentQuery
|
||||
withFKs bool
|
||||
ctx *QueryContext
|
||||
order []OrderFunc
|
||||
inters []Interceptor
|
||||
predicates []predicate.Document
|
||||
withGroup *GroupQuery
|
||||
withAttachments *AttachmentQuery
|
||||
withFKs bool
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
@@ -43,26 +39,26 @@ func (dq *DocumentQuery) Where(ps ...predicate.Document) *DocumentQuery {
|
||||
return dq
|
||||
}
|
||||
|
||||
// Limit adds a limit step to the query.
|
||||
// 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 adds an offset step to the query.
|
||||
// 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
|
||||
}
|
||||
|
||||
// Order adds an order step to the query.
|
||||
// Order specifies how the records should be ordered.
|
||||
func (dq *DocumentQuery) Order(o ...OrderFunc) *DocumentQuery {
|
||||
dq.order = append(dq.order, o...)
|
||||
return dq
|
||||
@@ -70,7 +66,7 @@ func (dq *DocumentQuery) Order(o ...OrderFunc) *DocumentQuery {
|
||||
|
||||
// QueryGroup chains the current query on the "group" edge.
|
||||
func (dq *DocumentQuery) QueryGroup() *GroupQuery {
|
||||
query := &GroupQuery{config: dq.config}
|
||||
query := (&GroupClient{config: dq.config}).Query()
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := dq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
@@ -90,31 +86,9 @@ func (dq *DocumentQuery) QueryGroup() *GroupQuery {
|
||||
return query
|
||||
}
|
||||
|
||||
// QueryDocumentTokens chains the current query on the "document_tokens" edge.
|
||||
func (dq *DocumentQuery) QueryDocumentTokens() *DocumentTokenQuery {
|
||||
query := &DocumentTokenQuery{config: dq.config}
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := dq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector := dq.sqlQuery(ctx)
|
||||
if err := selector.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(document.Table, document.FieldID, selector),
|
||||
sqlgraph.To(documenttoken.Table, documenttoken.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, document.DocumentTokensTable, document.DocumentTokensColumn),
|
||||
)
|
||||
fromU = sqlgraph.SetNeighbors(dq.driver.Dialect(), step)
|
||||
return fromU, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// QueryAttachments chains the current query on the "attachments" edge.
|
||||
func (dq *DocumentQuery) QueryAttachments() *AttachmentQuery {
|
||||
query := &AttachmentQuery{config: dq.config}
|
||||
query := (&AttachmentClient{config: dq.config}).Query()
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := dq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
@@ -137,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(ctx)
|
||||
nodes, err := dq.Limit(1).All(setContextOp(ctx, dq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -160,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(ctx); err != nil {
|
||||
if ids, err = dq.Limit(1).IDs(setContextOp(ctx, dq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
@@ -183,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(ctx)
|
||||
nodes, err := dq.Limit(2).All(setContextOp(ctx, dq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -211,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(ctx); err != nil {
|
||||
if ids, err = dq.Limit(2).IDs(setContextOp(ctx, dq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
@@ -236,10 +210,12 @@ 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 = setContextOp(ctx, dq.ctx, "All")
|
||||
if err := dq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dq.sqlAll(ctx)
|
||||
qr := querierAll[[]*Document, *DocumentQuery]()
|
||||
return withInterceptors[[]*Document](ctx, dq, qr, dq.inters)
|
||||
}
|
||||
|
||||
// AllX is like All, but panics if an error occurs.
|
||||
@@ -252,9 +228,12 @@ 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
|
||||
if err := dq.Select(document.FieldID).Scan(ctx, &ids); err != nil {
|
||||
func (dq *DocumentQuery) IDs(ctx context.Context) (ids []uuid.UUID, err error) {
|
||||
if dq.ctx.Unique == nil && dq.path != nil {
|
||||
dq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, dq.ctx, "IDs")
|
||||
if err = dq.Select(document.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ids, nil
|
||||
@@ -271,10 +250,11 @@ 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 = setContextOp(ctx, dq.ctx, "Count")
|
||||
if err := dq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return dq.sqlCount(ctx)
|
||||
return withInterceptors[int](ctx, dq, querierCount[*DocumentQuery](), dq.inters)
|
||||
}
|
||||
|
||||
// CountX is like Count, but panics if an error occurs.
|
||||
@@ -288,10 +268,15 @@ 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) {
|
||||
if err := dq.prepareQuery(ctx); err != nil {
|
||||
return false, err
|
||||
ctx = setContextOp(ctx, dq.ctx, "Exist")
|
||||
switch _, err := dq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
case err != nil:
|
||||
return false, fmt.Errorf("ent: check existence: %w", err)
|
||||
default:
|
||||
return true, nil
|
||||
}
|
||||
return dq.sqlExist(ctx)
|
||||
}
|
||||
|
||||
// ExistX is like Exist, but panics if an error occurs.
|
||||
@@ -310,25 +295,23 @@ func (dq *DocumentQuery) Clone() *DocumentQuery {
|
||||
return nil
|
||||
}
|
||||
return &DocumentQuery{
|
||||
config: dq.config,
|
||||
limit: dq.limit,
|
||||
offset: dq.offset,
|
||||
order: append([]OrderFunc{}, dq.order...),
|
||||
predicates: append([]predicate.Document{}, dq.predicates...),
|
||||
withGroup: dq.withGroup.Clone(),
|
||||
withDocumentTokens: dq.withDocumentTokens.Clone(),
|
||||
withAttachments: dq.withAttachments.Clone(),
|
||||
config: dq.config,
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
// WithGroup tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "group" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (dq *DocumentQuery) WithGroup(opts ...func(*GroupQuery)) *DocumentQuery {
|
||||
query := &GroupQuery{config: dq.config}
|
||||
query := (&GroupClient{config: dq.config}).Query()
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
@@ -336,21 +319,10 @@ func (dq *DocumentQuery) WithGroup(opts ...func(*GroupQuery)) *DocumentQuery {
|
||||
return dq
|
||||
}
|
||||
|
||||
// WithDocumentTokens tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "document_tokens" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (dq *DocumentQuery) WithDocumentTokens(opts ...func(*DocumentTokenQuery)) *DocumentQuery {
|
||||
query := &DocumentTokenQuery{config: dq.config}
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
dq.withDocumentTokens = query
|
||||
return dq
|
||||
}
|
||||
|
||||
// WithAttachments tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "attachments" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (dq *DocumentQuery) WithAttachments(opts ...func(*AttachmentQuery)) *DocumentQuery {
|
||||
query := &AttachmentQuery{config: dq.config}
|
||||
query := (&AttachmentClient{config: dq.config}).Query()
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
@@ -373,16 +345,11 @@ func (dq *DocumentQuery) WithAttachments(opts ...func(*AttachmentQuery)) *Docume
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (dq *DocumentQuery) GroupBy(field string, fields ...string) *DocumentGroupBy {
|
||||
grbuild := &DocumentGroupBy{config: dq.config}
|
||||
grbuild.fields = append([]string{field}, fields...)
|
||||
grbuild.path = func(ctx context.Context) (prev *sql.Selector, err error) {
|
||||
if err := dq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dq.sqlQuery(ctx), nil
|
||||
}
|
||||
dq.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &DocumentGroupBy{build: dq}
|
||||
grbuild.flds = &dq.ctx.Fields
|
||||
grbuild.label = document.Label
|
||||
grbuild.flds, grbuild.scan = &grbuild.fields, grbuild.Scan
|
||||
grbuild.scan = grbuild.Scan
|
||||
return grbuild
|
||||
}
|
||||
|
||||
@@ -399,15 +366,30 @@ 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...)
|
||||
selbuild := &DocumentSelect{DocumentQuery: dq}
|
||||
selbuild.label = document.Label
|
||||
selbuild.flds, selbuild.scan = &dq.fields, selbuild.Scan
|
||||
return selbuild
|
||||
dq.ctx.Fields = append(dq.ctx.Fields, fields...)
|
||||
sbuild := &DocumentSelect{DocumentQuery: dq}
|
||||
sbuild.label = document.Label
|
||||
sbuild.flds, sbuild.scan = &dq.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
// Aggregate returns a DocumentSelect configured with the given aggregations.
|
||||
func (dq *DocumentQuery) Aggregate(fns ...AggregateFunc) *DocumentSelect {
|
||||
return dq.Select().Aggregate(fns...)
|
||||
}
|
||||
|
||||
func (dq *DocumentQuery) prepareQuery(ctx context.Context) error {
|
||||
for _, f := range dq.fields {
|
||||
for _, inter := range dq.inters {
|
||||
if inter == nil {
|
||||
return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
|
||||
}
|
||||
if trv, ok := inter.(Traverser); ok {
|
||||
if err := trv.Traverse(ctx, dq); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range dq.ctx.Fields {
|
||||
if !document.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
@@ -427,9 +409,8 @@ func (dq *DocumentQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Doc
|
||||
nodes = []*Document{}
|
||||
withFKs = dq.withFKs
|
||||
_spec = dq.querySpec()
|
||||
loadedTypes = [3]bool{
|
||||
loadedTypes = [2]bool{
|
||||
dq.withGroup != nil,
|
||||
dq.withDocumentTokens != nil,
|
||||
dq.withAttachments != nil,
|
||||
}
|
||||
)
|
||||
@@ -463,13 +444,6 @@ func (dq *DocumentQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Doc
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if query := dq.withDocumentTokens; query != nil {
|
||||
if err := dq.loadDocumentTokens(ctx, query, nodes,
|
||||
func(n *Document) { n.Edges.DocumentTokens = []*DocumentToken{} },
|
||||
func(n *Document, e *DocumentToken) { n.Edges.DocumentTokens = append(n.Edges.DocumentTokens, e) }); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if query := dq.withAttachments; query != nil {
|
||||
if err := dq.loadAttachments(ctx, query, nodes,
|
||||
func(n *Document) { n.Edges.Attachments = []*Attachment{} },
|
||||
@@ -493,6 +467,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 {
|
||||
@@ -509,37 +486,6 @@ func (dq *DocumentQuery) loadGroup(ctx context.Context, query *GroupQuery, nodes
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (dq *DocumentQuery) loadDocumentTokens(ctx context.Context, query *DocumentTokenQuery, nodes []*Document, init func(*Document), assign func(*Document, *DocumentToken)) error {
|
||||
fks := make([]driver.Value, 0, len(nodes))
|
||||
nodeids := make(map[uuid.UUID]*Document)
|
||||
for i := range nodes {
|
||||
fks = append(fks, nodes[i].ID)
|
||||
nodeids[nodes[i].ID] = nodes[i]
|
||||
if init != nil {
|
||||
init(nodes[i])
|
||||
}
|
||||
}
|
||||
query.withFKs = true
|
||||
query.Where(predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.InValues(document.DocumentTokensColumn, fks...))
|
||||
}))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, n := range neighbors {
|
||||
fk := n.document_document_tokens
|
||||
if fk == nil {
|
||||
return fmt.Errorf(`foreign-key "document_document_tokens" is nil for node %v`, n.ID)
|
||||
}
|
||||
node, ok := nodeids[*fk]
|
||||
if !ok {
|
||||
return fmt.Errorf(`unexpected foreign-key "document_document_tokens" returned %v for node %v`, *fk, n.ID)
|
||||
}
|
||||
assign(node, n)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (dq *DocumentQuery) loadAttachments(ctx context.Context, query *AttachmentQuery, nodes []*Document, init func(*Document), assign func(*Document, *Attachment)) error {
|
||||
fks := make([]driver.Value, 0, len(nodes))
|
||||
nodeids := make(map[uuid.UUID]*Document)
|
||||
@@ -574,41 +520,22 @@ 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)
|
||||
}
|
||||
|
||||
func (dq *DocumentQuery) sqlExist(ctx context.Context) (bool, error) {
|
||||
switch _, err := dq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
case err != nil:
|
||||
return false, fmt.Errorf("ent: check existence: %w", err)
|
||||
default:
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (dq *DocumentQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
_spec := &sqlgraph.QuerySpec{
|
||||
Node: &sqlgraph.NodeSpec{
|
||||
Table: document.Table,
|
||||
Columns: document.Columns,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: document.FieldID,
|
||||
},
|
||||
},
|
||||
From: dq.sql,
|
||||
Unique: true,
|
||||
}
|
||||
if unique := dq.unique; unique != nil {
|
||||
_spec := sqlgraph.NewQuerySpec(document.Table, document.Columns, sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID))
|
||||
_spec.From = dq.sql
|
||||
if unique := dq.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
} else if dq.path != nil {
|
||||
_spec.Unique = true
|
||||
}
|
||||
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 {
|
||||
@@ -624,10 +551,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 {
|
||||
@@ -643,7 +570,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
|
||||
}
|
||||
@@ -652,7 +579,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 {
|
||||
@@ -661,12 +588,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
|
||||
@@ -674,13 +601,8 @@ func (dq *DocumentQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
|
||||
// DocumentGroupBy is the group-by builder for Document entities.
|
||||
type DocumentGroupBy struct {
|
||||
config
|
||||
selector
|
||||
fields []string
|
||||
fns []AggregateFunc
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
build *DocumentQuery
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the group-by query.
|
||||
@@ -689,74 +611,77 @@ func (dgb *DocumentGroupBy) Aggregate(fns ...AggregateFunc) *DocumentGroupBy {
|
||||
return dgb
|
||||
}
|
||||
|
||||
// Scan applies the group-by query and scans the result into the given value.
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (dgb *DocumentGroupBy) Scan(ctx context.Context, v any) error {
|
||||
query, err := dgb.path(ctx)
|
||||
if err != nil {
|
||||
ctx = setContextOp(ctx, dgb.build.ctx, "GroupBy")
|
||||
if err := dgb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
dgb.sql = query
|
||||
return dgb.sqlScan(ctx, v)
|
||||
return scanWithInterceptors[*DocumentQuery, *DocumentGroupBy](ctx, dgb.build, dgb, dgb.build.inters, v)
|
||||
}
|
||||
|
||||
func (dgb *DocumentGroupBy) sqlScan(ctx context.Context, v any) error {
|
||||
for _, f := range dgb.fields {
|
||||
if !document.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("invalid field %q for group-by", f)}
|
||||
}
|
||||
}
|
||||
selector := dgb.sqlQuery()
|
||||
if err := selector.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := dgb.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
func (dgb *DocumentGroupBy) sqlQuery() *sql.Selector {
|
||||
selector := dgb.sql.Select()
|
||||
func (dgb *DocumentGroupBy) sqlScan(ctx context.Context, root *DocumentQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx).Select()
|
||||
aggregation := make([]string, 0, len(dgb.fns))
|
||||
for _, fn := range dgb.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
// If no columns were selected in a custom aggregation function, the default
|
||||
// selection is the fields used for "group-by", and the aggregation functions.
|
||||
if len(selector.SelectedColumns()) == 0 {
|
||||
columns := make([]string, 0, len(dgb.fields)+len(dgb.fns))
|
||||
for _, f := range dgb.fields {
|
||||
columns := make([]string, 0, len(*dgb.flds)+len(dgb.fns))
|
||||
for _, f := range *dgb.flds {
|
||||
columns = append(columns, selector.C(f))
|
||||
}
|
||||
columns = append(columns, aggregation...)
|
||||
selector.Select(columns...)
|
||||
}
|
||||
return selector.GroupBy(selector.Columns(dgb.fields...)...)
|
||||
selector.GroupBy(selector.Columns(*dgb.flds...)...)
|
||||
if err := selector.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := dgb.build.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
// DocumentSelect is the builder for selecting fields of Document entities.
|
||||
type DocumentSelect struct {
|
||||
*DocumentQuery
|
||||
selector
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the selector query.
|
||||
func (ds *DocumentSelect) Aggregate(fns ...AggregateFunc) *DocumentSelect {
|
||||
ds.fns = append(ds.fns, fns...)
|
||||
return ds
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (ds *DocumentSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, ds.ctx, "Select")
|
||||
if err := ds.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
ds.sql = ds.DocumentQuery.sqlQuery(ctx)
|
||||
return ds.sqlScan(ctx, v)
|
||||
return scanWithInterceptors[*DocumentQuery, *DocumentSelect](ctx, ds.DocumentQuery, ds, ds.inters, v)
|
||||
}
|
||||
|
||||
func (ds *DocumentSelect) sqlScan(ctx context.Context, v any) error {
|
||||
func (ds *DocumentSelect) sqlScan(ctx context.Context, root *DocumentQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx)
|
||||
aggregation := make([]string, 0, len(ds.fns))
|
||||
for _, fn := range ds.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
switch n := len(*ds.selector.flds); {
|
||||
case n == 0 && len(aggregation) > 0:
|
||||
selector.Select(aggregation...)
|
||||
case n != 0 && len(aggregation) > 0:
|
||||
selector.AppendSelect(aggregation...)
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := ds.sql.Query()
|
||||
query, args := selector.Query()
|
||||
if err := ds.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/document"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/documenttoken"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/group"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||
)
|
||||
@@ -61,21 +60,6 @@ func (du *DocumentUpdate) SetGroup(g *Group) *DocumentUpdate {
|
||||
return du.SetGroupID(g.ID)
|
||||
}
|
||||
|
||||
// AddDocumentTokenIDs adds the "document_tokens" edge to the DocumentToken entity by IDs.
|
||||
func (du *DocumentUpdate) AddDocumentTokenIDs(ids ...uuid.UUID) *DocumentUpdate {
|
||||
du.mutation.AddDocumentTokenIDs(ids...)
|
||||
return du
|
||||
}
|
||||
|
||||
// AddDocumentTokens adds the "document_tokens" edges to the DocumentToken entity.
|
||||
func (du *DocumentUpdate) AddDocumentTokens(d ...*DocumentToken) *DocumentUpdate {
|
||||
ids := make([]uuid.UUID, len(d))
|
||||
for i := range d {
|
||||
ids[i] = d[i].ID
|
||||
}
|
||||
return du.AddDocumentTokenIDs(ids...)
|
||||
}
|
||||
|
||||
// AddAttachmentIDs adds the "attachments" edge to the Attachment entity by IDs.
|
||||
func (du *DocumentUpdate) AddAttachmentIDs(ids ...uuid.UUID) *DocumentUpdate {
|
||||
du.mutation.AddAttachmentIDs(ids...)
|
||||
@@ -102,27 +86,6 @@ func (du *DocumentUpdate) ClearGroup() *DocumentUpdate {
|
||||
return du
|
||||
}
|
||||
|
||||
// ClearDocumentTokens clears all "document_tokens" edges to the DocumentToken entity.
|
||||
func (du *DocumentUpdate) ClearDocumentTokens() *DocumentUpdate {
|
||||
du.mutation.ClearDocumentTokens()
|
||||
return du
|
||||
}
|
||||
|
||||
// RemoveDocumentTokenIDs removes the "document_tokens" edge to DocumentToken entities by IDs.
|
||||
func (du *DocumentUpdate) RemoveDocumentTokenIDs(ids ...uuid.UUID) *DocumentUpdate {
|
||||
du.mutation.RemoveDocumentTokenIDs(ids...)
|
||||
return du
|
||||
}
|
||||
|
||||
// RemoveDocumentTokens removes "document_tokens" edges to DocumentToken entities.
|
||||
func (du *DocumentUpdate) RemoveDocumentTokens(d ...*DocumentToken) *DocumentUpdate {
|
||||
ids := make([]uuid.UUID, len(d))
|
||||
for i := range d {
|
||||
ids[i] = d[i].ID
|
||||
}
|
||||
return du.RemoveDocumentTokenIDs(ids...)
|
||||
}
|
||||
|
||||
// ClearAttachments clears all "attachments" edges to the Attachment entity.
|
||||
func (du *DocumentUpdate) ClearAttachments() *DocumentUpdate {
|
||||
du.mutation.ClearAttachments()
|
||||
@@ -146,41 +109,8 @@ func (du *DocumentUpdate) RemoveAttachments(a ...*Attachment) *DocumentUpdate {
|
||||
|
||||
// Save executes the query and returns the number of nodes affected by the update operation.
|
||||
func (du *DocumentUpdate) Save(ctx context.Context) (int, error) {
|
||||
var (
|
||||
err error
|
||||
affected int
|
||||
)
|
||||
du.defaults()
|
||||
if len(du.hooks) == 0 {
|
||||
if err = du.check(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
affected, err = du.sqlSave(ctx)
|
||||
} else {
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*DocumentMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
if err = du.check(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
du.mutation = mutation
|
||||
affected, err = du.sqlSave(ctx)
|
||||
mutation.done = true
|
||||
return affected, err
|
||||
})
|
||||
for i := len(du.hooks) - 1; i >= 0; i-- {
|
||||
if du.hooks[i] == nil {
|
||||
return 0, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = du.hooks[i](mut)
|
||||
}
|
||||
if _, err := mut.Mutate(ctx, du.mutation); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
return affected, err
|
||||
return withHooks[int, DocumentMutation](ctx, du.sqlSave, du.mutation, du.hooks)
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
@@ -232,16 +162,10 @@ func (du *DocumentUpdate) check() error {
|
||||
}
|
||||
|
||||
func (du *DocumentUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
_spec := &sqlgraph.UpdateSpec{
|
||||
Node: &sqlgraph.NodeSpec{
|
||||
Table: document.Table,
|
||||
Columns: document.Columns,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: document.FieldID,
|
||||
},
|
||||
},
|
||||
if err := du.check(); err != nil {
|
||||
return n, err
|
||||
}
|
||||
_spec := sqlgraph.NewUpdateSpec(document.Table, document.Columns, sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID))
|
||||
if ps := du.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
@@ -250,25 +174,13 @@ func (du *DocumentUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
}
|
||||
}
|
||||
if value, ok := du.mutation.UpdatedAt(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: document.FieldUpdatedAt,
|
||||
})
|
||||
_spec.SetField(document.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if value, ok := du.mutation.Title(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeString,
|
||||
Value: value,
|
||||
Column: document.FieldTitle,
|
||||
})
|
||||
_spec.SetField(document.FieldTitle, field.TypeString, value)
|
||||
}
|
||||
if value, ok := du.mutation.Path(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeString,
|
||||
Value: value,
|
||||
Column: document.FieldPath,
|
||||
})
|
||||
_spec.SetField(document.FieldPath, field.TypeString, value)
|
||||
}
|
||||
if du.mutation.GroupCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
@@ -305,60 +217,6 @@ func (du *DocumentUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if du.mutation.DocumentTokensCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: document.DocumentTokensTable,
|
||||
Columns: []string{document.DocumentTokensColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: documenttoken.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := du.mutation.RemovedDocumentTokensIDs(); len(nodes) > 0 && !du.mutation.DocumentTokensCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: document.DocumentTokensTable,
|
||||
Columns: []string{document.DocumentTokensColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: documenttoken.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := du.mutation.DocumentTokensIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: document.DocumentTokensTable,
|
||||
Columns: []string{document.DocumentTokensColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: documenttoken.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if du.mutation.AttachmentsCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
@@ -421,6 +279,7 @@ func (du *DocumentUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
du.mutation.done = true
|
||||
return n, nil
|
||||
}
|
||||
|
||||
@@ -461,21 +320,6 @@ func (duo *DocumentUpdateOne) SetGroup(g *Group) *DocumentUpdateOne {
|
||||
return duo.SetGroupID(g.ID)
|
||||
}
|
||||
|
||||
// AddDocumentTokenIDs adds the "document_tokens" edge to the DocumentToken entity by IDs.
|
||||
func (duo *DocumentUpdateOne) AddDocumentTokenIDs(ids ...uuid.UUID) *DocumentUpdateOne {
|
||||
duo.mutation.AddDocumentTokenIDs(ids...)
|
||||
return duo
|
||||
}
|
||||
|
||||
// AddDocumentTokens adds the "document_tokens" edges to the DocumentToken entity.
|
||||
func (duo *DocumentUpdateOne) AddDocumentTokens(d ...*DocumentToken) *DocumentUpdateOne {
|
||||
ids := make([]uuid.UUID, len(d))
|
||||
for i := range d {
|
||||
ids[i] = d[i].ID
|
||||
}
|
||||
return duo.AddDocumentTokenIDs(ids...)
|
||||
}
|
||||
|
||||
// AddAttachmentIDs adds the "attachments" edge to the Attachment entity by IDs.
|
||||
func (duo *DocumentUpdateOne) AddAttachmentIDs(ids ...uuid.UUID) *DocumentUpdateOne {
|
||||
duo.mutation.AddAttachmentIDs(ids...)
|
||||
@@ -502,27 +346,6 @@ func (duo *DocumentUpdateOne) ClearGroup() *DocumentUpdateOne {
|
||||
return duo
|
||||
}
|
||||
|
||||
// ClearDocumentTokens clears all "document_tokens" edges to the DocumentToken entity.
|
||||
func (duo *DocumentUpdateOne) ClearDocumentTokens() *DocumentUpdateOne {
|
||||
duo.mutation.ClearDocumentTokens()
|
||||
return duo
|
||||
}
|
||||
|
||||
// RemoveDocumentTokenIDs removes the "document_tokens" edge to DocumentToken entities by IDs.
|
||||
func (duo *DocumentUpdateOne) RemoveDocumentTokenIDs(ids ...uuid.UUID) *DocumentUpdateOne {
|
||||
duo.mutation.RemoveDocumentTokenIDs(ids...)
|
||||
return duo
|
||||
}
|
||||
|
||||
// RemoveDocumentTokens removes "document_tokens" edges to DocumentToken entities.
|
||||
func (duo *DocumentUpdateOne) RemoveDocumentTokens(d ...*DocumentToken) *DocumentUpdateOne {
|
||||
ids := make([]uuid.UUID, len(d))
|
||||
for i := range d {
|
||||
ids[i] = d[i].ID
|
||||
}
|
||||
return duo.RemoveDocumentTokenIDs(ids...)
|
||||
}
|
||||
|
||||
// ClearAttachments clears all "attachments" edges to the Attachment entity.
|
||||
func (duo *DocumentUpdateOne) ClearAttachments() *DocumentUpdateOne {
|
||||
duo.mutation.ClearAttachments()
|
||||
@@ -544,6 +367,12 @@ func (duo *DocumentUpdateOne) RemoveAttachments(a ...*Attachment) *DocumentUpdat
|
||||
return duo.RemoveAttachmentIDs(ids...)
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the DocumentUpdate builder.
|
||||
func (duo *DocumentUpdateOne) Where(ps ...predicate.Document) *DocumentUpdateOne {
|
||||
duo.mutation.Where(ps...)
|
||||
return duo
|
||||
}
|
||||
|
||||
// Select allows selecting one or more fields (columns) of the returned entity.
|
||||
// The default is selecting all fields defined in the entity schema.
|
||||
func (duo *DocumentUpdateOne) Select(field string, fields ...string) *DocumentUpdateOne {
|
||||
@@ -553,47 +382,8 @@ func (duo *DocumentUpdateOne) Select(field string, fields ...string) *DocumentUp
|
||||
|
||||
// Save executes the query and returns the updated Document entity.
|
||||
func (duo *DocumentUpdateOne) Save(ctx context.Context) (*Document, error) {
|
||||
var (
|
||||
err error
|
||||
node *Document
|
||||
)
|
||||
duo.defaults()
|
||||
if len(duo.hooks) == 0 {
|
||||
if err = duo.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node, err = duo.sqlSave(ctx)
|
||||
} else {
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*DocumentMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
if err = duo.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
duo.mutation = mutation
|
||||
node, err = duo.sqlSave(ctx)
|
||||
mutation.done = true
|
||||
return node, err
|
||||
})
|
||||
for i := len(duo.hooks) - 1; i >= 0; i-- {
|
||||
if duo.hooks[i] == nil {
|
||||
return nil, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = duo.hooks[i](mut)
|
||||
}
|
||||
v, err := mut.Mutate(ctx, duo.mutation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nv, ok := v.(*Document)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected node type %T returned from DocumentMutation", v)
|
||||
}
|
||||
node = nv
|
||||
}
|
||||
return node, err
|
||||
return withHooks[*Document, DocumentMutation](ctx, duo.sqlSave, duo.mutation, duo.hooks)
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
@@ -645,16 +435,10 @@ func (duo *DocumentUpdateOne) check() error {
|
||||
}
|
||||
|
||||
func (duo *DocumentUpdateOne) sqlSave(ctx context.Context) (_node *Document, err error) {
|
||||
_spec := &sqlgraph.UpdateSpec{
|
||||
Node: &sqlgraph.NodeSpec{
|
||||
Table: document.Table,
|
||||
Columns: document.Columns,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: document.FieldID,
|
||||
},
|
||||
},
|
||||
if err := duo.check(); err != nil {
|
||||
return _node, err
|
||||
}
|
||||
_spec := sqlgraph.NewUpdateSpec(document.Table, document.Columns, sqlgraph.NewFieldSpec(document.FieldID, field.TypeUUID))
|
||||
id, ok := duo.mutation.ID()
|
||||
if !ok {
|
||||
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "Document.id" for update`)}
|
||||
@@ -680,25 +464,13 @@ func (duo *DocumentUpdateOne) sqlSave(ctx context.Context) (_node *Document, err
|
||||
}
|
||||
}
|
||||
if value, ok := duo.mutation.UpdatedAt(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: document.FieldUpdatedAt,
|
||||
})
|
||||
_spec.SetField(document.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if value, ok := duo.mutation.Title(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeString,
|
||||
Value: value,
|
||||
Column: document.FieldTitle,
|
||||
})
|
||||
_spec.SetField(document.FieldTitle, field.TypeString, value)
|
||||
}
|
||||
if value, ok := duo.mutation.Path(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeString,
|
||||
Value: value,
|
||||
Column: document.FieldPath,
|
||||
})
|
||||
_spec.SetField(document.FieldPath, field.TypeString, value)
|
||||
}
|
||||
if duo.mutation.GroupCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
@@ -735,60 +507,6 @@ func (duo *DocumentUpdateOne) sqlSave(ctx context.Context) (_node *Document, err
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if duo.mutation.DocumentTokensCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: document.DocumentTokensTable,
|
||||
Columns: []string{document.DocumentTokensColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: documenttoken.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := duo.mutation.RemovedDocumentTokensIDs(); len(nodes) > 0 && !duo.mutation.DocumentTokensCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: document.DocumentTokensTable,
|
||||
Columns: []string{document.DocumentTokensColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: documenttoken.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := duo.mutation.DocumentTokensIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: document.DocumentTokensTable,
|
||||
Columns: []string{document.DocumentTokensColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: documenttoken.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if duo.mutation.AttachmentsCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
@@ -854,5 +572,6 @@ func (duo *DocumentUpdateOne) sqlSave(ctx context.Context) (_node *Document, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
duo.mutation.done = true
|
||||
return _node, nil
|
||||
}
|
||||
|
||||
@@ -1,190 +0,0 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/document"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/documenttoken"
|
||||
)
|
||||
|
||||
// DocumentToken is the model entity for the DocumentToken schema.
|
||||
type DocumentToken struct {
|
||||
config `json:"-"`
|
||||
// ID of the ent.
|
||||
ID uuid.UUID `json:"id,omitempty"`
|
||||
// CreatedAt holds the value of the "created_at" field.
|
||||
CreatedAt time.Time `json:"created_at,omitempty"`
|
||||
// UpdatedAt holds the value of the "updated_at" field.
|
||||
UpdatedAt time.Time `json:"updated_at,omitempty"`
|
||||
// Token holds the value of the "token" field.
|
||||
Token []byte `json:"token,omitempty"`
|
||||
// Uses holds the value of the "uses" field.
|
||||
Uses int `json:"uses,omitempty"`
|
||||
// ExpiresAt holds the value of the "expires_at" field.
|
||||
ExpiresAt time.Time `json:"expires_at,omitempty"`
|
||||
// Edges holds the relations/edges for other nodes in the graph.
|
||||
// The values are being populated by the DocumentTokenQuery when eager-loading is set.
|
||||
Edges DocumentTokenEdges `json:"edges"`
|
||||
document_document_tokens *uuid.UUID
|
||||
}
|
||||
|
||||
// DocumentTokenEdges holds the relations/edges for other nodes in the graph.
|
||||
type DocumentTokenEdges struct {
|
||||
// Document holds the value of the document edge.
|
||||
Document *Document `json:"document,omitempty"`
|
||||
// loadedTypes holds the information for reporting if a
|
||||
// type was loaded (or requested) in eager-loading or not.
|
||||
loadedTypes [1]bool
|
||||
}
|
||||
|
||||
// DocumentOrErr returns the Document value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e DocumentTokenEdges) DocumentOrErr() (*Document, error) {
|
||||
if e.loadedTypes[0] {
|
||||
if e.Document == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: document.Label}
|
||||
}
|
||||
return e.Document, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "document"}
|
||||
}
|
||||
|
||||
// scanValues returns the types for scanning values from sql.Rows.
|
||||
func (*DocumentToken) scanValues(columns []string) ([]any, error) {
|
||||
values := make([]any, len(columns))
|
||||
for i := range columns {
|
||||
switch columns[i] {
|
||||
case documenttoken.FieldToken:
|
||||
values[i] = new([]byte)
|
||||
case documenttoken.FieldUses:
|
||||
values[i] = new(sql.NullInt64)
|
||||
case documenttoken.FieldCreatedAt, documenttoken.FieldUpdatedAt, documenttoken.FieldExpiresAt:
|
||||
values[i] = new(sql.NullTime)
|
||||
case documenttoken.FieldID:
|
||||
values[i] = new(uuid.UUID)
|
||||
case documenttoken.ForeignKeys[0]: // document_document_tokens
|
||||
values[i] = &sql.NullScanner{S: new(uuid.UUID)}
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected column %q for type DocumentToken", columns[i])
|
||||
}
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// assignValues assigns the values that were returned from sql.Rows (after scanning)
|
||||
// to the DocumentToken fields.
|
||||
func (dt *DocumentToken) assignValues(columns []string, values []any) error {
|
||||
if m, n := len(values), len(columns); m < n {
|
||||
return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
|
||||
}
|
||||
for i := range columns {
|
||||
switch columns[i] {
|
||||
case documenttoken.FieldID:
|
||||
if value, ok := values[i].(*uuid.UUID); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field id", values[i])
|
||||
} else if value != nil {
|
||||
dt.ID = *value
|
||||
}
|
||||
case documenttoken.FieldCreatedAt:
|
||||
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field created_at", values[i])
|
||||
} else if value.Valid {
|
||||
dt.CreatedAt = value.Time
|
||||
}
|
||||
case documenttoken.FieldUpdatedAt:
|
||||
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field updated_at", values[i])
|
||||
} else if value.Valid {
|
||||
dt.UpdatedAt = value.Time
|
||||
}
|
||||
case documenttoken.FieldToken:
|
||||
if value, ok := values[i].(*[]byte); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field token", values[i])
|
||||
} else if value != nil {
|
||||
dt.Token = *value
|
||||
}
|
||||
case documenttoken.FieldUses:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field uses", values[i])
|
||||
} else if value.Valid {
|
||||
dt.Uses = int(value.Int64)
|
||||
}
|
||||
case documenttoken.FieldExpiresAt:
|
||||
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field expires_at", values[i])
|
||||
} else if value.Valid {
|
||||
dt.ExpiresAt = value.Time
|
||||
}
|
||||
case documenttoken.ForeignKeys[0]:
|
||||
if value, ok := values[i].(*sql.NullScanner); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field document_document_tokens", values[i])
|
||||
} else if value.Valid {
|
||||
dt.document_document_tokens = new(uuid.UUID)
|
||||
*dt.document_document_tokens = *value.S.(*uuid.UUID)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// QueryDocument queries the "document" edge of the DocumentToken entity.
|
||||
func (dt *DocumentToken) QueryDocument() *DocumentQuery {
|
||||
return (&DocumentTokenClient{config: dt.config}).QueryDocument(dt)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this DocumentToken.
|
||||
// Note that you need to call DocumentToken.Unwrap() before calling this method if this DocumentToken
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (dt *DocumentToken) Update() *DocumentTokenUpdateOne {
|
||||
return (&DocumentTokenClient{config: dt.config}).UpdateOne(dt)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the DocumentToken entity that was returned from a transaction after it was closed,
|
||||
// so that all future queries will be executed through the driver which created the transaction.
|
||||
func (dt *DocumentToken) Unwrap() *DocumentToken {
|
||||
_tx, ok := dt.config.driver.(*txDriver)
|
||||
if !ok {
|
||||
panic("ent: DocumentToken is not a transactional entity")
|
||||
}
|
||||
dt.config.driver = _tx.drv
|
||||
return dt
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer.
|
||||
func (dt *DocumentToken) String() string {
|
||||
var builder strings.Builder
|
||||
builder.WriteString("DocumentToken(")
|
||||
builder.WriteString(fmt.Sprintf("id=%v, ", dt.ID))
|
||||
builder.WriteString("created_at=")
|
||||
builder.WriteString(dt.CreatedAt.Format(time.ANSIC))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("updated_at=")
|
||||
builder.WriteString(dt.UpdatedAt.Format(time.ANSIC))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("token=")
|
||||
builder.WriteString(fmt.Sprintf("%v", dt.Token))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("uses=")
|
||||
builder.WriteString(fmt.Sprintf("%v", dt.Uses))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("expires_at=")
|
||||
builder.WriteString(dt.ExpiresAt.Format(time.ANSIC))
|
||||
builder.WriteByte(')')
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
// DocumentTokens is a parsable slice of DocumentToken.
|
||||
type DocumentTokens []*DocumentToken
|
||||
|
||||
func (dt DocumentTokens) config(cfg config) {
|
||||
for _i := range dt {
|
||||
dt[_i].config = cfg
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package documenttoken
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const (
|
||||
// Label holds the string label denoting the documenttoken type in the database.
|
||||
Label = "document_token"
|
||||
// FieldID holds the string denoting the id field in the database.
|
||||
FieldID = "id"
|
||||
// FieldCreatedAt holds the string denoting the created_at field in the database.
|
||||
FieldCreatedAt = "created_at"
|
||||
// FieldUpdatedAt holds the string denoting the updated_at field in the database.
|
||||
FieldUpdatedAt = "updated_at"
|
||||
// FieldToken holds the string denoting the token field in the database.
|
||||
FieldToken = "token"
|
||||
// FieldUses holds the string denoting the uses field in the database.
|
||||
FieldUses = "uses"
|
||||
// FieldExpiresAt holds the string denoting the expires_at field in the database.
|
||||
FieldExpiresAt = "expires_at"
|
||||
// EdgeDocument holds the string denoting the document edge name in mutations.
|
||||
EdgeDocument = "document"
|
||||
// Table holds the table name of the documenttoken in the database.
|
||||
Table = "document_tokens"
|
||||
// DocumentTable is the table that holds the document relation/edge.
|
||||
DocumentTable = "document_tokens"
|
||||
// DocumentInverseTable is the table name for the Document entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "document" package.
|
||||
DocumentInverseTable = "documents"
|
||||
// DocumentColumn is the table column denoting the document relation/edge.
|
||||
DocumentColumn = "document_document_tokens"
|
||||
)
|
||||
|
||||
// Columns holds all SQL columns for documenttoken fields.
|
||||
var Columns = []string{
|
||||
FieldID,
|
||||
FieldCreatedAt,
|
||||
FieldUpdatedAt,
|
||||
FieldToken,
|
||||
FieldUses,
|
||||
FieldExpiresAt,
|
||||
}
|
||||
|
||||
// ForeignKeys holds the SQL foreign-keys that are owned by the "document_tokens"
|
||||
// table and are not defined as standalone fields in the schema.
|
||||
var ForeignKeys = []string{
|
||||
"document_document_tokens",
|
||||
}
|
||||
|
||||
// ValidColumn reports if the column name is valid (part of the table columns).
|
||||
func ValidColumn(column string) bool {
|
||||
for i := range Columns {
|
||||
if column == Columns[i] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
for i := range ForeignKeys {
|
||||
if column == ForeignKeys[i] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var (
|
||||
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
|
||||
DefaultCreatedAt func() time.Time
|
||||
// DefaultUpdatedAt holds the default value on creation for the "updated_at" field.
|
||||
DefaultUpdatedAt func() time.Time
|
||||
// UpdateDefaultUpdatedAt holds the default value on update for the "updated_at" field.
|
||||
UpdateDefaultUpdatedAt func() time.Time
|
||||
// TokenValidator is a validator for the "token" field. It is called by the builders before save.
|
||||
TokenValidator func([]byte) error
|
||||
// DefaultUses holds the default value on creation for the "uses" field.
|
||||
DefaultUses int
|
||||
// DefaultExpiresAt holds the default value on creation for the "expires_at" field.
|
||||
DefaultExpiresAt func() time.Time
|
||||
// DefaultID holds the default value on creation for the "id" field.
|
||||
DefaultID func() uuid.UUID
|
||||
)
|
||||
@@ -1,498 +0,0 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package documenttoken
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||
)
|
||||
|
||||
// ID filters vertices based on their ID field.
|
||||
func ID(id uuid.UUID) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldID), id))
|
||||
})
|
||||
}
|
||||
|
||||
// IDEQ applies the EQ predicate on the ID field.
|
||||
func IDEQ(id uuid.UUID) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldID), id))
|
||||
})
|
||||
}
|
||||
|
||||
// IDNEQ applies the NEQ predicate on the ID field.
|
||||
func IDNEQ(id uuid.UUID) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldID), id))
|
||||
})
|
||||
}
|
||||
|
||||
// IDIn applies the In predicate on the ID field.
|
||||
func IDIn(ids ...uuid.UUID) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
v := make([]any, len(ids))
|
||||
for i := range v {
|
||||
v[i] = ids[i]
|
||||
}
|
||||
s.Where(sql.In(s.C(FieldID), v...))
|
||||
})
|
||||
}
|
||||
|
||||
// IDNotIn applies the NotIn predicate on the ID field.
|
||||
func IDNotIn(ids ...uuid.UUID) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
v := make([]any, len(ids))
|
||||
for i := range v {
|
||||
v[i] = ids[i]
|
||||
}
|
||||
s.Where(sql.NotIn(s.C(FieldID), v...))
|
||||
})
|
||||
}
|
||||
|
||||
// IDGT applies the GT predicate on the ID field.
|
||||
func IDGT(id uuid.UUID) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldID), id))
|
||||
})
|
||||
}
|
||||
|
||||
// IDGTE applies the GTE predicate on the ID field.
|
||||
func IDGTE(id uuid.UUID) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldID), id))
|
||||
})
|
||||
}
|
||||
|
||||
// IDLT applies the LT predicate on the ID field.
|
||||
func IDLT(id uuid.UUID) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldID), id))
|
||||
})
|
||||
}
|
||||
|
||||
// IDLTE applies the LTE predicate on the ID field.
|
||||
func IDLTE(id uuid.UUID) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldID), id))
|
||||
})
|
||||
}
|
||||
|
||||
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
|
||||
func CreatedAt(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
|
||||
func UpdatedAt(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// Token applies equality check predicate on the "token" field. It's identical to TokenEQ.
|
||||
func Token(v []byte) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldToken), v))
|
||||
})
|
||||
}
|
||||
|
||||
// Uses applies equality check predicate on the "uses" field. It's identical to UsesEQ.
|
||||
func Uses(v int) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldUses), v))
|
||||
})
|
||||
}
|
||||
|
||||
// ExpiresAt applies equality check predicate on the "expires_at" field. It's identical to ExpiresAtEQ.
|
||||
func ExpiresAt(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldExpiresAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
|
||||
func CreatedAtEQ(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
|
||||
func CreatedAtNEQ(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// CreatedAtIn applies the In predicate on the "created_at" field.
|
||||
func CreatedAtIn(vs ...time.Time) predicate.DocumentToken {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldCreatedAt), v...))
|
||||
})
|
||||
}
|
||||
|
||||
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
|
||||
func CreatedAtNotIn(vs ...time.Time) predicate.DocumentToken {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldCreatedAt), v...))
|
||||
})
|
||||
}
|
||||
|
||||
// CreatedAtGT applies the GT predicate on the "created_at" field.
|
||||
func CreatedAtGT(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
|
||||
func CreatedAtGTE(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// CreatedAtLT applies the LT predicate on the "created_at" field.
|
||||
func CreatedAtLT(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
|
||||
func CreatedAtLTE(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
|
||||
func UpdatedAtEQ(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
|
||||
func UpdatedAtNEQ(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// UpdatedAtIn applies the In predicate on the "updated_at" field.
|
||||
func UpdatedAtIn(vs ...time.Time) predicate.DocumentToken {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldUpdatedAt), v...))
|
||||
})
|
||||
}
|
||||
|
||||
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
|
||||
func UpdatedAtNotIn(vs ...time.Time) predicate.DocumentToken {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldUpdatedAt), v...))
|
||||
})
|
||||
}
|
||||
|
||||
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
|
||||
func UpdatedAtGT(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
|
||||
func UpdatedAtGTE(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
|
||||
func UpdatedAtLT(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
|
||||
func UpdatedAtLTE(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// TokenEQ applies the EQ predicate on the "token" field.
|
||||
func TokenEQ(v []byte) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldToken), v))
|
||||
})
|
||||
}
|
||||
|
||||
// TokenNEQ applies the NEQ predicate on the "token" field.
|
||||
func TokenNEQ(v []byte) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldToken), v))
|
||||
})
|
||||
}
|
||||
|
||||
// TokenIn applies the In predicate on the "token" field.
|
||||
func TokenIn(vs ...[]byte) predicate.DocumentToken {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldToken), v...))
|
||||
})
|
||||
}
|
||||
|
||||
// TokenNotIn applies the NotIn predicate on the "token" field.
|
||||
func TokenNotIn(vs ...[]byte) predicate.DocumentToken {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldToken), v...))
|
||||
})
|
||||
}
|
||||
|
||||
// TokenGT applies the GT predicate on the "token" field.
|
||||
func TokenGT(v []byte) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldToken), v))
|
||||
})
|
||||
}
|
||||
|
||||
// TokenGTE applies the GTE predicate on the "token" field.
|
||||
func TokenGTE(v []byte) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldToken), v))
|
||||
})
|
||||
}
|
||||
|
||||
// TokenLT applies the LT predicate on the "token" field.
|
||||
func TokenLT(v []byte) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldToken), v))
|
||||
})
|
||||
}
|
||||
|
||||
// TokenLTE applies the LTE predicate on the "token" field.
|
||||
func TokenLTE(v []byte) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldToken), v))
|
||||
})
|
||||
}
|
||||
|
||||
// UsesEQ applies the EQ predicate on the "uses" field.
|
||||
func UsesEQ(v int) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldUses), v))
|
||||
})
|
||||
}
|
||||
|
||||
// UsesNEQ applies the NEQ predicate on the "uses" field.
|
||||
func UsesNEQ(v int) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldUses), v))
|
||||
})
|
||||
}
|
||||
|
||||
// UsesIn applies the In predicate on the "uses" field.
|
||||
func UsesIn(vs ...int) predicate.DocumentToken {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldUses), v...))
|
||||
})
|
||||
}
|
||||
|
||||
// UsesNotIn applies the NotIn predicate on the "uses" field.
|
||||
func UsesNotIn(vs ...int) predicate.DocumentToken {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldUses), v...))
|
||||
})
|
||||
}
|
||||
|
||||
// UsesGT applies the GT predicate on the "uses" field.
|
||||
func UsesGT(v int) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldUses), v))
|
||||
})
|
||||
}
|
||||
|
||||
// UsesGTE applies the GTE predicate on the "uses" field.
|
||||
func UsesGTE(v int) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldUses), v))
|
||||
})
|
||||
}
|
||||
|
||||
// UsesLT applies the LT predicate on the "uses" field.
|
||||
func UsesLT(v int) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldUses), v))
|
||||
})
|
||||
}
|
||||
|
||||
// UsesLTE applies the LTE predicate on the "uses" field.
|
||||
func UsesLTE(v int) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldUses), v))
|
||||
})
|
||||
}
|
||||
|
||||
// ExpiresAtEQ applies the EQ predicate on the "expires_at" field.
|
||||
func ExpiresAtEQ(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldExpiresAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// ExpiresAtNEQ applies the NEQ predicate on the "expires_at" field.
|
||||
func ExpiresAtNEQ(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldExpiresAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// ExpiresAtIn applies the In predicate on the "expires_at" field.
|
||||
func ExpiresAtIn(vs ...time.Time) predicate.DocumentToken {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldExpiresAt), v...))
|
||||
})
|
||||
}
|
||||
|
||||
// ExpiresAtNotIn applies the NotIn predicate on the "expires_at" field.
|
||||
func ExpiresAtNotIn(vs ...time.Time) predicate.DocumentToken {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldExpiresAt), v...))
|
||||
})
|
||||
}
|
||||
|
||||
// ExpiresAtGT applies the GT predicate on the "expires_at" field.
|
||||
func ExpiresAtGT(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldExpiresAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// ExpiresAtGTE applies the GTE predicate on the "expires_at" field.
|
||||
func ExpiresAtGTE(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldExpiresAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// ExpiresAtLT applies the LT predicate on the "expires_at" field.
|
||||
func ExpiresAtLT(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldExpiresAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// ExpiresAtLTE applies the LTE predicate on the "expires_at" field.
|
||||
func ExpiresAtLTE(v time.Time) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldExpiresAt), v))
|
||||
})
|
||||
}
|
||||
|
||||
// HasDocument applies the HasEdge predicate on the "document" edge.
|
||||
func HasDocument() predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(DocumentTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, DocumentTable, DocumentColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasDocumentWith applies the HasEdge predicate on the "document" edge with a given conditions (other predicates).
|
||||
func HasDocumentWith(preds ...predicate.Document) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(DocumentInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, DocumentTable, DocumentColumn),
|
||||
)
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// And groups predicates with the AND operator between them.
|
||||
func And(predicates ...predicate.DocumentToken) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s1 := s.Clone().SetP(nil)
|
||||
for _, p := range predicates {
|
||||
p(s1)
|
||||
}
|
||||
s.Where(s1.P())
|
||||
})
|
||||
}
|
||||
|
||||
// Or groups predicates with the OR operator between them.
|
||||
func Or(predicates ...predicate.DocumentToken) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
s1 := s.Clone().SetP(nil)
|
||||
for i, p := range predicates {
|
||||
if i > 0 {
|
||||
s1.Or()
|
||||
}
|
||||
p(s1)
|
||||
}
|
||||
s.Where(s1.P())
|
||||
})
|
||||
}
|
||||
|
||||
// Not applies the not operator on the given predicate.
|
||||
func Not(p predicate.DocumentToken) predicate.DocumentToken {
|
||||
return predicate.DocumentToken(func(s *sql.Selector) {
|
||||
p(s.Not())
|
||||
})
|
||||
}
|
||||
@@ -1,418 +0,0 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/document"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/documenttoken"
|
||||
)
|
||||
|
||||
// DocumentTokenCreate is the builder for creating a DocumentToken entity.
|
||||
type DocumentTokenCreate struct {
|
||||
config
|
||||
mutation *DocumentTokenMutation
|
||||
hooks []Hook
|
||||
}
|
||||
|
||||
// SetCreatedAt sets the "created_at" field.
|
||||
func (dtc *DocumentTokenCreate) SetCreatedAt(t time.Time) *DocumentTokenCreate {
|
||||
dtc.mutation.SetCreatedAt(t)
|
||||
return dtc
|
||||
}
|
||||
|
||||
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
|
||||
func (dtc *DocumentTokenCreate) SetNillableCreatedAt(t *time.Time) *DocumentTokenCreate {
|
||||
if t != nil {
|
||||
dtc.SetCreatedAt(*t)
|
||||
}
|
||||
return dtc
|
||||
}
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (dtc *DocumentTokenCreate) SetUpdatedAt(t time.Time) *DocumentTokenCreate {
|
||||
dtc.mutation.SetUpdatedAt(t)
|
||||
return dtc
|
||||
}
|
||||
|
||||
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
|
||||
func (dtc *DocumentTokenCreate) SetNillableUpdatedAt(t *time.Time) *DocumentTokenCreate {
|
||||
if t != nil {
|
||||
dtc.SetUpdatedAt(*t)
|
||||
}
|
||||
return dtc
|
||||
}
|
||||
|
||||
// SetToken sets the "token" field.
|
||||
func (dtc *DocumentTokenCreate) SetToken(b []byte) *DocumentTokenCreate {
|
||||
dtc.mutation.SetToken(b)
|
||||
return dtc
|
||||
}
|
||||
|
||||
// SetUses sets the "uses" field.
|
||||
func (dtc *DocumentTokenCreate) SetUses(i int) *DocumentTokenCreate {
|
||||
dtc.mutation.SetUses(i)
|
||||
return dtc
|
||||
}
|
||||
|
||||
// SetNillableUses sets the "uses" field if the given value is not nil.
|
||||
func (dtc *DocumentTokenCreate) SetNillableUses(i *int) *DocumentTokenCreate {
|
||||
if i != nil {
|
||||
dtc.SetUses(*i)
|
||||
}
|
||||
return dtc
|
||||
}
|
||||
|
||||
// SetExpiresAt sets the "expires_at" field.
|
||||
func (dtc *DocumentTokenCreate) SetExpiresAt(t time.Time) *DocumentTokenCreate {
|
||||
dtc.mutation.SetExpiresAt(t)
|
||||
return dtc
|
||||
}
|
||||
|
||||
// SetNillableExpiresAt sets the "expires_at" field if the given value is not nil.
|
||||
func (dtc *DocumentTokenCreate) SetNillableExpiresAt(t *time.Time) *DocumentTokenCreate {
|
||||
if t != nil {
|
||||
dtc.SetExpiresAt(*t)
|
||||
}
|
||||
return dtc
|
||||
}
|
||||
|
||||
// SetID sets the "id" field.
|
||||
func (dtc *DocumentTokenCreate) SetID(u uuid.UUID) *DocumentTokenCreate {
|
||||
dtc.mutation.SetID(u)
|
||||
return dtc
|
||||
}
|
||||
|
||||
// SetNillableID sets the "id" field if the given value is not nil.
|
||||
func (dtc *DocumentTokenCreate) SetNillableID(u *uuid.UUID) *DocumentTokenCreate {
|
||||
if u != nil {
|
||||
dtc.SetID(*u)
|
||||
}
|
||||
return dtc
|
||||
}
|
||||
|
||||
// SetDocumentID sets the "document" edge to the Document entity by ID.
|
||||
func (dtc *DocumentTokenCreate) SetDocumentID(id uuid.UUID) *DocumentTokenCreate {
|
||||
dtc.mutation.SetDocumentID(id)
|
||||
return dtc
|
||||
}
|
||||
|
||||
// SetNillableDocumentID sets the "document" edge to the Document entity by ID if the given value is not nil.
|
||||
func (dtc *DocumentTokenCreate) SetNillableDocumentID(id *uuid.UUID) *DocumentTokenCreate {
|
||||
if id != nil {
|
||||
dtc = dtc.SetDocumentID(*id)
|
||||
}
|
||||
return dtc
|
||||
}
|
||||
|
||||
// SetDocument sets the "document" edge to the Document entity.
|
||||
func (dtc *DocumentTokenCreate) SetDocument(d *Document) *DocumentTokenCreate {
|
||||
return dtc.SetDocumentID(d.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the DocumentTokenMutation object of the builder.
|
||||
func (dtc *DocumentTokenCreate) Mutation() *DocumentTokenMutation {
|
||||
return dtc.mutation
|
||||
}
|
||||
|
||||
// Save creates the DocumentToken in the database.
|
||||
func (dtc *DocumentTokenCreate) Save(ctx context.Context) (*DocumentToken, error) {
|
||||
var (
|
||||
err error
|
||||
node *DocumentToken
|
||||
)
|
||||
dtc.defaults()
|
||||
if len(dtc.hooks) == 0 {
|
||||
if err = dtc.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node, err = dtc.sqlSave(ctx)
|
||||
} else {
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*DocumentTokenMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
if err = dtc.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dtc.mutation = mutation
|
||||
if node, err = dtc.sqlSave(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mutation.id = &node.ID
|
||||
mutation.done = true
|
||||
return node, err
|
||||
})
|
||||
for i := len(dtc.hooks) - 1; i >= 0; i-- {
|
||||
if dtc.hooks[i] == nil {
|
||||
return nil, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = dtc.hooks[i](mut)
|
||||
}
|
||||
v, err := mut.Mutate(ctx, dtc.mutation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nv, ok := v.(*DocumentToken)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected node type %T returned from DocumentTokenMutation", v)
|
||||
}
|
||||
node = nv
|
||||
}
|
||||
return node, err
|
||||
}
|
||||
|
||||
// SaveX calls Save and panics if Save returns an error.
|
||||
func (dtc *DocumentTokenCreate) SaveX(ctx context.Context) *DocumentToken {
|
||||
v, err := dtc.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (dtc *DocumentTokenCreate) Exec(ctx context.Context) error {
|
||||
_, err := dtc.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (dtc *DocumentTokenCreate) ExecX(ctx context.Context) {
|
||||
if err := dtc.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (dtc *DocumentTokenCreate) defaults() {
|
||||
if _, ok := dtc.mutation.CreatedAt(); !ok {
|
||||
v := documenttoken.DefaultCreatedAt()
|
||||
dtc.mutation.SetCreatedAt(v)
|
||||
}
|
||||
if _, ok := dtc.mutation.UpdatedAt(); !ok {
|
||||
v := documenttoken.DefaultUpdatedAt()
|
||||
dtc.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
if _, ok := dtc.mutation.Uses(); !ok {
|
||||
v := documenttoken.DefaultUses
|
||||
dtc.mutation.SetUses(v)
|
||||
}
|
||||
if _, ok := dtc.mutation.ExpiresAt(); !ok {
|
||||
v := documenttoken.DefaultExpiresAt()
|
||||
dtc.mutation.SetExpiresAt(v)
|
||||
}
|
||||
if _, ok := dtc.mutation.ID(); !ok {
|
||||
v := documenttoken.DefaultID()
|
||||
dtc.mutation.SetID(v)
|
||||
}
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (dtc *DocumentTokenCreate) check() error {
|
||||
if _, ok := dtc.mutation.CreatedAt(); !ok {
|
||||
return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "DocumentToken.created_at"`)}
|
||||
}
|
||||
if _, ok := dtc.mutation.UpdatedAt(); !ok {
|
||||
return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "DocumentToken.updated_at"`)}
|
||||
}
|
||||
if _, ok := dtc.mutation.Token(); !ok {
|
||||
return &ValidationError{Name: "token", err: errors.New(`ent: missing required field "DocumentToken.token"`)}
|
||||
}
|
||||
if v, ok := dtc.mutation.Token(); ok {
|
||||
if err := documenttoken.TokenValidator(v); err != nil {
|
||||
return &ValidationError{Name: "token", err: fmt.Errorf(`ent: validator failed for field "DocumentToken.token": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := dtc.mutation.Uses(); !ok {
|
||||
return &ValidationError{Name: "uses", err: errors.New(`ent: missing required field "DocumentToken.uses"`)}
|
||||
}
|
||||
if _, ok := dtc.mutation.ExpiresAt(); !ok {
|
||||
return &ValidationError{Name: "expires_at", err: errors.New(`ent: missing required field "DocumentToken.expires_at"`)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dtc *DocumentTokenCreate) sqlSave(ctx context.Context) (*DocumentToken, error) {
|
||||
_node, _spec := dtc.createSpec()
|
||||
if err := sqlgraph.CreateNode(ctx, dtc.driver, _spec); err != nil {
|
||||
if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
if _spec.ID.Value != nil {
|
||||
if id, ok := _spec.ID.Value.(*uuid.UUID); ok {
|
||||
_node.ID = *id
|
||||
} else if err := _node.ID.Scan(_spec.ID.Value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return _node, nil
|
||||
}
|
||||
|
||||
func (dtc *DocumentTokenCreate) createSpec() (*DocumentToken, *sqlgraph.CreateSpec) {
|
||||
var (
|
||||
_node = &DocumentToken{config: dtc.config}
|
||||
_spec = &sqlgraph.CreateSpec{
|
||||
Table: documenttoken.Table,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: documenttoken.FieldID,
|
||||
},
|
||||
}
|
||||
)
|
||||
if id, ok := dtc.mutation.ID(); ok {
|
||||
_node.ID = id
|
||||
_spec.ID.Value = &id
|
||||
}
|
||||
if value, ok := dtc.mutation.CreatedAt(); ok {
|
||||
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: documenttoken.FieldCreatedAt,
|
||||
})
|
||||
_node.CreatedAt = value
|
||||
}
|
||||
if value, ok := dtc.mutation.UpdatedAt(); ok {
|
||||
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: documenttoken.FieldUpdatedAt,
|
||||
})
|
||||
_node.UpdatedAt = value
|
||||
}
|
||||
if value, ok := dtc.mutation.Token(); ok {
|
||||
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeBytes,
|
||||
Value: value,
|
||||
Column: documenttoken.FieldToken,
|
||||
})
|
||||
_node.Token = value
|
||||
}
|
||||
if value, ok := dtc.mutation.Uses(); ok {
|
||||
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeInt,
|
||||
Value: value,
|
||||
Column: documenttoken.FieldUses,
|
||||
})
|
||||
_node.Uses = value
|
||||
}
|
||||
if value, ok := dtc.mutation.ExpiresAt(); ok {
|
||||
_spec.Fields = append(_spec.Fields, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: documenttoken.FieldExpiresAt,
|
||||
})
|
||||
_node.ExpiresAt = value
|
||||
}
|
||||
if nodes := dtc.mutation.DocumentIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: documenttoken.DocumentTable,
|
||||
Columns: []string{documenttoken.DocumentColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: document.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_node.document_document_tokens = &nodes[0]
|
||||
_spec.Edges = append(_spec.Edges, edge)
|
||||
}
|
||||
return _node, _spec
|
||||
}
|
||||
|
||||
// DocumentTokenCreateBulk is the builder for creating many DocumentToken entities in bulk.
|
||||
type DocumentTokenCreateBulk struct {
|
||||
config
|
||||
builders []*DocumentTokenCreate
|
||||
}
|
||||
|
||||
// Save creates the DocumentToken entities in the database.
|
||||
func (dtcb *DocumentTokenCreateBulk) Save(ctx context.Context) ([]*DocumentToken, error) {
|
||||
specs := make([]*sqlgraph.CreateSpec, len(dtcb.builders))
|
||||
nodes := make([]*DocumentToken, len(dtcb.builders))
|
||||
mutators := make([]Mutator, len(dtcb.builders))
|
||||
for i := range dtcb.builders {
|
||||
func(i int, root context.Context) {
|
||||
builder := dtcb.builders[i]
|
||||
builder.defaults()
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*DocumentTokenMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
if err := builder.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
builder.mutation = mutation
|
||||
nodes[i], specs[i] = builder.createSpec()
|
||||
var err error
|
||||
if i < len(mutators)-1 {
|
||||
_, err = mutators[i+1].Mutate(root, dtcb.builders[i+1].mutation)
|
||||
} else {
|
||||
spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
|
||||
// Invoke the actual operation on the latest mutation in the chain.
|
||||
if err = sqlgraph.BatchCreate(ctx, dtcb.driver, spec); err != nil {
|
||||
if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mutation.id = &nodes[i].ID
|
||||
mutation.done = true
|
||||
return nodes[i], nil
|
||||
})
|
||||
for i := len(builder.hooks) - 1; i >= 0; i-- {
|
||||
mut = builder.hooks[i](mut)
|
||||
}
|
||||
mutators[i] = mut
|
||||
}(i, ctx)
|
||||
}
|
||||
if len(mutators) > 0 {
|
||||
if _, err := mutators[0].Mutate(ctx, dtcb.builders[0].mutation); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (dtcb *DocumentTokenCreateBulk) SaveX(ctx context.Context) []*DocumentToken {
|
||||
v, err := dtcb.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (dtcb *DocumentTokenCreateBulk) Exec(ctx context.Context) error {
|
||||
_, err := dtcb.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (dtcb *DocumentTokenCreateBulk) ExecX(ctx context.Context) {
|
||||
if err := dtcb.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/documenttoken"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||
)
|
||||
|
||||
// DocumentTokenDelete is the builder for deleting a DocumentToken entity.
|
||||
type DocumentTokenDelete struct {
|
||||
config
|
||||
hooks []Hook
|
||||
mutation *DocumentTokenMutation
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the DocumentTokenDelete builder.
|
||||
func (dtd *DocumentTokenDelete) Where(ps ...predicate.DocumentToken) *DocumentTokenDelete {
|
||||
dtd.mutation.Where(ps...)
|
||||
return dtd
|
||||
}
|
||||
|
||||
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||
func (dtd *DocumentTokenDelete) Exec(ctx context.Context) (int, error) {
|
||||
var (
|
||||
err error
|
||||
affected int
|
||||
)
|
||||
if len(dtd.hooks) == 0 {
|
||||
affected, err = dtd.sqlExec(ctx)
|
||||
} else {
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*DocumentTokenMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
dtd.mutation = mutation
|
||||
affected, err = dtd.sqlExec(ctx)
|
||||
mutation.done = true
|
||||
return affected, err
|
||||
})
|
||||
for i := len(dtd.hooks) - 1; i >= 0; i-- {
|
||||
if dtd.hooks[i] == nil {
|
||||
return 0, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = dtd.hooks[i](mut)
|
||||
}
|
||||
if _, err := mut.Mutate(ctx, dtd.mutation); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
return affected, err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (dtd *DocumentTokenDelete) ExecX(ctx context.Context) int {
|
||||
n, err := dtd.Exec(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (dtd *DocumentTokenDelete) sqlExec(ctx context.Context) (int, error) {
|
||||
_spec := &sqlgraph.DeleteSpec{
|
||||
Node: &sqlgraph.NodeSpec{
|
||||
Table: documenttoken.Table,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: documenttoken.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
if ps := dtd.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
affected, err := sqlgraph.DeleteNodes(ctx, dtd.driver, _spec)
|
||||
if err != nil && sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return affected, err
|
||||
}
|
||||
|
||||
// DocumentTokenDeleteOne is the builder for deleting a single DocumentToken entity.
|
||||
type DocumentTokenDeleteOne struct {
|
||||
dtd *DocumentTokenDelete
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (dtdo *DocumentTokenDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := dtdo.dtd.Exec(ctx)
|
||||
switch {
|
||||
case err != nil:
|
||||
return err
|
||||
case n == 0:
|
||||
return &NotFoundError{documenttoken.Label}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (dtdo *DocumentTokenDeleteOne) ExecX(ctx context.Context) {
|
||||
dtdo.dtd.ExecX(ctx)
|
||||
}
|
||||
@@ -1,614 +0,0 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/document"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/documenttoken"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||
)
|
||||
|
||||
// DocumentTokenQuery is the builder for querying DocumentToken entities.
|
||||
type DocumentTokenQuery struct {
|
||||
config
|
||||
limit *int
|
||||
offset *int
|
||||
unique *bool
|
||||
order []OrderFunc
|
||||
fields []string
|
||||
predicates []predicate.DocumentToken
|
||||
withDocument *DocumentQuery
|
||||
withFKs bool
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the DocumentTokenQuery builder.
|
||||
func (dtq *DocumentTokenQuery) Where(ps ...predicate.DocumentToken) *DocumentTokenQuery {
|
||||
dtq.predicates = append(dtq.predicates, ps...)
|
||||
return dtq
|
||||
}
|
||||
|
||||
// Limit adds a limit step to the query.
|
||||
func (dtq *DocumentTokenQuery) Limit(limit int) *DocumentTokenQuery {
|
||||
dtq.limit = &limit
|
||||
return dtq
|
||||
}
|
||||
|
||||
// Offset adds an offset step to the query.
|
||||
func (dtq *DocumentTokenQuery) Offset(offset int) *DocumentTokenQuery {
|
||||
dtq.offset = &offset
|
||||
return dtq
|
||||
}
|
||||
|
||||
// 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 (dtq *DocumentTokenQuery) Unique(unique bool) *DocumentTokenQuery {
|
||||
dtq.unique = &unique
|
||||
return dtq
|
||||
}
|
||||
|
||||
// Order adds an order step to the query.
|
||||
func (dtq *DocumentTokenQuery) Order(o ...OrderFunc) *DocumentTokenQuery {
|
||||
dtq.order = append(dtq.order, o...)
|
||||
return dtq
|
||||
}
|
||||
|
||||
// QueryDocument chains the current query on the "document" edge.
|
||||
func (dtq *DocumentTokenQuery) QueryDocument() *DocumentQuery {
|
||||
query := &DocumentQuery{config: dtq.config}
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := dtq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector := dtq.sqlQuery(ctx)
|
||||
if err := selector.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(documenttoken.Table, documenttoken.FieldID, selector),
|
||||
sqlgraph.To(document.Table, document.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, documenttoken.DocumentTable, documenttoken.DocumentColumn),
|
||||
)
|
||||
fromU = sqlgraph.SetNeighbors(dtq.driver.Dialect(), step)
|
||||
return fromU, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// First returns the first DocumentToken entity from the query.
|
||||
// Returns a *NotFoundError when no DocumentToken was found.
|
||||
func (dtq *DocumentTokenQuery) First(ctx context.Context) (*DocumentToken, error) {
|
||||
nodes, err := dtq.Limit(1).All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nil, &NotFoundError{documenttoken.Label}
|
||||
}
|
||||
return nodes[0], nil
|
||||
}
|
||||
|
||||
// FirstX is like First, but panics if an error occurs.
|
||||
func (dtq *DocumentTokenQuery) FirstX(ctx context.Context) *DocumentToken {
|
||||
node, err := dtq.First(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// FirstID returns the first DocumentToken ID from the query.
|
||||
// Returns a *NotFoundError when no DocumentToken ID was found.
|
||||
func (dtq *DocumentTokenQuery) FirstID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = dtq.Limit(1).IDs(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
err = &NotFoundError{documenttoken.Label}
|
||||
return
|
||||
}
|
||||
return ids[0], nil
|
||||
}
|
||||
|
||||
// FirstIDX is like FirstID, but panics if an error occurs.
|
||||
func (dtq *DocumentTokenQuery) FirstIDX(ctx context.Context) uuid.UUID {
|
||||
id, err := dtq.FirstID(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// Only returns a single DocumentToken entity found by the query, ensuring it only returns one.
|
||||
// Returns a *NotSingularError when more than one DocumentToken entity is found.
|
||||
// Returns a *NotFoundError when no DocumentToken entities are found.
|
||||
func (dtq *DocumentTokenQuery) Only(ctx context.Context) (*DocumentToken, error) {
|
||||
nodes, err := dtq.Limit(2).All(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch len(nodes) {
|
||||
case 1:
|
||||
return nodes[0], nil
|
||||
case 0:
|
||||
return nil, &NotFoundError{documenttoken.Label}
|
||||
default:
|
||||
return nil, &NotSingularError{documenttoken.Label}
|
||||
}
|
||||
}
|
||||
|
||||
// OnlyX is like Only, but panics if an error occurs.
|
||||
func (dtq *DocumentTokenQuery) OnlyX(ctx context.Context) *DocumentToken {
|
||||
node, err := dtq.Only(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// OnlyID is like Only, but returns the only DocumentToken ID in the query.
|
||||
// Returns a *NotSingularError when more than one DocumentToken ID is found.
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (dtq *DocumentTokenQuery) OnlyID(ctx context.Context) (id uuid.UUID, err error) {
|
||||
var ids []uuid.UUID
|
||||
if ids, err = dtq.Limit(2).IDs(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
case 1:
|
||||
id = ids[0]
|
||||
case 0:
|
||||
err = &NotFoundError{documenttoken.Label}
|
||||
default:
|
||||
err = &NotSingularError{documenttoken.Label}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// OnlyIDX is like OnlyID, but panics if an error occurs.
|
||||
func (dtq *DocumentTokenQuery) OnlyIDX(ctx context.Context) uuid.UUID {
|
||||
id, err := dtq.OnlyID(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// All executes the query and returns a list of DocumentTokens.
|
||||
func (dtq *DocumentTokenQuery) All(ctx context.Context) ([]*DocumentToken, error) {
|
||||
if err := dtq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dtq.sqlAll(ctx)
|
||||
}
|
||||
|
||||
// AllX is like All, but panics if an error occurs.
|
||||
func (dtq *DocumentTokenQuery) AllX(ctx context.Context) []*DocumentToken {
|
||||
nodes, err := dtq.All(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
// IDs executes the query and returns a list of DocumentToken IDs.
|
||||
func (dtq *DocumentTokenQuery) IDs(ctx context.Context) ([]uuid.UUID, error) {
|
||||
var ids []uuid.UUID
|
||||
if err := dtq.Select(documenttoken.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
// IDsX is like IDs, but panics if an error occurs.
|
||||
func (dtq *DocumentTokenQuery) IDsX(ctx context.Context) []uuid.UUID {
|
||||
ids, err := dtq.IDs(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (dtq *DocumentTokenQuery) Count(ctx context.Context) (int, error) {
|
||||
if err := dtq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return dtq.sqlCount(ctx)
|
||||
}
|
||||
|
||||
// CountX is like Count, but panics if an error occurs.
|
||||
func (dtq *DocumentTokenQuery) CountX(ctx context.Context) int {
|
||||
count, err := dtq.Count(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (dtq *DocumentTokenQuery) Exist(ctx context.Context) (bool, error) {
|
||||
if err := dtq.prepareQuery(ctx); err != nil {
|
||||
return false, err
|
||||
}
|
||||
return dtq.sqlExist(ctx)
|
||||
}
|
||||
|
||||
// ExistX is like Exist, but panics if an error occurs.
|
||||
func (dtq *DocumentTokenQuery) ExistX(ctx context.Context) bool {
|
||||
exist, err := dtq.Exist(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return exist
|
||||
}
|
||||
|
||||
// Clone returns a duplicate of the DocumentTokenQuery builder, including all associated steps. It can be
|
||||
// used to prepare common query builders and use them differently after the clone is made.
|
||||
func (dtq *DocumentTokenQuery) Clone() *DocumentTokenQuery {
|
||||
if dtq == nil {
|
||||
return nil
|
||||
}
|
||||
return &DocumentTokenQuery{
|
||||
config: dtq.config,
|
||||
limit: dtq.limit,
|
||||
offset: dtq.offset,
|
||||
order: append([]OrderFunc{}, dtq.order...),
|
||||
predicates: append([]predicate.DocumentToken{}, dtq.predicates...),
|
||||
withDocument: dtq.withDocument.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: dtq.sql.Clone(),
|
||||
path: dtq.path,
|
||||
unique: dtq.unique,
|
||||
}
|
||||
}
|
||||
|
||||
// WithDocument tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "document" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (dtq *DocumentTokenQuery) WithDocument(opts ...func(*DocumentQuery)) *DocumentTokenQuery {
|
||||
query := &DocumentQuery{config: dtq.config}
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
dtq.withDocument = query
|
||||
return dtq
|
||||
}
|
||||
|
||||
// GroupBy is used to group vertices by one or more fields/columns.
|
||||
// It is often used with aggregate functions, like: count, max, mean, min, sum.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// var v []struct {
|
||||
// CreatedAt time.Time `json:"created_at,omitempty"`
|
||||
// Count int `json:"count,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.DocumentToken.Query().
|
||||
// GroupBy(documenttoken.FieldCreatedAt).
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (dtq *DocumentTokenQuery) GroupBy(field string, fields ...string) *DocumentTokenGroupBy {
|
||||
grbuild := &DocumentTokenGroupBy{config: dtq.config}
|
||||
grbuild.fields = append([]string{field}, fields...)
|
||||
grbuild.path = func(ctx context.Context) (prev *sql.Selector, err error) {
|
||||
if err := dtq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dtq.sqlQuery(ctx), nil
|
||||
}
|
||||
grbuild.label = documenttoken.Label
|
||||
grbuild.flds, grbuild.scan = &grbuild.fields, grbuild.Scan
|
||||
return grbuild
|
||||
}
|
||||
|
||||
// Select allows the selection one or more fields/columns for the given query,
|
||||
// instead of selecting all fields in the entity.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// var v []struct {
|
||||
// CreatedAt time.Time `json:"created_at,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.DocumentToken.Query().
|
||||
// Select(documenttoken.FieldCreatedAt).
|
||||
// Scan(ctx, &v)
|
||||
func (dtq *DocumentTokenQuery) Select(fields ...string) *DocumentTokenSelect {
|
||||
dtq.fields = append(dtq.fields, fields...)
|
||||
selbuild := &DocumentTokenSelect{DocumentTokenQuery: dtq}
|
||||
selbuild.label = documenttoken.Label
|
||||
selbuild.flds, selbuild.scan = &dtq.fields, selbuild.Scan
|
||||
return selbuild
|
||||
}
|
||||
|
||||
func (dtq *DocumentTokenQuery) prepareQuery(ctx context.Context) error {
|
||||
for _, f := range dtq.fields {
|
||||
if !documenttoken.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
}
|
||||
if dtq.path != nil {
|
||||
prev, err := dtq.path(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dtq.sql = prev
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dtq *DocumentTokenQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*DocumentToken, error) {
|
||||
var (
|
||||
nodes = []*DocumentToken{}
|
||||
withFKs = dtq.withFKs
|
||||
_spec = dtq.querySpec()
|
||||
loadedTypes = [1]bool{
|
||||
dtq.withDocument != nil,
|
||||
}
|
||||
)
|
||||
if dtq.withDocument != nil {
|
||||
withFKs = true
|
||||
}
|
||||
if withFKs {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, documenttoken.ForeignKeys...)
|
||||
}
|
||||
_spec.ScanValues = func(columns []string) ([]any, error) {
|
||||
return (*DocumentToken).scanValues(nil, columns)
|
||||
}
|
||||
_spec.Assign = func(columns []string, values []any) error {
|
||||
node := &DocumentToken{config: dtq.config}
|
||||
nodes = append(nodes, node)
|
||||
node.Edges.loadedTypes = loadedTypes
|
||||
return node.assignValues(columns, values)
|
||||
}
|
||||
for i := range hooks {
|
||||
hooks[i](ctx, _spec)
|
||||
}
|
||||
if err := sqlgraph.QueryNodes(ctx, dtq.driver, _spec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nodes, nil
|
||||
}
|
||||
if query := dtq.withDocument; query != nil {
|
||||
if err := dtq.loadDocument(ctx, query, nodes, nil,
|
||||
func(n *DocumentToken, e *Document) { n.Edges.Document = e }); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
func (dtq *DocumentTokenQuery) loadDocument(ctx context.Context, query *DocumentQuery, nodes []*DocumentToken, init func(*DocumentToken), assign func(*DocumentToken, *Document)) error {
|
||||
ids := make([]uuid.UUID, 0, len(nodes))
|
||||
nodeids := make(map[uuid.UUID][]*DocumentToken)
|
||||
for i := range nodes {
|
||||
if nodes[i].document_document_tokens == nil {
|
||||
continue
|
||||
}
|
||||
fk := *nodes[i].document_document_tokens
|
||||
if _, ok := nodeids[fk]; !ok {
|
||||
ids = append(ids, fk)
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
query.Where(document.IDIn(ids...))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, n := range neighbors {
|
||||
nodes, ok := nodeids[n.ID]
|
||||
if !ok {
|
||||
return fmt.Errorf(`unexpected foreign-key "document_document_tokens" returned %v`, n.ID)
|
||||
}
|
||||
for i := range nodes {
|
||||
assign(nodes[i], n)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dtq *DocumentTokenQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := dtq.querySpec()
|
||||
_spec.Node.Columns = dtq.fields
|
||||
if len(dtq.fields) > 0 {
|
||||
_spec.Unique = dtq.unique != nil && *dtq.unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, dtq.driver, _spec)
|
||||
}
|
||||
|
||||
func (dtq *DocumentTokenQuery) sqlExist(ctx context.Context) (bool, error) {
|
||||
switch _, err := dtq.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
case err != nil:
|
||||
return false, fmt.Errorf("ent: check existence: %w", err)
|
||||
default:
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (dtq *DocumentTokenQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
_spec := &sqlgraph.QuerySpec{
|
||||
Node: &sqlgraph.NodeSpec{
|
||||
Table: documenttoken.Table,
|
||||
Columns: documenttoken.Columns,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: documenttoken.FieldID,
|
||||
},
|
||||
},
|
||||
From: dtq.sql,
|
||||
Unique: true,
|
||||
}
|
||||
if unique := dtq.unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
}
|
||||
if fields := dtq.fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, documenttoken.FieldID)
|
||||
for i := range fields {
|
||||
if fields[i] != documenttoken.FieldID {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
if ps := dtq.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := dtq.limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := dtq.offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := dtq.order; len(ps) > 0 {
|
||||
_spec.Order = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
return _spec
|
||||
}
|
||||
|
||||
func (dtq *DocumentTokenQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(dtq.driver.Dialect())
|
||||
t1 := builder.Table(documenttoken.Table)
|
||||
columns := dtq.fields
|
||||
if len(columns) == 0 {
|
||||
columns = documenttoken.Columns
|
||||
}
|
||||
selector := builder.Select(t1.Columns(columns...)...).From(t1)
|
||||
if dtq.sql != nil {
|
||||
selector = dtq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if dtq.unique != nil && *dtq.unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, p := range dtq.predicates {
|
||||
p(selector)
|
||||
}
|
||||
for _, p := range dtq.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := dtq.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 := dtq.limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
}
|
||||
|
||||
// DocumentTokenGroupBy is the group-by builder for DocumentToken entities.
|
||||
type DocumentTokenGroupBy struct {
|
||||
config
|
||||
selector
|
||||
fields []string
|
||||
fns []AggregateFunc
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the group-by query.
|
||||
func (dtgb *DocumentTokenGroupBy) Aggregate(fns ...AggregateFunc) *DocumentTokenGroupBy {
|
||||
dtgb.fns = append(dtgb.fns, fns...)
|
||||
return dtgb
|
||||
}
|
||||
|
||||
// Scan applies the group-by query and scans the result into the given value.
|
||||
func (dtgb *DocumentTokenGroupBy) Scan(ctx context.Context, v any) error {
|
||||
query, err := dtgb.path(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dtgb.sql = query
|
||||
return dtgb.sqlScan(ctx, v)
|
||||
}
|
||||
|
||||
func (dtgb *DocumentTokenGroupBy) sqlScan(ctx context.Context, v any) error {
|
||||
for _, f := range dtgb.fields {
|
||||
if !documenttoken.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("invalid field %q for group-by", f)}
|
||||
}
|
||||
}
|
||||
selector := dtgb.sqlQuery()
|
||||
if err := selector.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := dtgb.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
func (dtgb *DocumentTokenGroupBy) sqlQuery() *sql.Selector {
|
||||
selector := dtgb.sql.Select()
|
||||
aggregation := make([]string, 0, len(dtgb.fns))
|
||||
for _, fn := range dtgb.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
// If no columns were selected in a custom aggregation function, the default
|
||||
// selection is the fields used for "group-by", and the aggregation functions.
|
||||
if len(selector.SelectedColumns()) == 0 {
|
||||
columns := make([]string, 0, len(dtgb.fields)+len(dtgb.fns))
|
||||
for _, f := range dtgb.fields {
|
||||
columns = append(columns, selector.C(f))
|
||||
}
|
||||
columns = append(columns, aggregation...)
|
||||
selector.Select(columns...)
|
||||
}
|
||||
return selector.GroupBy(selector.Columns(dtgb.fields...)...)
|
||||
}
|
||||
|
||||
// DocumentTokenSelect is the builder for selecting fields of DocumentToken entities.
|
||||
type DocumentTokenSelect struct {
|
||||
*DocumentTokenQuery
|
||||
selector
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (dts *DocumentTokenSelect) Scan(ctx context.Context, v any) error {
|
||||
if err := dts.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
dts.sql = dts.DocumentTokenQuery.sqlQuery(ctx)
|
||||
return dts.sqlScan(ctx, v)
|
||||
}
|
||||
|
||||
func (dts *DocumentTokenSelect) sqlScan(ctx context.Context, v any) error {
|
||||
rows := &sql.Rows{}
|
||||
query, args := dts.sql.Query()
|
||||
if err := dts.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
@@ -1,582 +0,0 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/google/uuid"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/document"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/documenttoken"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/predicate"
|
||||
)
|
||||
|
||||
// DocumentTokenUpdate is the builder for updating DocumentToken entities.
|
||||
type DocumentTokenUpdate struct {
|
||||
config
|
||||
hooks []Hook
|
||||
mutation *DocumentTokenMutation
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the DocumentTokenUpdate builder.
|
||||
func (dtu *DocumentTokenUpdate) Where(ps ...predicate.DocumentToken) *DocumentTokenUpdate {
|
||||
dtu.mutation.Where(ps...)
|
||||
return dtu
|
||||
}
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (dtu *DocumentTokenUpdate) SetUpdatedAt(t time.Time) *DocumentTokenUpdate {
|
||||
dtu.mutation.SetUpdatedAt(t)
|
||||
return dtu
|
||||
}
|
||||
|
||||
// SetToken sets the "token" field.
|
||||
func (dtu *DocumentTokenUpdate) SetToken(b []byte) *DocumentTokenUpdate {
|
||||
dtu.mutation.SetToken(b)
|
||||
return dtu
|
||||
}
|
||||
|
||||
// SetUses sets the "uses" field.
|
||||
func (dtu *DocumentTokenUpdate) SetUses(i int) *DocumentTokenUpdate {
|
||||
dtu.mutation.ResetUses()
|
||||
dtu.mutation.SetUses(i)
|
||||
return dtu
|
||||
}
|
||||
|
||||
// SetNillableUses sets the "uses" field if the given value is not nil.
|
||||
func (dtu *DocumentTokenUpdate) SetNillableUses(i *int) *DocumentTokenUpdate {
|
||||
if i != nil {
|
||||
dtu.SetUses(*i)
|
||||
}
|
||||
return dtu
|
||||
}
|
||||
|
||||
// AddUses adds i to the "uses" field.
|
||||
func (dtu *DocumentTokenUpdate) AddUses(i int) *DocumentTokenUpdate {
|
||||
dtu.mutation.AddUses(i)
|
||||
return dtu
|
||||
}
|
||||
|
||||
// SetExpiresAt sets the "expires_at" field.
|
||||
func (dtu *DocumentTokenUpdate) SetExpiresAt(t time.Time) *DocumentTokenUpdate {
|
||||
dtu.mutation.SetExpiresAt(t)
|
||||
return dtu
|
||||
}
|
||||
|
||||
// SetNillableExpiresAt sets the "expires_at" field if the given value is not nil.
|
||||
func (dtu *DocumentTokenUpdate) SetNillableExpiresAt(t *time.Time) *DocumentTokenUpdate {
|
||||
if t != nil {
|
||||
dtu.SetExpiresAt(*t)
|
||||
}
|
||||
return dtu
|
||||
}
|
||||
|
||||
// SetDocumentID sets the "document" edge to the Document entity by ID.
|
||||
func (dtu *DocumentTokenUpdate) SetDocumentID(id uuid.UUID) *DocumentTokenUpdate {
|
||||
dtu.mutation.SetDocumentID(id)
|
||||
return dtu
|
||||
}
|
||||
|
||||
// SetNillableDocumentID sets the "document" edge to the Document entity by ID if the given value is not nil.
|
||||
func (dtu *DocumentTokenUpdate) SetNillableDocumentID(id *uuid.UUID) *DocumentTokenUpdate {
|
||||
if id != nil {
|
||||
dtu = dtu.SetDocumentID(*id)
|
||||
}
|
||||
return dtu
|
||||
}
|
||||
|
||||
// SetDocument sets the "document" edge to the Document entity.
|
||||
func (dtu *DocumentTokenUpdate) SetDocument(d *Document) *DocumentTokenUpdate {
|
||||
return dtu.SetDocumentID(d.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the DocumentTokenMutation object of the builder.
|
||||
func (dtu *DocumentTokenUpdate) Mutation() *DocumentTokenMutation {
|
||||
return dtu.mutation
|
||||
}
|
||||
|
||||
// ClearDocument clears the "document" edge to the Document entity.
|
||||
func (dtu *DocumentTokenUpdate) ClearDocument() *DocumentTokenUpdate {
|
||||
dtu.mutation.ClearDocument()
|
||||
return dtu
|
||||
}
|
||||
|
||||
// Save executes the query and returns the number of nodes affected by the update operation.
|
||||
func (dtu *DocumentTokenUpdate) Save(ctx context.Context) (int, error) {
|
||||
var (
|
||||
err error
|
||||
affected int
|
||||
)
|
||||
dtu.defaults()
|
||||
if len(dtu.hooks) == 0 {
|
||||
if err = dtu.check(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
affected, err = dtu.sqlSave(ctx)
|
||||
} else {
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*DocumentTokenMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
if err = dtu.check(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
dtu.mutation = mutation
|
||||
affected, err = dtu.sqlSave(ctx)
|
||||
mutation.done = true
|
||||
return affected, err
|
||||
})
|
||||
for i := len(dtu.hooks) - 1; i >= 0; i-- {
|
||||
if dtu.hooks[i] == nil {
|
||||
return 0, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = dtu.hooks[i](mut)
|
||||
}
|
||||
if _, err := mut.Mutate(ctx, dtu.mutation); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
}
|
||||
return affected, err
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (dtu *DocumentTokenUpdate) SaveX(ctx context.Context) int {
|
||||
affected, err := dtu.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return affected
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (dtu *DocumentTokenUpdate) Exec(ctx context.Context) error {
|
||||
_, err := dtu.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (dtu *DocumentTokenUpdate) ExecX(ctx context.Context) {
|
||||
if err := dtu.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (dtu *DocumentTokenUpdate) defaults() {
|
||||
if _, ok := dtu.mutation.UpdatedAt(); !ok {
|
||||
v := documenttoken.UpdateDefaultUpdatedAt()
|
||||
dtu.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (dtu *DocumentTokenUpdate) check() error {
|
||||
if v, ok := dtu.mutation.Token(); ok {
|
||||
if err := documenttoken.TokenValidator(v); err != nil {
|
||||
return &ValidationError{Name: "token", err: fmt.Errorf(`ent: validator failed for field "DocumentToken.token": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dtu *DocumentTokenUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
_spec := &sqlgraph.UpdateSpec{
|
||||
Node: &sqlgraph.NodeSpec{
|
||||
Table: documenttoken.Table,
|
||||
Columns: documenttoken.Columns,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: documenttoken.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
if ps := dtu.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if value, ok := dtu.mutation.UpdatedAt(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: documenttoken.FieldUpdatedAt,
|
||||
})
|
||||
}
|
||||
if value, ok := dtu.mutation.Token(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeBytes,
|
||||
Value: value,
|
||||
Column: documenttoken.FieldToken,
|
||||
})
|
||||
}
|
||||
if value, ok := dtu.mutation.Uses(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeInt,
|
||||
Value: value,
|
||||
Column: documenttoken.FieldUses,
|
||||
})
|
||||
}
|
||||
if value, ok := dtu.mutation.AddedUses(); ok {
|
||||
_spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeInt,
|
||||
Value: value,
|
||||
Column: documenttoken.FieldUses,
|
||||
})
|
||||
}
|
||||
if value, ok := dtu.mutation.ExpiresAt(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: documenttoken.FieldExpiresAt,
|
||||
})
|
||||
}
|
||||
if dtu.mutation.DocumentCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: documenttoken.DocumentTable,
|
||||
Columns: []string{documenttoken.DocumentColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: document.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := dtu.mutation.DocumentIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: documenttoken.DocumentTable,
|
||||
Columns: []string{documenttoken.DocumentColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: document.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if n, err = sqlgraph.UpdateNodes(ctx, dtu.driver, _spec); err != nil {
|
||||
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||
err = &NotFoundError{documenttoken.Label}
|
||||
} else if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// DocumentTokenUpdateOne is the builder for updating a single DocumentToken entity.
|
||||
type DocumentTokenUpdateOne struct {
|
||||
config
|
||||
fields []string
|
||||
hooks []Hook
|
||||
mutation *DocumentTokenMutation
|
||||
}
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (dtuo *DocumentTokenUpdateOne) SetUpdatedAt(t time.Time) *DocumentTokenUpdateOne {
|
||||
dtuo.mutation.SetUpdatedAt(t)
|
||||
return dtuo
|
||||
}
|
||||
|
||||
// SetToken sets the "token" field.
|
||||
func (dtuo *DocumentTokenUpdateOne) SetToken(b []byte) *DocumentTokenUpdateOne {
|
||||
dtuo.mutation.SetToken(b)
|
||||
return dtuo
|
||||
}
|
||||
|
||||
// SetUses sets the "uses" field.
|
||||
func (dtuo *DocumentTokenUpdateOne) SetUses(i int) *DocumentTokenUpdateOne {
|
||||
dtuo.mutation.ResetUses()
|
||||
dtuo.mutation.SetUses(i)
|
||||
return dtuo
|
||||
}
|
||||
|
||||
// SetNillableUses sets the "uses" field if the given value is not nil.
|
||||
func (dtuo *DocumentTokenUpdateOne) SetNillableUses(i *int) *DocumentTokenUpdateOne {
|
||||
if i != nil {
|
||||
dtuo.SetUses(*i)
|
||||
}
|
||||
return dtuo
|
||||
}
|
||||
|
||||
// AddUses adds i to the "uses" field.
|
||||
func (dtuo *DocumentTokenUpdateOne) AddUses(i int) *DocumentTokenUpdateOne {
|
||||
dtuo.mutation.AddUses(i)
|
||||
return dtuo
|
||||
}
|
||||
|
||||
// SetExpiresAt sets the "expires_at" field.
|
||||
func (dtuo *DocumentTokenUpdateOne) SetExpiresAt(t time.Time) *DocumentTokenUpdateOne {
|
||||
dtuo.mutation.SetExpiresAt(t)
|
||||
return dtuo
|
||||
}
|
||||
|
||||
// SetNillableExpiresAt sets the "expires_at" field if the given value is not nil.
|
||||
func (dtuo *DocumentTokenUpdateOne) SetNillableExpiresAt(t *time.Time) *DocumentTokenUpdateOne {
|
||||
if t != nil {
|
||||
dtuo.SetExpiresAt(*t)
|
||||
}
|
||||
return dtuo
|
||||
}
|
||||
|
||||
// SetDocumentID sets the "document" edge to the Document entity by ID.
|
||||
func (dtuo *DocumentTokenUpdateOne) SetDocumentID(id uuid.UUID) *DocumentTokenUpdateOne {
|
||||
dtuo.mutation.SetDocumentID(id)
|
||||
return dtuo
|
||||
}
|
||||
|
||||
// SetNillableDocumentID sets the "document" edge to the Document entity by ID if the given value is not nil.
|
||||
func (dtuo *DocumentTokenUpdateOne) SetNillableDocumentID(id *uuid.UUID) *DocumentTokenUpdateOne {
|
||||
if id != nil {
|
||||
dtuo = dtuo.SetDocumentID(*id)
|
||||
}
|
||||
return dtuo
|
||||
}
|
||||
|
||||
// SetDocument sets the "document" edge to the Document entity.
|
||||
func (dtuo *DocumentTokenUpdateOne) SetDocument(d *Document) *DocumentTokenUpdateOne {
|
||||
return dtuo.SetDocumentID(d.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the DocumentTokenMutation object of the builder.
|
||||
func (dtuo *DocumentTokenUpdateOne) Mutation() *DocumentTokenMutation {
|
||||
return dtuo.mutation
|
||||
}
|
||||
|
||||
// ClearDocument clears the "document" edge to the Document entity.
|
||||
func (dtuo *DocumentTokenUpdateOne) ClearDocument() *DocumentTokenUpdateOne {
|
||||
dtuo.mutation.ClearDocument()
|
||||
return dtuo
|
||||
}
|
||||
|
||||
// Select allows selecting one or more fields (columns) of the returned entity.
|
||||
// The default is selecting all fields defined in the entity schema.
|
||||
func (dtuo *DocumentTokenUpdateOne) Select(field string, fields ...string) *DocumentTokenUpdateOne {
|
||||
dtuo.fields = append([]string{field}, fields...)
|
||||
return dtuo
|
||||
}
|
||||
|
||||
// Save executes the query and returns the updated DocumentToken entity.
|
||||
func (dtuo *DocumentTokenUpdateOne) Save(ctx context.Context) (*DocumentToken, error) {
|
||||
var (
|
||||
err error
|
||||
node *DocumentToken
|
||||
)
|
||||
dtuo.defaults()
|
||||
if len(dtuo.hooks) == 0 {
|
||||
if err = dtuo.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
node, err = dtuo.sqlSave(ctx)
|
||||
} else {
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*DocumentTokenMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
if err = dtuo.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dtuo.mutation = mutation
|
||||
node, err = dtuo.sqlSave(ctx)
|
||||
mutation.done = true
|
||||
return node, err
|
||||
})
|
||||
for i := len(dtuo.hooks) - 1; i >= 0; i-- {
|
||||
if dtuo.hooks[i] == nil {
|
||||
return nil, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = dtuo.hooks[i](mut)
|
||||
}
|
||||
v, err := mut.Mutate(ctx, dtuo.mutation)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
nv, ok := v.(*DocumentToken)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected node type %T returned from DocumentTokenMutation", v)
|
||||
}
|
||||
node = nv
|
||||
}
|
||||
return node, err
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (dtuo *DocumentTokenUpdateOne) SaveX(ctx context.Context) *DocumentToken {
|
||||
node, err := dtuo.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// Exec executes the query on the entity.
|
||||
func (dtuo *DocumentTokenUpdateOne) Exec(ctx context.Context) error {
|
||||
_, err := dtuo.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (dtuo *DocumentTokenUpdateOne) ExecX(ctx context.Context) {
|
||||
if err := dtuo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (dtuo *DocumentTokenUpdateOne) defaults() {
|
||||
if _, ok := dtuo.mutation.UpdatedAt(); !ok {
|
||||
v := documenttoken.UpdateDefaultUpdatedAt()
|
||||
dtuo.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (dtuo *DocumentTokenUpdateOne) check() error {
|
||||
if v, ok := dtuo.mutation.Token(); ok {
|
||||
if err := documenttoken.TokenValidator(v); err != nil {
|
||||
return &ValidationError{Name: "token", err: fmt.Errorf(`ent: validator failed for field "DocumentToken.token": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dtuo *DocumentTokenUpdateOne) sqlSave(ctx context.Context) (_node *DocumentToken, err error) {
|
||||
_spec := &sqlgraph.UpdateSpec{
|
||||
Node: &sqlgraph.NodeSpec{
|
||||
Table: documenttoken.Table,
|
||||
Columns: documenttoken.Columns,
|
||||
ID: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: documenttoken.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
id, ok := dtuo.mutation.ID()
|
||||
if !ok {
|
||||
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "DocumentToken.id" for update`)}
|
||||
}
|
||||
_spec.Node.ID.Value = id
|
||||
if fields := dtuo.fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, documenttoken.FieldID)
|
||||
for _, f := range fields {
|
||||
if !documenttoken.ValidColumn(f) {
|
||||
return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
if f != documenttoken.FieldID {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
if ps := dtuo.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if value, ok := dtuo.mutation.UpdatedAt(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: documenttoken.FieldUpdatedAt,
|
||||
})
|
||||
}
|
||||
if value, ok := dtuo.mutation.Token(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeBytes,
|
||||
Value: value,
|
||||
Column: documenttoken.FieldToken,
|
||||
})
|
||||
}
|
||||
if value, ok := dtuo.mutation.Uses(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeInt,
|
||||
Value: value,
|
||||
Column: documenttoken.FieldUses,
|
||||
})
|
||||
}
|
||||
if value, ok := dtuo.mutation.AddedUses(); ok {
|
||||
_spec.Fields.Add = append(_spec.Fields.Add, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeInt,
|
||||
Value: value,
|
||||
Column: documenttoken.FieldUses,
|
||||
})
|
||||
}
|
||||
if value, ok := dtuo.mutation.ExpiresAt(); ok {
|
||||
_spec.Fields.Set = append(_spec.Fields.Set, &sqlgraph.FieldSpec{
|
||||
Type: field.TypeTime,
|
||||
Value: value,
|
||||
Column: documenttoken.FieldExpiresAt,
|
||||
})
|
||||
}
|
||||
if dtuo.mutation.DocumentCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: documenttoken.DocumentTable,
|
||||
Columns: []string{documenttoken.DocumentColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: document.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := dtuo.mutation.DocumentIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: documenttoken.DocumentTable,
|
||||
Columns: []string{documenttoken.DocumentColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: &sqlgraph.FieldSpec{
|
||||
Type: field.TypeUUID,
|
||||
Column: document.FieldID,
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
_node = &DocumentToken{config: dtuo.config}
|
||||
_spec.Assign = _node.assignValues
|
||||
_spec.ScanValues = _node.scanValues
|
||||
if err = sqlgraph.UpdateNode(ctx, dtuo.driver, _spec); err != nil {
|
||||
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||
err = &NotFoundError{documenttoken.Label}
|
||||
} else if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return _node, nil
|
||||
}
|
||||
@@ -6,33 +6,43 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/attachment"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authroles"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/authtokens"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/document"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/documenttoken"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/group"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/groupinvitationtoken"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/item"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/itemfield"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/label"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/location"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/maintenanceentry"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/notifier"
|
||||
"github.com/hay-kot/homebox/backend/internal/data/ent/user"
|
||||
)
|
||||
|
||||
// ent aliases to avoid import conflicts in user's code.
|
||||
type (
|
||||
Op = ent.Op
|
||||
Hook = ent.Hook
|
||||
Value = ent.Value
|
||||
Query = ent.Query
|
||||
Policy = ent.Policy
|
||||
Mutator = ent.Mutator
|
||||
Mutation = ent.Mutation
|
||||
MutateFunc = ent.MutateFunc
|
||||
Op = ent.Op
|
||||
Hook = ent.Hook
|
||||
Value = ent.Value
|
||||
Query = ent.Query
|
||||
QueryContext = ent.QueryContext
|
||||
Querier = ent.Querier
|
||||
QuerierFunc = ent.QuerierFunc
|
||||
Interceptor = ent.Interceptor
|
||||
InterceptFunc = ent.InterceptFunc
|
||||
Traverser = ent.Traverser
|
||||
TraverseFunc = ent.TraverseFunc
|
||||
Policy = ent.Policy
|
||||
Mutator = ent.Mutator
|
||||
Mutation = ent.Mutation
|
||||
MutateFunc = ent.MutateFunc
|
||||
)
|
||||
|
||||
// OrderFunc applies an ordering on the sql selector.
|
||||
@@ -42,15 +52,17 @@ type OrderFunc func(*sql.Selector)
|
||||
func columnChecker(table string) func(string) error {
|
||||
checks := map[string]func(string) bool{
|
||||
attachment.Table: attachment.ValidColumn,
|
||||
authroles.Table: authroles.ValidColumn,
|
||||
authtokens.Table: authtokens.ValidColumn,
|
||||
document.Table: document.ValidColumn,
|
||||
documenttoken.Table: documenttoken.ValidColumn,
|
||||
group.Table: group.ValidColumn,
|
||||
groupinvitationtoken.Table: groupinvitationtoken.ValidColumn,
|
||||
item.Table: item.ValidColumn,
|
||||
itemfield.Table: itemfield.ValidColumn,
|
||||
label.Table: label.ValidColumn,
|
||||
location.Table: location.ValidColumn,
|
||||
maintenanceentry.Table: maintenanceentry.ValidColumn,
|
||||
notifier.Table: notifier.ValidColumn,
|
||||
user.Table: user.ValidColumn,
|
||||
}
|
||||
check, ok := checks[table]
|
||||
@@ -283,6 +295,7 @@ func IsConstraintError(err error) bool {
|
||||
type selector struct {
|
||||
label string
|
||||
flds *[]string
|
||||
fns []AggregateFunc
|
||||
scan func(context.Context, any) error
|
||||
}
|
||||
|
||||
@@ -481,5 +494,121 @@ func (s *selector) BoolX(ctx context.Context) bool {
|
||||
return v
|
||||
}
|
||||
|
||||
// withHooks invokes the builder operation with the given hooks, if any.
|
||||
func withHooks[V Value, M any, PM interface {
|
||||
*M
|
||||
Mutation
|
||||
}](ctx context.Context, exec func(context.Context) (V, error), mutation PM, hooks []Hook) (value V, err error) {
|
||||
if len(hooks) == 0 {
|
||||
return exec(ctx)
|
||||
}
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutationT, ok := m.(PM)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
// Set the mutation to the builder.
|
||||
*mutation = *mutationT
|
||||
return exec(ctx)
|
||||
})
|
||||
for i := len(hooks) - 1; i >= 0; i-- {
|
||||
if hooks[i] == nil {
|
||||
return value, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = hooks[i](mut)
|
||||
}
|
||||
v, err := mut.Mutate(ctx, mutation)
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
nv, ok := v.(V)
|
||||
if !ok {
|
||||
return value, fmt.Errorf("unexpected node type %T returned from %T", v, mutation)
|
||||
}
|
||||
return nv, nil
|
||||
}
|
||||
|
||||
// setContextOp returns a new context with the given QueryContext attached (including its op) in case it does not exist.
|
||||
func setContextOp(ctx context.Context, qc *QueryContext, op string) context.Context {
|
||||
if ent.QueryFromContext(ctx) == nil {
|
||||
qc.Op = op
|
||||
ctx = ent.NewQueryContext(ctx, qc)
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
func querierAll[V Value, Q interface {
|
||||
sqlAll(context.Context, ...queryHook) (V, error)
|
||||
}]() Querier {
|
||||
return QuerierFunc(func(ctx context.Context, q Query) (Value, error) {
|
||||
query, ok := q.(Q)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected query type %T", q)
|
||||
}
|
||||
return query.sqlAll(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
func querierCount[Q interface {
|
||||
sqlCount(context.Context) (int, error)
|
||||
}]() Querier {
|
||||
return QuerierFunc(func(ctx context.Context, q Query) (Value, error) {
|
||||
query, ok := q.(Q)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected query type %T", q)
|
||||
}
|
||||
return query.sqlCount(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
func withInterceptors[V Value](ctx context.Context, q Query, qr Querier, inters []Interceptor) (v V, err error) {
|
||||
for i := len(inters) - 1; i >= 0; i-- {
|
||||
qr = inters[i].Intercept(qr)
|
||||
}
|
||||
rv, err := qr.Query(ctx, q)
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
vt, ok := rv.(V)
|
||||
if !ok {
|
||||
return v, fmt.Errorf("unexpected type %T returned from %T. expected type: %T", vt, q, v)
|
||||
}
|
||||
return vt, nil
|
||||
}
|
||||
|
||||
func scanWithInterceptors[Q1 ent.Query, Q2 interface {
|
||||
sqlScan(context.Context, Q1, any) error
|
||||
}](ctx context.Context, rootQuery Q1, selectOrGroup Q2, inters []Interceptor, v any) error {
|
||||
rv := reflect.ValueOf(v)
|
||||
var qr Querier = QuerierFunc(func(ctx context.Context, q Query) (Value, error) {
|
||||
query, ok := q.(Q1)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected query type %T", q)
|
||||
}
|
||||
if err := selectOrGroup.sqlScan(ctx, query, v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if k := rv.Kind(); k == reflect.Pointer && rv.Elem().CanInterface() {
|
||||
return rv.Elem().Interface(), nil
|
||||
}
|
||||
return v, nil
|
||||
})
|
||||
for i := len(inters) - 1; i >= 0; i-- {
|
||||
qr = inters[i].Intercept(qr)
|
||||
}
|
||||
vv, err := qr.Query(ctx, rootQuery)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch rv2 := reflect.ValueOf(vv); {
|
||||
case rv.IsNil(), rv2.IsNil(), rv.Kind() != reflect.Pointer:
|
||||
case rv.Type() == rv2.Type():
|
||||
rv.Elem().Set(rv2.Elem())
|
||||
case rv.Elem().Type() == rv2.Type():
|
||||
rv.Elem().Set(rv2)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// queryHook describes an internal hook for the different sqlAll methods.
|
||||
type queryHook func(context.Context, *sqlgraph.QuerySpec)
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
package ent
|
||||
|
||||
//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate --feature sql/versioned-migration ./schema
|
||||
//go:generate go run -mod=mod entgo.io/ent/cmd/ent generate --feature sql/versioned-migration ./schema --template=./schema/templates/has_id.tmpl
|
||||
|
||||
@@ -44,9 +44,11 @@ type GroupEdges struct {
|
||||
Documents []*Document `json:"documents,omitempty"`
|
||||
// InvitationTokens holds the value of the invitation_tokens edge.
|
||||
InvitationTokens []*GroupInvitationToken `json:"invitation_tokens,omitempty"`
|
||||
// Notifiers holds the value of the notifiers edge.
|
||||
Notifiers []*Notifier `json:"notifiers,omitempty"`
|
||||
// loadedTypes holds the information for reporting if a
|
||||
// type was loaded (or requested) in eager-loading or not.
|
||||
loadedTypes [6]bool
|
||||
loadedTypes [7]bool
|
||||
}
|
||||
|
||||
// UsersOrErr returns the Users value or an error if the edge
|
||||
@@ -103,6 +105,15 @@ func (e GroupEdges) InvitationTokensOrErr() ([]*GroupInvitationToken, error) {
|
||||
return nil, &NotLoadedError{edge: "invitation_tokens"}
|
||||
}
|
||||
|
||||
// NotifiersOrErr returns the Notifiers value or an error if the edge
|
||||
// was not loaded in eager-loading.
|
||||
func (e GroupEdges) NotifiersOrErr() ([]*Notifier, error) {
|
||||
if e.loadedTypes[6] {
|
||||
return e.Notifiers, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "notifiers"}
|
||||
}
|
||||
|
||||
// scanValues returns the types for scanning values from sql.Rows.
|
||||
func (*Group) scanValues(columns []string) ([]any, error) {
|
||||
values := make([]any, len(columns))
|
||||
@@ -166,39 +177,44 @@ 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)
|
||||
}
|
||||
|
||||
// QueryNotifiers queries the "notifiers" edge of the Group entity.
|
||||
func (gr *Group) QueryNotifiers() *NotifierQuery {
|
||||
return NewGroupClient(gr.config).QueryNotifiers(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,
|
||||
@@ -234,9 +250,3 @@ func (gr *Group) String() string {
|
||||
|
||||
// Groups is a parsable slice of Group.
|
||||
type Groups []*Group
|
||||
|
||||
func (gr Groups) config(cfg config) {
|
||||
for _i := range gr {
|
||||
gr[_i].config = cfg
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ const (
|
||||
EdgeDocuments = "documents"
|
||||
// EdgeInvitationTokens holds the string denoting the invitation_tokens edge name in mutations.
|
||||
EdgeInvitationTokens = "invitation_tokens"
|
||||
// EdgeNotifiers holds the string denoting the notifiers edge name in mutations.
|
||||
EdgeNotifiers = "notifiers"
|
||||
// Table holds the table name of the group in the database.
|
||||
Table = "groups"
|
||||
// UsersTable is the table that holds the users relation/edge.
|
||||
@@ -78,6 +80,13 @@ const (
|
||||
InvitationTokensInverseTable = "group_invitation_tokens"
|
||||
// InvitationTokensColumn is the table column denoting the invitation_tokens relation/edge.
|
||||
InvitationTokensColumn = "group_invitation_tokens"
|
||||
// NotifiersTable is the table that holds the notifiers relation/edge.
|
||||
NotifiersTable = "notifiers"
|
||||
// NotifiersInverseTable is the table name for the Notifier entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "notifier" package.
|
||||
NotifiersInverseTable = "notifiers"
|
||||
// NotifiersColumn is the table column denoting the notifiers relation/edge.
|
||||
NotifiersColumn = "group_id"
|
||||
)
|
||||
|
||||
// Columns holds all SQL columns for group fields.
|
||||
@@ -129,6 +138,13 @@ const (
|
||||
CurrencyNok Currency = "nok"
|
||||
CurrencySek Currency = "sek"
|
||||
CurrencyDkk Currency = "dkk"
|
||||
CurrencyInr Currency = "inr"
|
||||
CurrencyRmb Currency = "rmb"
|
||||
CurrencyBgn Currency = "bgn"
|
||||
CurrencyChf Currency = "chf"
|
||||
CurrencyPln Currency = "pln"
|
||||
CurrencyTry Currency = "try"
|
||||
CurrencyRon Currency = "ron"
|
||||
)
|
||||
|
||||
func (c Currency) String() string {
|
||||
@@ -138,7 +154,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:
|
||||
case CurrencyUsd, CurrencyEur, CurrencyGbp, CurrencyJpy, CurrencyZar, CurrencyAud, CurrencyNok, CurrencySek, CurrencyDkk, CurrencyInr, CurrencyRmb, CurrencyBgn, CurrencyChf, CurrencyPln, CurrencyTry, CurrencyRon:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("group: invalid enum value for currency field: %q", c)
|
||||
|
||||
@@ -13,357 +13,227 @@ import (
|
||||
|
||||
// ID filters vertices based on their ID field.
|
||||
func ID(id uuid.UUID) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Group(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDEQ applies the EQ predicate on the ID field.
|
||||
func IDEQ(id uuid.UUID) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Group(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDNEQ applies the NEQ predicate on the ID field.
|
||||
func IDNEQ(id uuid.UUID) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Group(sql.FieldNEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDIn applies the In predicate on the ID field.
|
||||
func IDIn(ids ...uuid.UUID) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
v := make([]any, len(ids))
|
||||
for i := range v {
|
||||
v[i] = ids[i]
|
||||
}
|
||||
s.Where(sql.In(s.C(FieldID), v...))
|
||||
})
|
||||
return predicate.Group(sql.FieldIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDNotIn applies the NotIn predicate on the ID field.
|
||||
func IDNotIn(ids ...uuid.UUID) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
v := make([]any, len(ids))
|
||||
for i := range v {
|
||||
v[i] = ids[i]
|
||||
}
|
||||
s.Where(sql.NotIn(s.C(FieldID), v...))
|
||||
})
|
||||
return predicate.Group(sql.FieldNotIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDGT applies the GT predicate on the ID field.
|
||||
func IDGT(id uuid.UUID) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Group(sql.FieldGT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDGTE applies the GTE predicate on the ID field.
|
||||
func IDGTE(id uuid.UUID) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Group(sql.FieldGTE(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLT applies the LT predicate on the ID field.
|
||||
func IDLT(id uuid.UUID) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Group(sql.FieldLT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLTE applies the LTE predicate on the ID field.
|
||||
func IDLTE(id uuid.UUID) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldID), id))
|
||||
})
|
||||
return predicate.Group(sql.FieldLTE(FieldID, id))
|
||||
}
|
||||
|
||||
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
|
||||
func CreatedAt(v time.Time) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
|
||||
func UpdatedAt(v time.Time) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// Name applies equality check predicate on the "name" field. It's identical to NameEQ.
|
||||
func Name(v string) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldName), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldEQ(FieldName, v))
|
||||
}
|
||||
|
||||
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
|
||||
func CreatedAtEQ(v time.Time) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
|
||||
func CreatedAtNEQ(v time.Time) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldNEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtIn applies the In predicate on the "created_at" field.
|
||||
func CreatedAtIn(vs ...time.Time) predicate.Group {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldCreatedAt), v...))
|
||||
})
|
||||
return predicate.Group(sql.FieldIn(FieldCreatedAt, vs...))
|
||||
}
|
||||
|
||||
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
|
||||
func CreatedAtNotIn(vs ...time.Time) predicate.Group {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldCreatedAt), v...))
|
||||
})
|
||||
return predicate.Group(sql.FieldNotIn(FieldCreatedAt, vs...))
|
||||
}
|
||||
|
||||
// CreatedAtGT applies the GT predicate on the "created_at" field.
|
||||
func CreatedAtGT(v time.Time) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldGT(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
|
||||
func CreatedAtGTE(v time.Time) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldGTE(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtLT applies the LT predicate on the "created_at" field.
|
||||
func CreatedAtLT(v time.Time) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldLT(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
|
||||
func CreatedAtLTE(v time.Time) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldCreatedAt), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldLTE(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
|
||||
func UpdatedAtEQ(v time.Time) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
|
||||
func UpdatedAtNEQ(v time.Time) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldNEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtIn applies the In predicate on the "updated_at" field.
|
||||
func UpdatedAtIn(vs ...time.Time) predicate.Group {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldUpdatedAt), v...))
|
||||
})
|
||||
return predicate.Group(sql.FieldIn(FieldUpdatedAt, vs...))
|
||||
}
|
||||
|
||||
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
|
||||
func UpdatedAtNotIn(vs ...time.Time) predicate.Group {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldUpdatedAt), v...))
|
||||
})
|
||||
return predicate.Group(sql.FieldNotIn(FieldUpdatedAt, vs...))
|
||||
}
|
||||
|
||||
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
|
||||
func UpdatedAtGT(v time.Time) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldGT(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
|
||||
func UpdatedAtGTE(v time.Time) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldGTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
|
||||
func UpdatedAtLT(v time.Time) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldLT(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
|
||||
func UpdatedAtLTE(v time.Time) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldUpdatedAt), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldLTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// NameEQ applies the EQ predicate on the "name" field.
|
||||
func NameEQ(v string) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldName), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldEQ(FieldName, v))
|
||||
}
|
||||
|
||||
// NameNEQ applies the NEQ predicate on the "name" field.
|
||||
func NameNEQ(v string) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldName), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldNEQ(FieldName, v))
|
||||
}
|
||||
|
||||
// NameIn applies the In predicate on the "name" field.
|
||||
func NameIn(vs ...string) predicate.Group {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldName), v...))
|
||||
})
|
||||
return predicate.Group(sql.FieldIn(FieldName, vs...))
|
||||
}
|
||||
|
||||
// NameNotIn applies the NotIn predicate on the "name" field.
|
||||
func NameNotIn(vs ...string) predicate.Group {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldName), v...))
|
||||
})
|
||||
return predicate.Group(sql.FieldNotIn(FieldName, vs...))
|
||||
}
|
||||
|
||||
// NameGT applies the GT predicate on the "name" field.
|
||||
func NameGT(v string) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.GT(s.C(FieldName), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldGT(FieldName, v))
|
||||
}
|
||||
|
||||
// NameGTE applies the GTE predicate on the "name" field.
|
||||
func NameGTE(v string) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.GTE(s.C(FieldName), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldGTE(FieldName, v))
|
||||
}
|
||||
|
||||
// NameLT applies the LT predicate on the "name" field.
|
||||
func NameLT(v string) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.LT(s.C(FieldName), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldLT(FieldName, v))
|
||||
}
|
||||
|
||||
// NameLTE applies the LTE predicate on the "name" field.
|
||||
func NameLTE(v string) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.LTE(s.C(FieldName), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldLTE(FieldName, v))
|
||||
}
|
||||
|
||||
// NameContains applies the Contains predicate on the "name" field.
|
||||
func NameContains(v string) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.Contains(s.C(FieldName), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldContains(FieldName, v))
|
||||
}
|
||||
|
||||
// NameHasPrefix applies the HasPrefix predicate on the "name" field.
|
||||
func NameHasPrefix(v string) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.HasPrefix(s.C(FieldName), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldHasPrefix(FieldName, v))
|
||||
}
|
||||
|
||||
// NameHasSuffix applies the HasSuffix predicate on the "name" field.
|
||||
func NameHasSuffix(v string) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.HasSuffix(s.C(FieldName), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldHasSuffix(FieldName, v))
|
||||
}
|
||||
|
||||
// NameEqualFold applies the EqualFold predicate on the "name" field.
|
||||
func NameEqualFold(v string) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.EqualFold(s.C(FieldName), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldEqualFold(FieldName, v))
|
||||
}
|
||||
|
||||
// NameContainsFold applies the ContainsFold predicate on the "name" field.
|
||||
func NameContainsFold(v string) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.ContainsFold(s.C(FieldName), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldContainsFold(FieldName, v))
|
||||
}
|
||||
|
||||
// CurrencyEQ applies the EQ predicate on the "currency" field.
|
||||
func CurrencyEQ(v Currency) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.EQ(s.C(FieldCurrency), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldEQ(FieldCurrency, v))
|
||||
}
|
||||
|
||||
// CurrencyNEQ applies the NEQ predicate on the "currency" field.
|
||||
func CurrencyNEQ(v Currency) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.NEQ(s.C(FieldCurrency), v))
|
||||
})
|
||||
return predicate.Group(sql.FieldNEQ(FieldCurrency, v))
|
||||
}
|
||||
|
||||
// CurrencyIn applies the In predicate on the "currency" field.
|
||||
func CurrencyIn(vs ...Currency) predicate.Group {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.In(s.C(FieldCurrency), v...))
|
||||
})
|
||||
return predicate.Group(sql.FieldIn(FieldCurrency, vs...))
|
||||
}
|
||||
|
||||
// CurrencyNotIn applies the NotIn predicate on the "currency" field.
|
||||
func CurrencyNotIn(vs ...Currency) predicate.Group {
|
||||
v := make([]any, len(vs))
|
||||
for i := range v {
|
||||
v[i] = vs[i]
|
||||
}
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
s.Where(sql.NotIn(s.C(FieldCurrency), v...))
|
||||
})
|
||||
return predicate.Group(sql.FieldNotIn(FieldCurrency, vs...))
|
||||
}
|
||||
|
||||
// HasUsers applies the HasEdge predicate on the "users" edge.
|
||||
@@ -371,7 +241,6 @@ func HasUsers() predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(UsersTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, UsersTable, UsersColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
@@ -399,7 +268,6 @@ func HasLocations() predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(LocationsTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, LocationsTable, LocationsColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
@@ -427,7 +295,6 @@ func HasItems() predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(ItemsTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, ItemsTable, ItemsColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
@@ -455,7 +322,6 @@ func HasLabels() predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(LabelsTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, LabelsTable, LabelsColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
@@ -483,7 +349,6 @@ func HasDocuments() predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(DocumentsTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, DocumentsTable, DocumentsColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
@@ -511,7 +376,6 @@ func HasInvitationTokens() predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(InvitationTokensTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, InvitationTokensTable, InvitationTokensColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
@@ -534,6 +398,33 @@ func HasInvitationTokensWith(preds ...predicate.GroupInvitationToken) predicate.
|
||||
})
|
||||
}
|
||||
|
||||
// HasNotifiers applies the HasEdge predicate on the "notifiers" edge.
|
||||
func HasNotifiers() predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, NotifiersTable, NotifiersColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasNotifiersWith applies the HasEdge predicate on the "notifiers" edge with a given conditions (other predicates).
|
||||
func HasNotifiersWith(preds ...predicate.Notifier) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(NotifiersInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, NotifiersTable, NotifiersColumn),
|
||||
)
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// And groups predicates with the AND operator between them.
|
||||
func And(predicates ...predicate.Group) predicate.Group {
|
||||
return predicate.Group(func(s *sql.Selector) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user