mirror of
https://github.com/cloudreve/cloudreve.git
synced 2026-03-03 16:57:02 +00:00
Compare commits
234 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b823305d5 | ||
|
|
edf16a9ed8 | ||
|
|
5d915f11ff | ||
|
|
d9baa74c81 | ||
|
|
3180c72b53 | ||
|
|
95865add54 | ||
|
|
9a59c8348e | ||
|
|
846366d223 | ||
|
|
5d45691e43 | ||
|
|
2a59407916 | ||
|
|
a8a625e967 | ||
|
|
153a00ecd5 | ||
|
|
1e3b851e19 | ||
|
|
ec9fdd33bc | ||
|
|
6322a9e951 | ||
|
|
57239e81af | ||
|
|
9dcc82ead8 | ||
|
|
b913b4683f | ||
|
|
1f580f0d8a | ||
|
|
87d48ac4a7 | ||
|
|
5d9cfaa973 | ||
|
|
2241a9e2c8 | ||
|
|
1c5eefdc6a | ||
|
|
c99a4ece90 | ||
|
|
43d77d2319 | ||
|
|
e4e6beb52d | ||
|
|
47218607ff | ||
|
|
5b214beadc | ||
|
|
2ecc7f4f59 | ||
|
|
2725bd47b5 | ||
|
|
864332f2e5 | ||
|
|
a84c5d8e97 | ||
|
|
a908ec462f | ||
|
|
bc6845bd74 | ||
|
|
7039fa801d | ||
|
|
6f8aecd35a | ||
|
|
722abb81c5 | ||
|
|
e8f965e980 | ||
|
|
f01ed64bdb | ||
|
|
736414fa10 | ||
|
|
5924e406ab | ||
|
|
87b1020c4a | ||
|
|
32632db36f | ||
|
|
c01b748dfc | ||
|
|
05c68b4062 | ||
|
|
a08c796e3f | ||
|
|
fec4dec3ac | ||
|
|
67c6f937c9 | ||
|
|
6ad72e07f4 | ||
|
|
994ef7af81 | ||
|
|
b507c1b893 | ||
|
|
deecc5c20b | ||
|
|
6085f2090f | ||
|
|
670b79eef3 | ||
|
|
4785be81c2 | ||
|
|
f27969d74f | ||
|
|
e3580d9351 | ||
|
|
16b02b1fb3 | ||
|
|
6bd30a8af7 | ||
|
|
21cdafb2af | ||
|
|
e29237d593 | ||
|
|
46897e2880 | ||
|
|
213eaa54dd | ||
|
|
e7d6fb25e4 | ||
|
|
e3e08a9b75 | ||
|
|
78f7ec8b08 | ||
|
|
3d41e00384 | ||
|
|
5e5dca40c4 | ||
|
|
668b542c59 | ||
|
|
440ab775b8 | ||
|
|
678593f30d | ||
|
|
58ceae9708 | ||
|
|
3b8110b648 | ||
|
|
f0c5b08428 | ||
|
|
9434c2f29b | ||
|
|
7d97237593 | ||
|
|
a581851f84 | ||
|
|
fe7cf5d0d8 | ||
|
|
cec2b55e1e | ||
|
|
af43746ba2 | ||
|
|
9f1cb52cfb | ||
|
|
4acf9401b8 | ||
|
|
c3ed4f5839 | ||
|
|
9b40e0146f | ||
|
|
a16b491f65 | ||
|
|
a095117061 | ||
|
|
acc660f112 | ||
|
|
a677e23394 | ||
|
|
13e774f27d | ||
|
|
91717b7c49 | ||
|
|
a1ce16bd5e | ||
|
|
872b08e5da | ||
|
|
f73583b370 | ||
|
|
c0132a10cb | ||
|
|
927c3bff00 | ||
|
|
bb9b42eb10 | ||
|
|
5f18d277c8 | ||
|
|
b0057fe92f | ||
|
|
bb3db2e326 | ||
|
|
8deeadb1e5 | ||
|
|
8688069fac | ||
|
|
4c08644b05 | ||
|
|
4c976b8627 | ||
|
|
b0375f5a24 | ||
|
|
48e9719336 | ||
|
|
7654ce889c | ||
|
|
80b25e88ee | ||
|
|
e31a6cbcb3 | ||
|
|
51d9e06f21 | ||
|
|
36be9b7a19 | ||
|
|
c8c2a60adb | ||
|
|
60bf0e02b3 | ||
|
|
488f32512d | ||
|
|
1cdccf5fc9 | ||
|
|
15762cb393 | ||
|
|
e96b595622 | ||
|
|
d19fc0e75c | ||
|
|
195d68c535 | ||
|
|
000124f6c7 | ||
|
|
ca57ca1ba0 | ||
|
|
3cda4d1ef7 | ||
|
|
b13490357b | ||
|
|
617d3a4262 | ||
|
|
75a03aa708 | ||
|
|
fe2ccb4d4e | ||
|
|
aada3aab02 | ||
|
|
a0aefef691 | ||
|
|
17fc598fb3 | ||
|
|
19a65b065c | ||
|
|
e0b2b4649e | ||
|
|
642c32c6cc | ||
|
|
6106b57bc7 | ||
|
|
f38f32f9f5 | ||
|
|
d382bd8f8d | ||
|
|
02abeaed2e | ||
|
|
6c9a72af14 | ||
|
|
4562042b8d | ||
|
|
dc611bcb0d | ||
|
|
2500ebc6a4 | ||
|
|
3db522609e | ||
|
|
d1bbfd4bc4 | ||
|
|
b11188fa50 | ||
|
|
1bd62e8feb | ||
|
|
fec549f5ec | ||
|
|
8fe2889772 | ||
|
|
bdc0aafab0 | ||
|
|
3de33aeb10 | ||
|
|
9f9796f2f3 | ||
|
|
9a216cd09e | ||
|
|
41eb010698 | ||
|
|
9d28fde00c | ||
|
|
40644f5234 | ||
|
|
d6d615e689 | ||
|
|
95d2b5804e | ||
|
|
a517f41ab1 | ||
|
|
e57e11a30e | ||
|
|
5f1b3a2bed | ||
|
|
b5136fc5e4 | ||
|
|
633ea479d7 | ||
|
|
8d6d188c3f | ||
|
|
6561e3075f | ||
|
|
e750cbfb77 | ||
|
|
3ab86e9b1d | ||
|
|
e2dbb0404a | ||
|
|
2a7b46437f | ||
|
|
fe309b234c | ||
|
|
522fcca6af | ||
|
|
c13b7365b0 | ||
|
|
51fa9f66a5 | ||
|
|
65095855c1 | ||
|
|
ec53769e33 | ||
|
|
9a96a88243 | ||
|
|
e0b193427c | ||
|
|
1fa70dc699 | ||
|
|
db7b54c5d7 | ||
|
|
c6ee3e5dcd | ||
|
|
9f5ebe11b6 | ||
|
|
1a3c3311e6 | ||
|
|
acffd984c1 | ||
|
|
7ddb611d6c | ||
|
|
7bace40a4d | ||
|
|
2fac086127 | ||
|
|
a10a008ed7 | ||
|
|
5d72faf688 | ||
|
|
0a28bf1689 | ||
|
|
bdaf091aca | ||
|
|
d60c3e6bf4 | ||
|
|
1e2cfe0061 | ||
|
|
71a624c10e | ||
|
|
1b8beb3390 | ||
|
|
762811d50f | ||
|
|
edd50147e7 | ||
|
|
006bcabcdb | ||
|
|
10e3854082 | ||
|
|
fbf1d1d42c | ||
|
|
c5467f228a | ||
|
|
2a6a43d242 | ||
|
|
6e82ce2a9d | ||
|
|
a0b4c97db0 | ||
|
|
2333ed3501 | ||
|
|
67d3b25c87 | ||
|
|
ca47f79ecb | ||
|
|
77ae381474 | ||
|
|
c6eef43590 | ||
|
|
d8fc81d0eb | ||
|
|
d195002bf7 | ||
|
|
d6496ee9a0 | ||
|
|
55a3669a9e | ||
|
|
969e35192a | ||
|
|
224ac28ffe | ||
|
|
cc69178310 | ||
|
|
9226d0c8ec | ||
|
|
7b5e0e8581 | ||
|
|
d60e400f83 | ||
|
|
21d158db07 | ||
|
|
da4e44b77a | ||
|
|
3373b9dc02 | ||
|
|
12e3f10ad7 | ||
|
|
23d009d611 | ||
|
|
3edb00a648 | ||
|
|
88409cc1f0 | ||
|
|
cd6eee0b60 | ||
|
|
3ffce1e356 | ||
|
|
ce832bf13d | ||
|
|
5642dd3b66 | ||
|
|
a1747073df | ||
|
|
ad6c6bcd93 | ||
|
|
f4a04ce3c3 | ||
|
|
247e31079c | ||
|
|
a26893aabc | ||
|
|
ce759c02b1 | ||
|
|
9f6f9adc89 | ||
|
|
91025b9f24 | ||
|
|
a9bee3e638 |
7
.build/aria2.supervisor.conf
Normal file
7
.build/aria2.supervisor.conf
Normal file
@@ -0,0 +1,7 @@
|
||||
[supervisord]
|
||||
nodaemon=false
|
||||
|
||||
[program:background_process]
|
||||
command=aria2c --enable-rpc --save-session /cloudreve/data
|
||||
autostart=true
|
||||
autorestart=true
|
||||
15
.build/build-assets.sh
Executable file
15
.build/build-assets.sh
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
export NODE_OPTIONS="--max-old-space-size=8192"
|
||||
|
||||
# This script is used to build the assets for the application.
|
||||
cd assets
|
||||
rm -rf build
|
||||
yarn install --network-timeout 1000000
|
||||
yarn version --new-version $1 --no-git-tag-version
|
||||
yarn run build
|
||||
|
||||
# Copy the build files to the application directory
|
||||
cd ../
|
||||
zip -r - assets/build >assets.zip
|
||||
mv assets.zip application/statics
|
||||
2
.build/entrypoint.sh
Executable file
2
.build/entrypoint.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
supervisord -c ./aria2.supervisor.conf
|
||||
./cloudreve
|
||||
19
.github/DISCUSSION_TEMPLATE/general.yml
vendored
Normal file
19
.github/DISCUSSION_TEMPLATE/general.yml
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
title: "General Discussion"
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Self Checks
|
||||
description: "To make sure we get to you in time, please check the following :)"
|
||||
options:
|
||||
- label: I have searched for existing issues [search for existing issues](https://github.com/cloudreve/cloudreve/issues), including closed ones.
|
||||
required: true
|
||||
- label: I confirm that I am using English to submit this report, otherwise it will be closed. / 请使用英语提交,否则会被关闭。
|
||||
required: true
|
||||
- label: "Please do not modify this template :) and fill in all the required fields."
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Content
|
||||
placeholder: Please describe the content you would like to discuss.
|
||||
validations:
|
||||
required: true
|
||||
35
.github/DISCUSSION_TEMPLATE/ideas.yml
vendored
Normal file
35
.github/DISCUSSION_TEMPLATE/ideas.yml
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
title: Suggestions for New Features
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Self Checks
|
||||
description: "To make sure we get to you in time, please check the following :)"
|
||||
options:
|
||||
- label: I have searched for existing issues [search for existing issues](https://github.com/cloudreve/cloudreve/issues), including closed ones.
|
||||
required: true
|
||||
- label: I confirm that I am using English to submit this report, otherwise it will be closed. / 请使用英语提交,否则会被关闭。
|
||||
required: true
|
||||
- label: "Please do not modify this template :) and fill in all the required fields."
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 1. Is this request related to a challenge you're experiencing? Tell me about your story.
|
||||
placeholder: Please describe the specific scenario or problem you're facing as clearly as possible. For instance "I was trying to use [feature] for [specific task], and [what happened]... It was frustrating because...."
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 2. Additional context or comments
|
||||
placeholder: (Any other information, comments, documentations, links, or screenshots that would provide more clarity. This is the place to add anything else not covered above.)
|
||||
validations:
|
||||
required: false
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: 3. Can you help us with this feature?
|
||||
description: Let us know! This is not a commitment, but a starting point for collaboration.
|
||||
options:
|
||||
- label: I am interested in contributing to this feature.
|
||||
required: false
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: Please limit one request per issue.
|
||||
28
.github/DISCUSSION_TEMPLATE/q-a.yml
vendored
Normal file
28
.github/DISCUSSION_TEMPLATE/q-a.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
title: "Q&A"
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Self Checks
|
||||
description: "To make sure we get to you in time, please check the following :)"
|
||||
options:
|
||||
- label: I have searched for existing issues [search for existing issues](https://github.com/cloudreve/cloudreve/issues), including closed ones.
|
||||
required: true
|
||||
- label: I confirm that I am using English to submit this report, otherwise it will be closed. / 请使用英语提交,否则会被关闭。
|
||||
required: true
|
||||
- label: "Please do not modify this template :) and fill in all the required fields."
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 1. Is this request related to a challenge you're experiencing? Tell me about your story.
|
||||
placeholder: Please describe the specific scenario or problem you're facing as clearly as possible. For instance "I was trying to use [feature] for [specific task], and [what happened]... It was frustrating because...."
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 2. Additional context or comments
|
||||
placeholder: (Any other information, comments, documentations, links, or screenshots that would provide more clarity. This is the place to add anything else not covered above.)
|
||||
validations:
|
||||
required: false
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: Please limit one request per issue.
|
||||
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
38
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,38 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Desktop (please complete the following information):**
|
||||
- OS: [e.g. iOS]
|
||||
- Browser [e.g. chrome, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Smartphone (please complete the following information):**
|
||||
- Device: [e.g. iPhone6]
|
||||
- OS: [e.g. iOS8.1]
|
||||
- Browser [e.g. stock browser, safari]
|
||||
- Version [e.g. 22]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
91
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
91
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
name: "🕷️ Bug report"
|
||||
description: Report errors or unexpected behavior
|
||||
labels:
|
||||
- bug
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Self Checks
|
||||
description: "To make sure we get to you in time, please check the following :)"
|
||||
options:
|
||||
- label: I have read the [Contributing Guide](https://docs.cloudreve.org/api/contributing) and [Language Policy](https://github.com/cloudreve/cloudreve/discussions/3335).
|
||||
required: true
|
||||
- label: This is only for bug report, if you would like to ask a question, please head to [Discussions](https://github.com/cloudreve/cloudreve/discussions).
|
||||
required: true
|
||||
- label: I have searched for existing issues [search for existing issues](https://github.com/cloudreve/cloudreve/issues), including closed ones.
|
||||
required: true
|
||||
- label: I confirm that I am using English to submit this report, otherwise it will be closed. / 请使用英语提交,否则会被关闭。
|
||||
required: true
|
||||
- label: "Please do not modify this template :) and fill in all the required fields."
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: Cloudreve version
|
||||
description: e.g. 4.14.0
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Pro or Community Edition
|
||||
description: What version of Cloudreve are you using?
|
||||
multiple: true
|
||||
options:
|
||||
- Pro
|
||||
- Community (Open Source)
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Database type
|
||||
description: What database are you using?
|
||||
multiple: true
|
||||
options:
|
||||
- MySQL
|
||||
- PostgreSQL
|
||||
- SQLite
|
||||
- I don't know
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: Browser and operating system
|
||||
description: What browser and operating system are you using?
|
||||
placeholder: E.g. Chrome 123.0.0 on macOS 14.0.0
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: We highly suggest including screenshots and a bug report log. Please use the right markdown syntax for code blocks.
|
||||
placeholder: Having detailed steps helps us reproduce the bug. If you have logs, please use fenced code blocks (triple backticks ```) to format them.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: ✔️ Expected Behavior
|
||||
description: Describe what you expected to happen.
|
||||
placeholder: What were you expecting? Please do not copy and paste the steps to reproduce here.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: ❌ Actual Behavior
|
||||
description: Describe what actually happened.
|
||||
placeholder: What happened instead? Please do not copy and paste the steps to reproduce here.
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: Addition context information
|
||||
description: Provide any additional context information that might be helpful.
|
||||
placeholder: Any additional information that might be helpful.
|
||||
validations:
|
||||
required: false
|
||||
14
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
14
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: "\U0001F4F1 iOS App related issues"
|
||||
url: "https://github.com/cloudreve/ios-feedback/issues/new"
|
||||
about: Report issues related to the official iOS/iPadOS client.
|
||||
- name: "\U0001F5A5 Desktop client related issues"
|
||||
url: "https://github.com/cloudreve/desktop/issues/new"
|
||||
about: Report issues related to the official desktop client.
|
||||
- name: "\U0001F4AC Documentation Issues"
|
||||
url: "https://github.com/cloudreve/docs/issues/new"
|
||||
about: Report issues with the documentation, such as typos, outdated information, or missing content. Please provide the specific section and details of the issue.
|
||||
- name: "\U0001F4E7 Discussions"
|
||||
url: https://github.com/cloudreve/cloudreve/discussions
|
||||
about: General discussions and seek help from the community
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
40
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
40
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
name: "⭐ Feature or enhancement request"
|
||||
description: Propose something new.
|
||||
labels:
|
||||
- enhancement
|
||||
body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Self Checks
|
||||
description: "To make sure we get to you in time, please check the following :)"
|
||||
options:
|
||||
- label: I have read the [Contributing Guide](https://docs.cloudreve.org/api/contributing) and [Language Policy](https://github.com/cloudreve/cloudreve/discussions/3335).
|
||||
required: true
|
||||
- label: I have searched for existing issues [search for existing issues](https://github.com/cloudreve/cloudreve/issues), including closed ones.
|
||||
required: true
|
||||
- label: I confirm that I am using English to submit this report, otherwise it will be closed. / 请使用英语提交,否则会被关闭。
|
||||
required: true
|
||||
- label: "Please do not modify this template :) and fill in all the required fields."
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 1. Is this request related to a challenge you're experiencing? Tell me about your story.
|
||||
placeholder: Please describe the specific scenario or problem you're facing as clearly as possible. For instance "I was trying to use [feature] for [specific task], and [what happened]... It was frustrating because...."
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: 2. Additional context or comments
|
||||
placeholder: (Any other information, comments, documentations, links, or screenshots that would provide more clarity. This is the place to add anything else not covered above.)
|
||||
validations:
|
||||
required: false
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: 3. Can you help us with this feature?
|
||||
description: Let us know! This is not a commitment, but a starting point for collaboration.
|
||||
options:
|
||||
- label: I am interested in contributing to this feature.
|
||||
required: false
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: Please limit one request per issue.
|
||||
31
.github/workflows/build.yml
vendored
31
.github/workflows/build.yml
vendored
@@ -1,31 +0,0 @@
|
||||
name: Build
|
||||
|
||||
on: workflow_dispatch
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Go 1.20
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: "1.20"
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
clean: false
|
||||
submodules: "recursive"
|
||||
- run: |
|
||||
git fetch --prune --unshallow --tags
|
||||
|
||||
- name: Build and Release
|
||||
uses: goreleaser/goreleaser-action@v4
|
||||
with:
|
||||
distribution: goreleaser
|
||||
version: latest
|
||||
args: release --clean --skip-validate
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
57
.github/workflows/docker-release.yml
vendored
57
.github/workflows/docker-release.yml
vendored
@@ -1,57 +0,0 @@
|
||||
name: Build and push docker image
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 3.* # triggered on every push with tag 3.*
|
||||
workflow_dispatch: # or just on button clicked
|
||||
|
||||
jobs:
|
||||
docker-build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- run: git fetch --prune --unshallow
|
||||
- name: Setup Environments
|
||||
id: envs
|
||||
run: |
|
||||
CLOUDREVE_LATEST_TAG=$(git describe --tags --abbrev=0)
|
||||
DOCKER_IMAGE="cloudreve/cloudreve"
|
||||
|
||||
echo "RELEASE_VERSION=${GITHUB_REF#refs}"
|
||||
TAGS="${DOCKER_IMAGE}:latest,${DOCKER_IMAGE}:${CLOUDREVE_LATEST_TAG}"
|
||||
|
||||
echo "CLOUDREVE_LATEST_TAG:${CLOUDREVE_LATEST_TAG}"
|
||||
echo ::set-output name=tags::${TAGS}
|
||||
- name: Setup QEMU Emulator
|
||||
uses: docker/setup-qemu-action@master
|
||||
with:
|
||||
platforms: all
|
||||
- name: Setup Docker Buildx Command
|
||||
id: buildx
|
||||
uses: docker/setup-buildx-action@master
|
||||
- name: Login to Dockerhub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
- name: Build Docker Image and Push
|
||||
id: docker_build
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
push: true
|
||||
builder: ${{ steps.buildx.outputs.name }}
|
||||
context: .
|
||||
file: ./Dockerfile
|
||||
platforms: linux/amd64,linux/arm64,linux/arm/v7
|
||||
tags: ${{ steps.envs.outputs.tags }}
|
||||
- name: Update Docker Hub Description
|
||||
uses: peter-evans/dockerhub-description@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_PASSWORD }}
|
||||
repository: cloudreve/cloudreve
|
||||
short-description: ${{ github.event.repository.description }}
|
||||
- name: Image Digest
|
||||
run: echo ${{ steps.docker_build.outputs.digest }}
|
||||
35
.github/workflows/test.yml
vendored
35
.github/workflows/test.yml
vendored
@@ -1,35 +0,0 @@
|
||||
name: Test
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
push:
|
||||
branches: [master]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Go 1.20
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: "1.20"
|
||||
id: go
|
||||
|
||||
- name: Check out code into the Go module directory
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: "recursive"
|
||||
|
||||
- name: Build static files
|
||||
run: |
|
||||
mkdir assets/build
|
||||
touch assets/build/test.html
|
||||
|
||||
- name: Test
|
||||
run: go test -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
|
||||
- name: Upload coverage reports to Codecov
|
||||
uses: codecov/codecov-action@v2
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,5 +1,4 @@
|
||||
# Binaries for programs and plugins
|
||||
cloudreve
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
@@ -8,7 +7,7 @@ cloudreve
|
||||
*.db
|
||||
*.bin
|
||||
/release/
|
||||
assets.zip
|
||||
application/statics/assets.zip
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
@@ -31,3 +30,7 @@ conf/conf.ini
|
||||
.vscode/
|
||||
|
||||
dist/
|
||||
data/
|
||||
tmp/
|
||||
.devcontainer/
|
||||
cloudreve
|
||||
|
||||
@@ -1,29 +1,32 @@
|
||||
env:
|
||||
- CI=false
|
||||
- GENERATE_SOURCEMAP=false
|
||||
version: 2
|
||||
|
||||
before:
|
||||
hooks:
|
||||
- go mod tidy
|
||||
- sh -c "cd assets && rm -rf build && yarn install --network-timeout 1000000 && yarn run build && cd ../ && zip -r - assets/build >assets.zip"
|
||||
- chmod +x ./.build/build-assets.sh
|
||||
- ./.build/build-assets.sh {{.Version}}
|
||||
|
||||
builds:
|
||||
-
|
||||
env:
|
||||
- env:
|
||||
- CGO_ENABLED=0
|
||||
|
||||
binary: cloudreve
|
||||
|
||||
ldflags:
|
||||
- -X 'github.com/cloudreve/Cloudreve/v3/pkg/conf.BackendVersion={{.Tag}}' -X 'github.com/cloudreve/Cloudreve/v3/pkg/conf.LastCommit={{.ShortCommit}}'
|
||||
- -s -w
|
||||
- -X 'github.com/cloudreve/Cloudreve/v4/application/constants.BackendVersion={{.Tag}}' -X 'github.com/cloudreve/Cloudreve/v4/application/constants.LastCommit={{.ShortCommit}}'
|
||||
|
||||
goos:
|
||||
- linux
|
||||
- windows
|
||||
- darwin
|
||||
- freebsd
|
||||
|
||||
goarch:
|
||||
- amd64
|
||||
- arm
|
||||
- arm64
|
||||
- loong64
|
||||
|
||||
goarm:
|
||||
- 5
|
||||
@@ -37,85 +40,79 @@ builds:
|
||||
goarm: 6
|
||||
- goos: windows
|
||||
goarm: 7
|
||||
- goos: windows
|
||||
goarch: loong64
|
||||
- goos: freebsd
|
||||
goarch: loong64
|
||||
- goos: freebsd
|
||||
goarch: arm
|
||||
|
||||
archives:
|
||||
- format: tar.gz
|
||||
- formats: ["tar.gz"]
|
||||
# this name template makes the OS and Arch compatible with the results of uname.
|
||||
name_template: >-
|
||||
cloudreve_{{.Tag}}_{{- .Os }}_{{ .Arch }}
|
||||
{{- if .Arm }}v{{ .Arm }}{{ end }}
|
||||
# use zip for windows archives
|
||||
format_overrides:
|
||||
- goos: windows
|
||||
format: zip
|
||||
- goos: windows
|
||||
formats: ["zip"]
|
||||
|
||||
checksum:
|
||||
name_template: 'checksums.txt'
|
||||
name_template: "checksums.txt"
|
||||
snapshot:
|
||||
name_template: "{{ incpatch .Version }}-next"
|
||||
version_template: "{{ incpatch .Version }}-next"
|
||||
|
||||
changelog:
|
||||
sort: asc
|
||||
filters:
|
||||
exclude:
|
||||
- '^docs:'
|
||||
- '^test:'
|
||||
- "^docs:"
|
||||
- "^test:"
|
||||
|
||||
release:
|
||||
draft: true
|
||||
prerelease: auto
|
||||
target_commitish: '{{ .Commit }}'
|
||||
target_commitish: "{{ .Commit }}"
|
||||
name_template: "{{.Version}}"
|
||||
|
||||
dockers:
|
||||
-
|
||||
dockerfile: Dockerfile
|
||||
- dockerfile: Dockerfile
|
||||
use: buildx
|
||||
build_flag_templates:
|
||||
- "--platform=linux/amd64"
|
||||
- "--provenance=false"
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
goamd64: v1
|
||||
extra_files:
|
||||
- .build/aria2.supervisor.conf
|
||||
- .build/entrypoint.sh
|
||||
image_templates:
|
||||
- "cloudreve/cloudreve:{{ .Tag }}-amd64"
|
||||
-
|
||||
dockerfile: Dockerfile
|
||||
- dockerfile: Dockerfile
|
||||
use: buildx
|
||||
build_flag_templates:
|
||||
- "--platform=linux/arm64"
|
||||
- "--provenance=false"
|
||||
goos: linux
|
||||
goarch: arm64
|
||||
extra_files:
|
||||
- .build/aria2.supervisor.conf
|
||||
- .build/entrypoint.sh
|
||||
image_templates:
|
||||
- "cloudreve/cloudreve:{{ .Tag }}-arm64"
|
||||
-
|
||||
dockerfile: Dockerfile
|
||||
use: buildx
|
||||
build_flag_templates:
|
||||
- "--platform=linux/arm/v6"
|
||||
goos: linux
|
||||
goarch: arm
|
||||
goarm: '6'
|
||||
image_templates:
|
||||
- "cloudreve/cloudreve:{{ .Tag }}-armv6"
|
||||
-
|
||||
dockerfile: Dockerfile
|
||||
use: buildx
|
||||
build_flag_templates:
|
||||
- "--platform=linux/arm/v7"
|
||||
goos: linux
|
||||
goarch: arm
|
||||
goarm: '7'
|
||||
image_templates:
|
||||
- "cloudreve/cloudreve:{{ .Tag }}-armv7"
|
||||
|
||||
docker_manifests:
|
||||
- name_template: "cloudreve/cloudreve:latest"
|
||||
image_templates:
|
||||
- "cloudreve/cloudreve:{{ .Tag }}-amd64"
|
||||
- "cloudreve/cloudreve:{{ .Tag }}-arm64"
|
||||
- "cloudreve/cloudreve:{{ .Tag }}-armv6"
|
||||
- "cloudreve/cloudreve:{{ .Tag }}-armv7"
|
||||
- name_template: "cloudreve/cloudreve:v4"
|
||||
image_templates:
|
||||
- "cloudreve/cloudreve:{{ .Tag }}-amd64"
|
||||
- "cloudreve/cloudreve:{{ .Tag }}-arm64"
|
||||
- name_template: "cloudreve/cloudreve:{{ .Tag }}"
|
||||
image_templates:
|
||||
- "cloudreve/cloudreve:{{ .Tag }}-amd64"
|
||||
- "cloudreve/cloudreve:{{ .Tag }}-arm64"
|
||||
- "cloudreve/cloudreve:{{ .Tag }}-armv6"
|
||||
- "cloudreve/cloudreve:{{ .Tag }}-armv7"
|
||||
29
Dockerfile
29
Dockerfile
@@ -1,17 +1,30 @@
|
||||
FROM alpine:latest
|
||||
|
||||
WORKDIR /cloudreve
|
||||
COPY cloudreve ./cloudreve
|
||||
|
||||
RUN apk update \
|
||||
&& apk add --no-cache tzdata \
|
||||
&& apk add --no-cache tzdata vips-tools ffmpeg libreoffice aria2 supervisor font-noto font-noto-cjk libheif libraw-tools\
|
||||
&& cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
|
||||
&& echo "Asia/Shanghai" > /etc/timezone \
|
||||
&& chmod +x ./cloudreve \
|
||||
&& mkdir -p /data/aria2 \
|
||||
&& chmod -R 766 /data/aria2
|
||||
&& mkdir -p ./data/temp/aria2 \
|
||||
&& chmod -R 766 ./data/temp/aria2
|
||||
|
||||
EXPOSE 5212
|
||||
VOLUME ["/cloudreve/uploads", "/cloudreve/avatar", "/data"]
|
||||
ENV CR_ENABLE_ARIA2=1 \
|
||||
CR_SETTING_DEFAULT_thumb_ffmpeg_enabled=1 \
|
||||
CR_SETTING_DEFAULT_thumb_vips_enabled=1 \
|
||||
CR_SETTING_DEFAULT_thumb_libreoffice_enabled=1 \
|
||||
CR_SETTING_DEFAULT_media_meta_ffprobe=1 \
|
||||
CR_SETTING_DEFAULT_thumb_libraw_enabled=1
|
||||
|
||||
COPY .build/aria2.supervisor.conf .build/entrypoint.sh ./
|
||||
COPY cloudreve ./cloudreve
|
||||
|
||||
RUN chmod +x ./cloudreve \
|
||||
&& chmod +x ./entrypoint.sh
|
||||
|
||||
EXPOSE 5212 443
|
||||
|
||||
VOLUME ["/cloudreve/data"]
|
||||
|
||||
ENTRYPOINT ["sh", "./entrypoint.sh"]
|
||||
|
||||
ENTRYPOINT ["./cloudreve"]
|
||||
|
||||
100
README.md
100
README.md
@@ -1,4 +1,4 @@
|
||||
[中文版本](https://github.com/cloudreve/Cloudreve/blob/master/README_zh-CN.md)
|
||||
[中文版本](https://github.com/cloudreve/cloudreve/blob/master/README_zh-CN.md)
|
||||
|
||||
<h1 align="center">
|
||||
<br>
|
||||
@@ -7,97 +7,69 @@
|
||||
Cloudreve
|
||||
<br>
|
||||
</h1>
|
||||
<h4 align="center">Self-hosted file management system with muilt-cloud support.</h4>
|
||||
<h4 align="center">Self-hosted file management system with multi-cloud support.</h4>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/cloudreve/Cloudreve/actions/workflows/test.yml">
|
||||
<img src="https://img.shields.io/github/actions/workflow/status/cloudreve/Cloudreve/test.yml?branch=master&style=flat-square"
|
||||
alt="GitHub Test Workflow">
|
||||
<a href="https://dev.azure.com/abslantliu/cloudreve/_build?definitionId=6">
|
||||
<img src="https://img.shields.io/github/check-runs/cloudreve/cloudreve/master"
|
||||
alt="Azure pipelines">
|
||||
</a>
|
||||
<a href="https://codecov.io/gh/cloudreve/Cloudreve"><img src="https://img.shields.io/codecov/c/github/cloudreve/Cloudreve?style=flat-square"></a>
|
||||
<a href="https://goreportcard.com/report/github.com/cloudreve/Cloudreve">
|
||||
<img src="https://goreportcard.com/badge/github.com/cloudreve/Cloudreve?style=flat-square">
|
||||
<a href="https://github.com/cloudreve/cloudreve/releases">
|
||||
<img src="https://img.shields.io/github/v/release/cloudreve/cloudreve?include_prereleases" />
|
||||
</a>
|
||||
<a href="https://github.com/cloudreve/Cloudreve/releases">
|
||||
<img src="https://img.shields.io/github/v/release/cloudreve/Cloudreve?include_prereleases&style=flat-square" />
|
||||
<a href="https://github.com/cloudreve/cloudreve/releases">
|
||||
<img src="https://badgen.net/static/release%20size/34%20MB/blue"/>
|
||||
</a>
|
||||
<a href="https://hub.docker.com/r/cloudreve/cloudreve">
|
||||
<img src="https://img.shields.io/docker/image-size/cloudreve/cloudreve?style=flat-square"/>
|
||||
<img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/cloudreve/cloudreve" />
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://cloudreve.org">Homepage</a> •
|
||||
<a href="https://demo.cloudreve.org">Demo</a> •
|
||||
<a href="https://forum.cloudreve.org/">Discussion</a> •
|
||||
<a href="https://docs.cloudreve.org/v/en/">Documents</a> •
|
||||
<a href="https://github.com/cloudreve/Cloudreve/releases">Download</a> •
|
||||
<a href="https://t.me/cloudreve_official">Telegram Group</a> •
|
||||
<a href="#scroll-License">License</a>
|
||||
<a href="https://demo.cloudreve.org">Try it</a> •
|
||||
<a href="https://github.com/cloudreve/cloudreve/discussions">Discussion</a> •
|
||||
<a href="https://docs.cloudreve.org">Documents</a> •
|
||||
<a href="https://github.com/cloudreve/cloudreve/releases">Download</a> •
|
||||
<a href="https://t.me/cloudreve_official">Telegram</a> •
|
||||
<a href="https://discord.com/invite/WTpMFpZT76">Discord</a>
|
||||
</p>
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
## :sparkles: Features
|
||||
|
||||
* :cloud: Support storing files into Local storage, Remote storage, Qiniu, Aliyun OSS, Tencent COS, Upyun, OneDrive, S3 compatible API.
|
||||
* :outbox_tray: Upload/Download in directly transmission with speed limiting support.
|
||||
* 💾 Integrate with Aria2 to download files offline, use multiple download nodes to share the load.
|
||||
* 📚 Compress/Extract files, download files in batch.
|
||||
* 💻 WebDAV support covering all storage providers.
|
||||
* :zap:Drag&Drop to upload files or folders, with streaming upload processing.
|
||||
* :card_file_box: Drag & Drop to manage your files.
|
||||
* :family_woman_girl_boy: Multi-users with multi-groups.
|
||||
* :link: Create share links for files and folders with expiration date.
|
||||
* :eye_speech_bubble: Preview videos, images, audios, ePub files online; edit texts, Office documents online.
|
||||
* :art: Customize theme colors, dark mode, PWA application, SPA, i18n.
|
||||
* :rocket: All-In-One packing, with all features out-of-the-box.
|
||||
* 🌈 ... ...
|
||||
- :cloud: Support storing files into Local, Remote node, OneDrive, S3 compatible API, Qiniu Kodo, Aliyun OSS, Tencent COS, Huawei Cloud OBS, Kingsoft Cloud KS3, Upyun.
|
||||
- :outbox_tray: Upload/Download in directly transmission from client to storage providers.
|
||||
- 💾 Integrate with Aria2/qBittorrent to download files in background, use multiple download nodes to share the load.
|
||||
- 📚 Compress/Extract/Preview archived files, download files in batch.
|
||||
- 💻 WebDAV support covering all storage providers.
|
||||
- :zap:Drag&Drop to upload files or folders, with parallel resumable upload support.
|
||||
- :card_file_box: Extract media metadata from files, search files by metadata or tags.
|
||||
- :family_woman_girl_boy: Multi-users with multi-groups.
|
||||
- :link: Create share links for files and folders with expiration date.
|
||||
- :eye_speech_bubble: Preview videos, images, audios, ePub files online; edit texts, diagrams, Markdown, images, Office documents online.
|
||||
- :art: Customize theme colors, dark mode, PWA application, SPA, i18n.
|
||||
- :rocket: All-in-one packaging, with all features out of the box.
|
||||
- 🌈 ... ...
|
||||
|
||||
## :hammer_and_wrench: Deploy
|
||||
|
||||
Download the main binary for your target machine OS, CPU architecture and run it directly.
|
||||
To deploy Cloudreve, you can refer to [Getting started](https://docs.cloudreve.org/overview/quickstart) for a quick local deployment to test.
|
||||
|
||||
```shell
|
||||
# Extract Cloudreve binary
|
||||
tar -zxvf cloudreve_VERSION_OS_ARCH.tar.gz
|
||||
|
||||
# Grant execute permission
|
||||
chmod +x ./cloudreve
|
||||
|
||||
# Start Cloudreve
|
||||
./cloudreve
|
||||
```
|
||||
|
||||
The above is a minimum deploy example, you can refer to [Getting started](https://docs.cloudreve.org/v/en/getting-started/install) for a completed deployment.
|
||||
When you're ready to deploy Cloudreve to a production environment, you can refer to [Deploy](https://docs.cloudreve.org/overview/deploy/) for a complete deployment.
|
||||
|
||||
## :gear: Build
|
||||
|
||||
You need to have `Go >= 1.18`, `node.js`, `yarn`, `zip`, [goreleaser](https://goreleaser.com/intro/) and other necessary dependencies before you can build it yourself.
|
||||
Please refer to [Build](https://docs.cloudreve.org/overview/build/) for how to build Cloudreve from source code.
|
||||
|
||||
#### Install goreleaser
|
||||
## :rocket: Contributing
|
||||
|
||||
```shell
|
||||
go install github.com/goreleaser/goreleaser@latest
|
||||
```
|
||||
|
||||
#### Clone the code
|
||||
|
||||
```shell
|
||||
git clone --recurse-submodules https://github.com/cloudreve/Cloudreve.git
|
||||
```
|
||||
|
||||
#### Compile
|
||||
|
||||
```shell
|
||||
goreleaser build --clean --single-target --snapshot
|
||||
```
|
||||
If you're interested in contributing to Cloudreve, please refer to [Contributing](https://docs.cloudreve.org/api/contributing/) for how to contribute to Cloudreve.
|
||||
|
||||
## :alembic: Stacks
|
||||
|
||||
* [Go](https://golang.org/) + [Gin](https://github.com/gin-gonic/gin)
|
||||
* [React](https://github.com/facebook/react) + [Redux](https://github.com/reduxjs/redux) + [Material-UI](https://github.com/mui-org/material-ui)
|
||||
- [Go](https://golang.org/) + [Gin](https://github.com/gin-gonic/gin) + [ent](https://github.com/ent/ent)
|
||||
- [React](https://github.com/facebook/react) + [Redux](https://github.com/reduxjs/redux) + [Material-UI](https://github.com/mui-org/material-ui)
|
||||
|
||||
## :scroll: License
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[English Version](https://github.com/cloudreve/Cloudreve/blob/master/README.md)
|
||||
[English Version](https://github.com/cloudreve/cloudreve/blob/master/README.md)
|
||||
|
||||
<h1 align="center">
|
||||
<br>
|
||||
@@ -11,93 +11,66 @@
|
||||
<h4 align="center">支持多家云存储驱动的公有云文件系统.</h4>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/cloudreve/Cloudreve/actions/workflows/test.yml">
|
||||
<img src="https://img.shields.io/github/actions/workflow/status/cloudreve/Cloudreve/test.yml?branch=master&style=flat-square"
|
||||
alt="GitHub Test Workflow">
|
||||
<a href="https://dev.azure.com/abslantliu/cloudreve/_build?definitionId=6">
|
||||
<img src="https://img.shields.io/github/check-runs/cloudreve/cloudreve/master"
|
||||
alt="Azure pipelines">
|
||||
</a>
|
||||
<a href="https://codecov.io/gh/cloudreve/Cloudreve"><img src="https://img.shields.io/codecov/c/github/cloudreve/Cloudreve?style=flat-square"></a>
|
||||
<a href="https://goreportcard.com/report/github.com/cloudreve/Cloudreve">
|
||||
<img src="https://goreportcard.com/badge/github.com/cloudreve/Cloudreve?style=flat-square">
|
||||
<a href="https://github.com/cloudreve/cloudreve/releases">
|
||||
<img src="https://img.shields.io/github/v/release/cloudreve/cloudreve?include_prereleases" />
|
||||
</a>
|
||||
<a href="https://github.com/cloudreve/Cloudreve/releases">
|
||||
<img src="https://img.shields.io/github/v/release/cloudreve/Cloudreve?include_prereleases&style=flat-square" />
|
||||
<a href="https://github.com/cloudreve/cloudreve/releases">
|
||||
<img src="https://badgen.net/static/release%20size/34%20MB/blue"/>
|
||||
</a>
|
||||
<a href="https://hub.docker.com/r/cloudreve/cloudreve">
|
||||
<img src="https://img.shields.io/docker/image-size/cloudreve/cloudreve?style=flat-square"/>
|
||||
<img alt="Docker Pulls" src="https://img.shields.io/docker/pulls/cloudreve/cloudreve" />
|
||||
</a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://cloudreve.org">主页</a> •
|
||||
<a href="https://demo.cloudreve.org">演示站</a> •
|
||||
<a href="https://forum.cloudreve.org/">讨论社区</a> •
|
||||
<a href="https://docs.cloudreve.org/">文档</a> •
|
||||
<a href="https://github.com/cloudreve/Cloudreve/releases">下载</a> •
|
||||
<a href="https://t.me/cloudreve_official">Telegram 群组</a> •
|
||||
<a href="#scroll-许可证">许可证</a>
|
||||
<a href="https://demo.cloudreve.org">演示</a> •
|
||||
<a href="https://github.com/cloudreve/cloudreve/discussions">讨论</a> •
|
||||
<a href="https://docs.cloudreve.org">文档</a> •
|
||||
<a href="https://github.com/cloudreve/cloudreve/releases">下载</a> •
|
||||
<a href="https://t.me/cloudreve_official">Telegram</a> •
|
||||
<a href="https://discord.com/invite/WTpMFpZT76">Discord</a>
|
||||
</p>
|
||||
|
||||
|
||||

|
||||
|
||||
## :sparkles: 特性
|
||||
|
||||
* :cloud: 支持本机、从机、七牛、阿里云 OSS、腾讯云 COS、又拍云、OneDrive (包括世纪互联版) 、S3兼容协议 作为存储端
|
||||
* :outbox_tray: 上传/下载 支持客户端直传,支持下载限速
|
||||
* 💾 可对接 Aria2 离线下载,可使用多个从机节点分担下载任务
|
||||
* 📚 在线 压缩/解压缩、多文件打包下载
|
||||
* 💻 覆盖全部存储策略的 WebDAV 协议支持
|
||||
* :zap: 拖拽上传、目录上传、流式上传处理
|
||||
* :card_file_box: 文件拖拽管理
|
||||
* :family_woman_girl_boy: 多用户、用户组、多存储策略
|
||||
* :link: 创建文件、目录的分享链接,可设定自动过期
|
||||
* :eye_speech_bubble: 视频、图像、音频、 ePub 在线预览,文本、Office 文档在线编辑
|
||||
* :art: 自定义配色、黑暗模式、PWA 应用、全站单页应用、国际化支持
|
||||
* :rocket: All-In-One 打包,开箱即用
|
||||
* 🌈 ... ...
|
||||
- :cloud: 支持本机、从机、七牛 Kodo、阿里云 OSS、腾讯云 COS、华为云 OBS、金山云 KS3、又拍云、OneDrive (包括世纪互联版) 、S3 兼容协议 作为存储端
|
||||
- :outbox_tray: 上传/下载 支持客户端直传,支持下载限速
|
||||
- 💾 可对接 Aria2/qBittorrent 离线下载,可使用多个从机节点分担下载任务
|
||||
- 📚 在线 压缩/解压缩/压缩包预览、多文件打包下载
|
||||
- 💻 覆盖全部存储策略的 WebDAV 协议支持
|
||||
- :zap: 拖拽上传、目录上传、并行分片上传
|
||||
- :card_file_box: 提取媒体元数据,通过元数据或标签搜索文件
|
||||
- :family_woman_girl_boy: 多用户、用户组、多存储策略
|
||||
- :link: 创建文件、目录的分享链接,可设定自动过期
|
||||
- :eye_speech_bubble: 视频、图像、音频、 ePub 在线预览,文本、Office 文档在线编辑
|
||||
- :art: 自定义配色、黑暗模式、PWA 应用、全站单页应用、国际化支持
|
||||
- :rocket: All-in-One 打包,开箱即用
|
||||
- 🌈 ... ...
|
||||
|
||||
## :hammer_and_wrench: 部署
|
||||
|
||||
下载适用于您目标机器操作系统、CPU架构的主程序,直接运行即可。
|
||||
你可以参考 [快速开始](https://docs.cloudreve.org/overview/quickstart) 启动一个本地实例进行体验、测试。
|
||||
|
||||
```shell
|
||||
# 解压程序包
|
||||
tar -zxvf cloudreve_VERSION_OS_ARCH.tar.gz
|
||||
|
||||
# 赋予执行权限
|
||||
chmod +x ./cloudreve
|
||||
|
||||
# 启动 Cloudreve
|
||||
./cloudreve
|
||||
```
|
||||
|
||||
以上为最简单的部署示例,您可以参考 [文档 - 起步](https://docs.cloudreve.org/) 进行更为完善的部署。
|
||||
当你准备好将 Cloudreve 部署到生产环境时,可以参考 [部署](https://docs.cloudreve.org/overview/deploy/) 进行完整部署。
|
||||
|
||||
## :gear: 构建
|
||||
|
||||
自行构建前需要拥有 `Go >= 1.18`、`node.js`、`yarn`、`zip`, [goreleaser](https://goreleaser.com/intro/) 等必要依赖。
|
||||
你可以参考 [构建](https://docs.cloudreve.org/overview/build/) 从源代码构建 Cloudreve。
|
||||
|
||||
#### 安装 goreleaser
|
||||
## :rocket: 贡献
|
||||
|
||||
```shell
|
||||
go install github.com/goreleaser/goreleaser@latest
|
||||
```
|
||||
|
||||
#### 克隆代码
|
||||
|
||||
```shell
|
||||
git clone --recurse-submodules https://github.com/cloudreve/Cloudreve.git
|
||||
```
|
||||
|
||||
#### 编译项目
|
||||
|
||||
```shell
|
||||
goreleaser build --clean --single-target --snapshot
|
||||
```
|
||||
如果你有兴趣为 Cloudreve 贡献代码,请参考 [贡献](https://docs.cloudreve.org/api/contributing/) 了解如何贡献。
|
||||
|
||||
## :alembic: 技术栈
|
||||
|
||||
* [Go](https://golang.org/) + [Gin](https://github.com/gin-gonic/gin)
|
||||
* [React](https://github.com/facebook/react) + [Redux](https://github.com/reduxjs/redux) + [Material-UI](https://github.com/mui-org/material-ui)
|
||||
- [Go](https://golang.org/) + [Gin](https://github.com/gin-gonic/gin) + [ent](https://github.com/ent/ent)
|
||||
- [React](https://github.com/facebook/react) + [Redux](https://github.com/reduxjs/redux) + [Material-UI](https://github.com/mui-org/material-ui)
|
||||
|
||||
## :scroll: 许可证
|
||||
|
||||
|
||||
12
SECURITY.md
Normal file
12
SECURITY.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
* For security issues with high-impacts (e.g. related to payments or user permission), we support 3.8.x and all 4.x version. But the fix for 4.x will released only in latest sub-version.
|
||||
* For all other security issues, we mainly support version >= 4.x (in which `x` is the latest stable sub-version).
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please send the details about the security issue to `support@cloudreve.org`. Once the vulnerability is comfirmed or fixed, you will get updates from the email thread.
|
||||
|
||||
We will reward you with bounty/swag for success submission of securty issues.
|
||||
247
application/application.go
Normal file
247
application/application.go
Normal file
@@ -0,0 +1,247 @@
|
||||
package application
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
_ "net/http/pprof"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/application/constants"
|
||||
"github.com/cloudreve/Cloudreve/v4/application/dependency"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/cache"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/conf"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/crontab"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/email"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/driver/onedrive"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/logging"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/setting"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/util"
|
||||
"github.com/cloudreve/Cloudreve/v4/routers"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type Server interface {
|
||||
// Start starts the Cloudreve server.
|
||||
Start() error
|
||||
PrintBanner()
|
||||
Close()
|
||||
}
|
||||
|
||||
// NewServer constructs a new Cloudreve server instance with given dependency.
|
||||
func NewServer(dep dependency.Dep) Server {
|
||||
return &server{
|
||||
dep: dep,
|
||||
logger: dep.Logger(),
|
||||
config: dep.ConfigProvider(),
|
||||
}
|
||||
}
|
||||
|
||||
type server struct {
|
||||
dep dependency.Dep
|
||||
logger logging.Logger
|
||||
dbClient *ent.Client
|
||||
config conf.ConfigProvider
|
||||
server *http.Server
|
||||
pprofServer *http.Server
|
||||
kv cache.Driver
|
||||
mailQueue email.Driver
|
||||
}
|
||||
|
||||
func (s *server) PrintBanner() {
|
||||
fmt.Print(`
|
||||
___ _ _
|
||||
/ __\ | ___ _ _ __| |_ __ _____ _____
|
||||
/ / | |/ _ \| | | |/ _ | '__/ _ \ \ / / _ \
|
||||
/ /___| | (_) | |_| | (_| | | | __/\ V / __/
|
||||
\____/|_|\___/ \__,_|\__,_|_| \___| \_/ \___|
|
||||
|
||||
V` + constants.BackendVersion + ` Commit #` + constants.LastCommit + ` Pro=` + constants.IsPro + `
|
||||
================================================
|
||||
|
||||
`)
|
||||
}
|
||||
|
||||
func (s *server) Start() error {
|
||||
// Debug 关闭时,切换为生产模式
|
||||
if !s.config.System().Debug {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
}
|
||||
|
||||
s.kv = s.dep.KV()
|
||||
// delete all cached settings
|
||||
_ = s.kv.Delete(setting.KvSettingPrefix)
|
||||
if memKv, ok := s.kv.(*cache.MemoStore); ok {
|
||||
memKv.GarbageCollect(s.logger)
|
||||
}
|
||||
|
||||
// TODO: make sure redis is connected in dep before user traffic.
|
||||
if s.config.System().Mode == conf.MasterMode {
|
||||
s.dbClient = s.dep.DBClient()
|
||||
// TODO: make sure all dep is initialized before server start.
|
||||
s.dep.LockSystem()
|
||||
s.dep.UAParser()
|
||||
|
||||
// Initialize OneDrive credentials
|
||||
credentials, err := onedrive.RetrieveOneDriveCredentials(context.Background(), s.dep.StoragePolicyClient())
|
||||
if err != nil {
|
||||
return fmt.Errorf("faield to retrieve OneDrive credentials for CredManager: %w", err)
|
||||
}
|
||||
if err := s.dep.CredManager().Upsert(context.Background(), credentials...); err != nil {
|
||||
return fmt.Errorf("failed to upsert OneDrive credentials to CredManager: %w", err)
|
||||
}
|
||||
crontab.Register(setting.CronTypeOauthCredRefresh, func(ctx context.Context) {
|
||||
dep := dependency.FromContext(ctx)
|
||||
cred := dep.CredManager()
|
||||
cred.RefreshAll(ctx)
|
||||
})
|
||||
|
||||
// Initialize email queue before user traffic starts.
|
||||
_ = s.dep.EmailClient(context.Background())
|
||||
|
||||
// Start all queues
|
||||
s.dep.MediaMetaQueue(context.Background()).Start()
|
||||
s.dep.EntityRecycleQueue(context.Background()).Start()
|
||||
s.dep.IoIntenseQueue(context.Background()).Start()
|
||||
s.dep.RemoteDownloadQueue(context.Background()).Start()
|
||||
|
||||
// Start cron jobs
|
||||
c, err := crontab.NewCron(context.Background(), s.dep)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Start()
|
||||
|
||||
// Start node pool
|
||||
if _, err := s.dep.NodePool(context.Background()); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
s.dep.SlaveQueue(context.Background()).Start()
|
||||
}
|
||||
s.dep.ThumbQueue(context.Background()).Start()
|
||||
|
||||
api := routers.InitRouter(s.dep)
|
||||
api.TrustedPlatform = s.config.System().ProxyHeader
|
||||
s.server = &http.Server{Handler: api}
|
||||
|
||||
// Start pprof server if configured
|
||||
if pprofAddr := s.config.System().Pprof; pprofAddr != "" {
|
||||
s.pprofServer = &http.Server{
|
||||
Addr: pprofAddr,
|
||||
Handler: http.DefaultServeMux,
|
||||
}
|
||||
go func() {
|
||||
s.logger.Info("pprof server listening on %q", pprofAddr)
|
||||
if err := s.pprofServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
s.logger.Error("pprof server error: %s", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// 如果启用了SSL
|
||||
if s.config.SSL().CertPath != "" {
|
||||
s.logger.Info("Listening to %q", s.config.SSL().Listen)
|
||||
s.server.Addr = s.config.SSL().Listen
|
||||
if err := s.server.ListenAndServeTLS(s.config.SSL().CertPath, s.config.SSL().KeyPath); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
return fmt.Errorf("failed to listen to %q: %w", s.config.SSL().Listen, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 如果启用了Unix
|
||||
if s.config.Unix().Listen != "" {
|
||||
// delete socket file before listening
|
||||
if _, err := os.Stat(s.config.Unix().Listen); err == nil {
|
||||
if err = os.Remove(s.config.Unix().Listen); err != nil {
|
||||
return fmt.Errorf("failed to delete socket file %q: %w", s.config.Unix().Listen, err)
|
||||
}
|
||||
}
|
||||
|
||||
s.logger.Info("Listening to %q", s.config.Unix().Listen)
|
||||
if err := s.runUnix(s.server); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
return fmt.Errorf("failed to listen to %q: %w", s.config.Unix().Listen, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
s.logger.Info("Listening to %q", s.config.System().Listen)
|
||||
s.server.Addr = s.config.System().Listen
|
||||
if err := s.server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
return fmt.Errorf("failed to listen to %q: %w", s.config.System().Listen, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *server) Close() {
|
||||
if s.dbClient != nil {
|
||||
s.logger.Info("Shutting down database connection...")
|
||||
if err := s.dbClient.Close(); err != nil {
|
||||
s.logger.Error("Failed to close database connection: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
if conf.SystemConfig.GracePeriod != 0 {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithTimeout(ctx, time.Duration(s.config.System().GracePeriod)*time.Second)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
s.dep.EventHub().Close()
|
||||
|
||||
// Shutdown http server
|
||||
if s.server != nil {
|
||||
err := s.server.Shutdown(ctx)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to shutdown server: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Shutdown pprof server
|
||||
if s.pprofServer != nil {
|
||||
if err := s.pprofServer.Shutdown(ctx); err != nil {
|
||||
s.logger.Error("Failed to shutdown pprof server: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if s.kv != nil {
|
||||
if err := s.kv.Persist(util.DataPath(cache.DefaultCacheFile)); err != nil {
|
||||
s.logger.Warning("Failed to persist cache: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.dep.Shutdown(ctx); err != nil {
|
||||
s.logger.Warning("Failed to shutdown dependency manager: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *server) runUnix(server *http.Server) error {
|
||||
listener, err := net.Listen("unix", s.config.Unix().Listen)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer listener.Close()
|
||||
defer os.Remove(s.config.Unix().Listen)
|
||||
|
||||
if conf.UnixConfig.Perm > 0 {
|
||||
err = os.Chmod(conf.UnixConfig.Listen, os.FileMode(s.config.Unix().Perm))
|
||||
if err != nil {
|
||||
s.logger.Warning(
|
||||
"Failed to set permission to %q for socket file %q: %s",
|
||||
s.config.Unix().Perm,
|
||||
s.config.Unix().Listen,
|
||||
err,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return server.Serve(listener)
|
||||
}
|
||||
34
application/constants/constants.go
Normal file
34
application/constants/constants.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package constants
|
||||
|
||||
// These values will be injected at build time, DO NOT EDIT.
|
||||
|
||||
// BackendVersion 当前后端版本号
|
||||
var BackendVersion = "4.14.0"
|
||||
|
||||
// IsPro 是否为Pro版本
|
||||
var IsPro = "false"
|
||||
|
||||
var IsProBool = IsPro == "true"
|
||||
|
||||
// LastCommit 最后commit id
|
||||
var LastCommit = "000000"
|
||||
|
||||
const (
|
||||
APIPrefix = "/api/v4"
|
||||
APIPrefixSlave = "/api/v4/slave"
|
||||
CrHeaderPrefix = "X-Cr-"
|
||||
)
|
||||
|
||||
const CloudreveScheme = "cloudreve"
|
||||
|
||||
type (
|
||||
FileSystemType string
|
||||
)
|
||||
|
||||
const (
|
||||
FileSystemMy = FileSystemType("my")
|
||||
FileSystemShare = FileSystemType("share")
|
||||
FileSystemTrash = FileSystemType("trash")
|
||||
FileSystemSharedWithMe = FileSystemType("shared_with_me")
|
||||
FileSystemUnknown = FileSystemType("unknown")
|
||||
)
|
||||
8
application/constants/size.go
Normal file
8
application/constants/size.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package constants
|
||||
|
||||
const (
|
||||
MB = 1 << 20
|
||||
GB = 1 << 30
|
||||
TB = 1 << 40
|
||||
PB = 1 << 50
|
||||
)
|
||||
1011
application/dependency/dependency.go
Normal file
1011
application/dependency/dependency.go
Normal file
File diff suppressed because it is too large
Load Diff
175
application/dependency/options.go
Normal file
175
application/dependency/options.go
Normal file
@@ -0,0 +1,175 @@
|
||||
package dependency
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/ent"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/auth"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/cache"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/conf"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/email"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/hashid"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/logging"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/searcher"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/setting"
|
||||
"github.com/gin-contrib/static"
|
||||
)
|
||||
|
||||
// Option 发送请求的额外设置
|
||||
type Option interface {
|
||||
apply(*dependency)
|
||||
}
|
||||
|
||||
type optionFunc func(*dependency)
|
||||
|
||||
func (f optionFunc) apply(o *dependency) {
|
||||
f(o)
|
||||
}
|
||||
|
||||
// WithConfigPath Set the path of the config file.
|
||||
func WithConfigPath(p string) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.configPath = p
|
||||
})
|
||||
}
|
||||
|
||||
// WithLogger Set the default logging.
|
||||
func WithLogger(l logging.Logger) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.logger = l
|
||||
})
|
||||
}
|
||||
|
||||
// WithConfigProvider Set the default config provider.
|
||||
func WithConfigProvider(c conf.ConfigProvider) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.configProvider = c
|
||||
})
|
||||
}
|
||||
|
||||
// WithStatics Set the default statics FS.
|
||||
func WithStatics(c fs.FS) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.statics = c
|
||||
})
|
||||
}
|
||||
|
||||
// WithServerStaticFS Set the default statics FS for server.
|
||||
func WithServerStaticFS(c static.ServeFileSystem) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.serverStaticFS = c
|
||||
})
|
||||
}
|
||||
|
||||
// WithProFlag Set if current instance is a pro version.
|
||||
func WithProFlag(c bool) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.isPro = c
|
||||
})
|
||||
}
|
||||
|
||||
// WithRawEntClient Set the default raw ent client.
|
||||
func WithRawEntClient(c *ent.Client) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.rawEntClient = c
|
||||
})
|
||||
}
|
||||
|
||||
// WithDbClient Set the default ent client.
|
||||
func WithDbClient(c *ent.Client) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.dbClient = c
|
||||
})
|
||||
}
|
||||
|
||||
// WithRequiredDbVersion Set the required db version.
|
||||
func WithRequiredDbVersion(c string) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.requiredDbVersion = c
|
||||
})
|
||||
}
|
||||
|
||||
// WithKV Set the default KV store driverold
|
||||
func WithKV(c cache.Driver) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.kv = c
|
||||
})
|
||||
}
|
||||
|
||||
// WithSettingClient Set the default setting client
|
||||
func WithSettingClient(s inventory.SettingClient) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.settingClient = s
|
||||
})
|
||||
}
|
||||
|
||||
// WithSettingProvider Set the default setting provider
|
||||
func WithSettingProvider(s setting.Provider) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.settingProvider = s
|
||||
})
|
||||
}
|
||||
|
||||
// WithUserClient Set the default user client
|
||||
func WithUserClient(s inventory.UserClient) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.userClient = s
|
||||
})
|
||||
}
|
||||
|
||||
// WithEmailClient Set the default email client
|
||||
func WithEmailClient(s email.Driver) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.emailClient = s
|
||||
})
|
||||
}
|
||||
|
||||
// WithGeneralAuth Set the default general auth
|
||||
func WithGeneralAuth(s auth.Auth) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.generalAuth = s
|
||||
})
|
||||
}
|
||||
|
||||
// WithHashIDEncoder Set the default hash id encoder
|
||||
func WithHashIDEncoder(s hashid.Encoder) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.hashidEncoder = s
|
||||
})
|
||||
}
|
||||
|
||||
// WithTokenAuth Set the default token auth
|
||||
func WithTokenAuth(s auth.TokenAuth) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.tokenAuth = s
|
||||
})
|
||||
}
|
||||
|
||||
// WithFileClient Set the default file client
|
||||
func WithFileClient(s inventory.FileClient) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.fileClient = s
|
||||
})
|
||||
}
|
||||
|
||||
// WithShareClient Set the default share client
|
||||
func WithShareClient(s inventory.ShareClient) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.shareClient = s
|
||||
})
|
||||
}
|
||||
|
||||
// WithSearchIndexer Set the default search indexer
|
||||
func WithSearchIndexer(s searcher.SearchIndexer) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.searchIndexer = s
|
||||
})
|
||||
}
|
||||
|
||||
// WithTextExtractor Set the default text extractor
|
||||
func WithTextExtractor(s searcher.TextExtractor) Option {
|
||||
return optionFunc(func(o *dependency) {
|
||||
o.textExtractor = s
|
||||
})
|
||||
}
|
||||
47
application/migrator/avatars.go
Normal file
47
application/migrator/avatars.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package migrator
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/util"
|
||||
)
|
||||
|
||||
func migrateAvatars(m *Migrator) error {
|
||||
m.l.Info("Migrating avatars files...")
|
||||
avatarRoot := util.RelativePath(m.state.V3AvatarPath)
|
||||
|
||||
for uid, _ := range m.state.UserIDs {
|
||||
avatarPath := filepath.Join(avatarRoot, fmt.Sprintf("avatar_%d_2.png", uid))
|
||||
|
||||
// check if file exists
|
||||
if util.Exists(avatarPath) {
|
||||
m.l.Info("Migrating avatar for user %d", uid)
|
||||
// Copy to v4 avatar path
|
||||
v4Path := filepath.Join(util.DataPath("avatar"), fmt.Sprintf("avatar_%d.png", uid))
|
||||
|
||||
// copy
|
||||
origin, err := os.Open(avatarPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open avatar file: %w", err)
|
||||
}
|
||||
defer origin.Close()
|
||||
|
||||
dest, err := util.CreatNestedFile(v4Path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create avatar file: %w", err)
|
||||
}
|
||||
defer dest.Close()
|
||||
|
||||
_, err = io.Copy(dest, origin)
|
||||
|
||||
if err != nil {
|
||||
m.l.Warning("Failed to copy avatar file: %s, skipping...", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
124
application/migrator/conf/conf.go
Normal file
124
application/migrator/conf/conf.go
Normal file
@@ -0,0 +1,124 @@
|
||||
package conf
|
||||
|
||||
import (
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/logging"
|
||||
"github.com/go-ini/ini"
|
||||
"github.com/go-playground/validator/v10"
|
||||
)
|
||||
|
||||
// database 数据库
|
||||
type database struct {
|
||||
Type string
|
||||
User string
|
||||
Password string
|
||||
Host string
|
||||
Name string
|
||||
TablePrefix string
|
||||
DBFile string
|
||||
Port int
|
||||
Charset string
|
||||
UnixSocket bool
|
||||
}
|
||||
|
||||
// system 系统通用配置
|
||||
type system struct {
|
||||
Mode string `validate:"eq=master|eq=slave"`
|
||||
Listen string `validate:"required"`
|
||||
Debug bool
|
||||
SessionSecret string
|
||||
HashIDSalt string
|
||||
GracePeriod int `validate:"gte=0"`
|
||||
ProxyHeader string
|
||||
}
|
||||
|
||||
type ssl struct {
|
||||
CertPath string `validate:"omitempty,required"`
|
||||
KeyPath string `validate:"omitempty,required"`
|
||||
Listen string `validate:"required"`
|
||||
}
|
||||
|
||||
type unix struct {
|
||||
Listen string
|
||||
Perm uint32
|
||||
}
|
||||
|
||||
// slave 作为slave存储端配置
|
||||
type slave struct {
|
||||
Secret string `validate:"omitempty,gte=64"`
|
||||
CallbackTimeout int `validate:"omitempty,gte=1"`
|
||||
SignatureTTL int `validate:"omitempty,gte=1"`
|
||||
}
|
||||
|
||||
// redis 配置
|
||||
type redis struct {
|
||||
Network string
|
||||
Server string
|
||||
User string
|
||||
Password string
|
||||
DB string
|
||||
}
|
||||
|
||||
// 跨域配置
|
||||
type cors struct {
|
||||
AllowOrigins []string
|
||||
AllowMethods []string
|
||||
AllowHeaders []string
|
||||
AllowCredentials bool
|
||||
ExposeHeaders []string
|
||||
SameSite string
|
||||
Secure bool
|
||||
}
|
||||
|
||||
var cfg *ini.File
|
||||
|
||||
// Init 初始化配置文件
|
||||
func Init(l logging.Logger, path string) error {
|
||||
var err error
|
||||
|
||||
cfg, err = ini.Load(path)
|
||||
if err != nil {
|
||||
l.Error("Failed to parse config file %q: %s", path, err)
|
||||
return err
|
||||
}
|
||||
|
||||
sections := map[string]interface{}{
|
||||
"Database": DatabaseConfig,
|
||||
"System": SystemConfig,
|
||||
"SSL": SSLConfig,
|
||||
"UnixSocket": UnixConfig,
|
||||
"Redis": RedisConfig,
|
||||
"CORS": CORSConfig,
|
||||
"Slave": SlaveConfig,
|
||||
}
|
||||
for sectionName, sectionStruct := range sections {
|
||||
err = mapSection(sectionName, sectionStruct)
|
||||
if err != nil {
|
||||
l.Error("Failed to parse config section %q: %s", sectionName, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// 映射数据库配置覆盖
|
||||
for _, key := range cfg.Section("OptionOverwrite").Keys() {
|
||||
OptionOverwrite[key.Name()] = key.Value()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// mapSection 将配置文件的 Section 映射到结构体上
|
||||
func mapSection(section string, confStruct interface{}) error {
|
||||
err := cfg.Section(section).MapTo(confStruct)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 验证合法性
|
||||
validate := validator.New()
|
||||
err = validate.Struct(confStruct)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -22,7 +22,7 @@ var SystemConfig = &system{
|
||||
Debug: false,
|
||||
Mode: "master",
|
||||
Listen: ":5212",
|
||||
ProxyHeader: "X-Forwarded-For",
|
||||
ProxyHeader: "",
|
||||
}
|
||||
|
||||
// CORSConfig 跨域配置
|
||||
82
application/migrator/directlink.go
Normal file
82
application/migrator/directlink.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package migrator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/application/migrator/model"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/file"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/conf"
|
||||
)
|
||||
|
||||
func (m *Migrator) migrateDirectLink() error {
|
||||
m.l.Info("Migrating direct links...")
|
||||
batchSize := 1000
|
||||
offset := m.state.DirectLinkOffset
|
||||
ctx := context.Background()
|
||||
|
||||
if m.state.DirectLinkOffset > 0 {
|
||||
m.l.Info("Resuming direct link migration from offset %d", offset)
|
||||
}
|
||||
|
||||
for {
|
||||
m.l.Info("Migrating direct links with offset %d", offset)
|
||||
var directLinks []model.SourceLink
|
||||
if err := model.DB.Limit(batchSize).Offset(offset).Find(&directLinks).Error; err != nil {
|
||||
return fmt.Errorf("failed to list v3 direct links: %w", err)
|
||||
}
|
||||
|
||||
if len(directLinks) == 0 {
|
||||
if m.dep.ConfigProvider().Database().Type == conf.PostgresDB {
|
||||
m.l.Info("Resetting direct link ID sequence for postgres...")
|
||||
m.v4client.DirectLink.ExecContext(ctx, "SELECT SETVAL('direct_links_id_seq', (SELECT MAX(id) FROM direct_links))")
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
tx, err := m.v4client.Tx(ctx)
|
||||
if err != nil {
|
||||
_ = tx.Rollback()
|
||||
return fmt.Errorf("failed to start transaction: %w", err)
|
||||
}
|
||||
|
||||
for _, dl := range directLinks {
|
||||
sourceId := int(dl.FileID) + m.state.LastFolderID
|
||||
// check if file exists
|
||||
_, err = tx.File.Query().Where(file.ID(sourceId)).First(ctx)
|
||||
if err != nil {
|
||||
m.l.Warning("File %d not found, skipping direct link %d", sourceId, dl.ID)
|
||||
continue
|
||||
}
|
||||
|
||||
stm := tx.DirectLink.Create().
|
||||
SetCreatedAt(formatTime(dl.CreatedAt)).
|
||||
SetUpdatedAt(formatTime(dl.UpdatedAt)).
|
||||
SetRawID(int(dl.ID)).
|
||||
SetFileID(sourceId).
|
||||
SetName(dl.Name).
|
||||
SetDownloads(dl.Downloads).
|
||||
SetSpeed(0)
|
||||
|
||||
if _, err := stm.Save(ctx); err != nil {
|
||||
_ = tx.Rollback()
|
||||
return fmt.Errorf("failed to create direct link %d: %w", dl.ID, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return fmt.Errorf("failed to commit transaction: %w", err)
|
||||
}
|
||||
|
||||
offset += batchSize
|
||||
m.state.DirectLinkOffset = offset
|
||||
if err := m.saveState(); err != nil {
|
||||
m.l.Warning("Failed to save state after direct link batch: %s", err)
|
||||
} else {
|
||||
m.l.Info("Saved migration state after processing this batch")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
189
application/migrator/file.go
Normal file
189
application/migrator/file.go
Normal file
@@ -0,0 +1,189 @@
|
||||
package migrator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/application/migrator/model"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/conf"
|
||||
)
|
||||
|
||||
func (m *Migrator) migrateFile() error {
|
||||
m.l.Info("Migrating files...")
|
||||
batchSize := 1000
|
||||
offset := m.state.FileOffset
|
||||
ctx := context.Background()
|
||||
|
||||
if m.state.FileConflictRename == nil {
|
||||
m.state.FileConflictRename = make(map[uint]string)
|
||||
}
|
||||
|
||||
if m.state.EntitySources == nil {
|
||||
m.state.EntitySources = make(map[string]int)
|
||||
}
|
||||
|
||||
if offset > 0 {
|
||||
m.l.Info("Resuming file migration from offset %d", offset)
|
||||
}
|
||||
|
||||
out:
|
||||
for {
|
||||
m.l.Info("Migrating files with offset %d", offset)
|
||||
var files []model.File
|
||||
if err := model.DB.Limit(batchSize).Offset(offset).Find(&files).Error; err != nil {
|
||||
return fmt.Errorf("failed to list v3 files: %w", err)
|
||||
}
|
||||
|
||||
if len(files) == 0 {
|
||||
if m.dep.ConfigProvider().Database().Type == conf.PostgresDB {
|
||||
m.l.Info("Resetting file ID sequence for postgres...")
|
||||
m.v4client.File.ExecContext(ctx, "SELECT SETVAL('files_id_seq', (SELECT MAX(id) FROM files))")
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
tx, err := m.v4client.Tx(ctx)
|
||||
if err != nil {
|
||||
_ = tx.Rollback()
|
||||
return fmt.Errorf("failed to start transaction: %w", err)
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
if _, ok := m.state.FolderIDs[int(f.FolderID)]; !ok {
|
||||
m.l.Warning("Folder ID %d for file %d not found, skipping", f.FolderID, f.ID)
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := m.state.UserIDs[int(f.UserID)]; !ok {
|
||||
m.l.Warning("User ID %d for file %d not found, skipping", f.UserID, f.ID)
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := m.state.PolicyIDs[int(f.PolicyID)]; !ok {
|
||||
m.l.Warning("Policy ID %d for file %d not found, skipping", f.PolicyID, f.ID)
|
||||
continue
|
||||
}
|
||||
|
||||
metadata := make(map[string]string)
|
||||
if f.Metadata != "" {
|
||||
json.Unmarshal([]byte(f.Metadata), &metadata)
|
||||
}
|
||||
|
||||
var (
|
||||
thumbnail *ent.Entity
|
||||
entity *ent.Entity
|
||||
err error
|
||||
)
|
||||
|
||||
if metadata[model.ThumbStatusMetadataKey] == model.ThumbStatusExist {
|
||||
size := int64(0)
|
||||
if m.state.LocalPolicyIDs[int(f.PolicyID)] {
|
||||
thumbFile, err := os.Stat(f.SourceName + m.state.ThumbSuffix)
|
||||
if err == nil {
|
||||
size = thumbFile.Size()
|
||||
}
|
||||
m.l.Warning("Thumbnail file %s for file %d not found, use 0 size", f.SourceName+m.state.ThumbSuffix, f.ID)
|
||||
}
|
||||
// Insert thumbnail entity
|
||||
thumbnail, err = m.insertEntity(tx, f.SourceName+m.state.ThumbSuffix, int(types.EntityTypeThumbnail), int(f.PolicyID), int(f.UserID), size)
|
||||
if err != nil {
|
||||
_ = tx.Rollback()
|
||||
return fmt.Errorf("failed to insert thumbnail entity: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Insert file version entity
|
||||
entity, err = m.insertEntity(tx, f.SourceName, int(types.EntityTypeVersion), int(f.PolicyID), int(f.UserID), int64(f.Size))
|
||||
if err != nil {
|
||||
_ = tx.Rollback()
|
||||
return fmt.Errorf("failed to insert file version entity: %w", err)
|
||||
}
|
||||
|
||||
fname := f.Name
|
||||
if _, ok := m.state.FileConflictRename[f.ID]; ok {
|
||||
fname = m.state.FileConflictRename[f.ID]
|
||||
}
|
||||
|
||||
stm := tx.File.Create().
|
||||
SetCreatedAt(formatTime(f.CreatedAt)).
|
||||
SetUpdatedAt(formatTime(f.UpdatedAt)).
|
||||
SetName(fname).
|
||||
SetRawID(int(f.ID) + m.state.LastFolderID).
|
||||
SetOwnerID(int(f.UserID)).
|
||||
SetSize(int64(f.Size)).
|
||||
SetPrimaryEntity(entity.ID).
|
||||
SetFileChildren(int(f.FolderID)).
|
||||
SetType(int(types.FileTypeFile)).
|
||||
SetStoragePoliciesID(int(f.PolicyID)).
|
||||
AddEntities(entity)
|
||||
|
||||
if thumbnail != nil {
|
||||
stm.AddEntities(thumbnail)
|
||||
}
|
||||
|
||||
if _, err := stm.Save(ctx); err != nil {
|
||||
_ = tx.Rollback()
|
||||
if ent.IsConstraintError(err) {
|
||||
if _, ok := m.state.FileConflictRename[f.ID]; ok {
|
||||
return fmt.Errorf("file %d already exists, but new name is already in conflict rename map, please resolve this manually", f.ID)
|
||||
}
|
||||
|
||||
m.l.Warning("File %d already exists, will retry with new name in next batch", f.ID)
|
||||
m.state.FileConflictRename[f.ID] = fmt.Sprintf("%d_%s", f.ID, f.Name)
|
||||
continue out
|
||||
}
|
||||
return fmt.Errorf("failed to create file %d: %w", f.ID, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return fmt.Errorf("failed to commit transaction: %w", err)
|
||||
}
|
||||
|
||||
offset += batchSize
|
||||
m.state.FileOffset = offset
|
||||
if err := m.saveState(); err != nil {
|
||||
m.l.Warning("Failed to save state after file batch: %s", err)
|
||||
} else {
|
||||
m.l.Info("Saved migration state after processing this batch")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Migrator) insertEntity(tx *ent.Tx, source string, entityType, policyID, createdBy int, size int64) (*ent.Entity, error) {
|
||||
|
||||
// find existing one
|
||||
entityKey := strconv.Itoa(policyID) + "+" + source
|
||||
if existingId, ok := m.state.EntitySources[entityKey]; ok {
|
||||
existing, err := tx.Entity.UpdateOneID(existingId).
|
||||
AddReferenceCount(1).
|
||||
Save(context.Background())
|
||||
if err == nil {
|
||||
return existing, nil
|
||||
}
|
||||
m.l.Warning("Failed to update existing entity %d: %s, fallback to create new one.", existingId, err)
|
||||
}
|
||||
|
||||
// create new one
|
||||
e, err := tx.Entity.Create().
|
||||
SetSource(source).
|
||||
SetType(entityType).
|
||||
SetSize(size).
|
||||
SetStoragePolicyEntities(policyID).
|
||||
SetCreatedBy(createdBy).
|
||||
SetReferenceCount(1).
|
||||
Save(context.Background())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create new entity: %w", err)
|
||||
}
|
||||
|
||||
m.state.EntitySources[entityKey] = e.ID
|
||||
return e, nil
|
||||
}
|
||||
147
application/migrator/folders.go
Normal file
147
application/migrator/folders.go
Normal file
@@ -0,0 +1,147 @@
|
||||
package migrator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/application/migrator/model"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
)
|
||||
|
||||
func (m *Migrator) migrateFolders() error {
|
||||
m.l.Info("Migrating folders...")
|
||||
batchSize := 1000
|
||||
// Start from the saved offset if available
|
||||
offset := m.state.FolderOffset
|
||||
ctx := context.Background()
|
||||
foldersCount := 0
|
||||
|
||||
if m.state.FolderIDs == nil {
|
||||
m.state.FolderIDs = make(map[int]bool)
|
||||
}
|
||||
|
||||
if offset > 0 {
|
||||
m.l.Info("Resuming folder migration from offset %d", offset)
|
||||
}
|
||||
|
||||
for {
|
||||
m.l.Info("Migrating folders with offset %d", offset)
|
||||
var folders []model.Folder
|
||||
if err := model.DB.Limit(batchSize).Offset(offset).Find(&folders).Error; err != nil {
|
||||
return fmt.Errorf("failed to list v3 folders: %w", err)
|
||||
}
|
||||
|
||||
if len(folders) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
tx, err := m.v4client.Tx(ctx)
|
||||
if err != nil {
|
||||
_ = tx.Rollback()
|
||||
return fmt.Errorf("failed to start transaction: %w", err)
|
||||
}
|
||||
|
||||
batchFoldersCount := 0
|
||||
for _, f := range folders {
|
||||
if _, ok := m.state.UserIDs[int(f.OwnerID)]; !ok {
|
||||
m.l.Warning("Owner ID %d not found, skipping folder %d", f.OwnerID, f.ID)
|
||||
continue
|
||||
}
|
||||
|
||||
isRoot := f.ParentID == nil
|
||||
if isRoot {
|
||||
f.Name = ""
|
||||
} else if *f.ParentID == 0 {
|
||||
m.l.Warning("Parent ID %d not found, skipping folder %d", *f.ParentID, f.ID)
|
||||
continue
|
||||
}
|
||||
|
||||
stm := tx.File.Create().
|
||||
SetRawID(int(f.ID)).
|
||||
SetType(int(types.FileTypeFolder)).
|
||||
SetCreatedAt(formatTime(f.CreatedAt)).
|
||||
SetUpdatedAt(formatTime(f.UpdatedAt)).
|
||||
SetName(f.Name).
|
||||
SetOwnerID(int(f.OwnerID))
|
||||
|
||||
if _, err := stm.Save(ctx); err != nil {
|
||||
_ = tx.Rollback()
|
||||
return fmt.Errorf("failed to create folder %d: %w", f.ID, err)
|
||||
}
|
||||
|
||||
m.state.FolderIDs[int(f.ID)] = true
|
||||
m.state.LastFolderID = int(f.ID)
|
||||
|
||||
foldersCount++
|
||||
batchFoldersCount++
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return fmt.Errorf("failed to commit transaction: %w", err)
|
||||
}
|
||||
|
||||
// Update the offset in state and save after each batch
|
||||
offset += batchSize
|
||||
m.state.FolderOffset = offset
|
||||
if err := m.saveState(); err != nil {
|
||||
m.l.Warning("Failed to save state after folder batch: %s", err)
|
||||
} else {
|
||||
m.l.Info("Saved migration state after processing %d folders in this batch", batchFoldersCount)
|
||||
}
|
||||
}
|
||||
|
||||
m.l.Info("Successfully migrated %d folders", foldersCount)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Migrator) migrateFolderParent() error {
|
||||
m.l.Info("Migrating folder parent...")
|
||||
batchSize := 1000
|
||||
offset := m.state.FolderParentOffset
|
||||
ctx := context.Background()
|
||||
|
||||
for {
|
||||
m.l.Info("Migrating folder parent with offset %d", offset)
|
||||
var folderParents []model.Folder
|
||||
if err := model.DB.Limit(batchSize).Offset(offset).Find(&folderParents).Error; err != nil {
|
||||
return fmt.Errorf("failed to list v3 folder parents: %w", err)
|
||||
}
|
||||
|
||||
if len(folderParents) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
tx, err := m.v4client.Tx(ctx)
|
||||
if err != nil {
|
||||
_ = tx.Rollback()
|
||||
return fmt.Errorf("failed to start transaction: %w", err)
|
||||
}
|
||||
|
||||
for _, f := range folderParents {
|
||||
if f.ParentID != nil {
|
||||
if _, ok := m.state.FolderIDs[int(*f.ParentID)]; !ok {
|
||||
m.l.Warning("Folder ID %d not found, skipping folder parent %d", f.ID, f.ID)
|
||||
continue
|
||||
}
|
||||
|
||||
if _, err := tx.File.UpdateOneID(int(f.ID)).SetParentID(int(*f.ParentID)).Save(ctx); err != nil {
|
||||
_ = tx.Rollback()
|
||||
return fmt.Errorf("failed to update folder parent %d: %w", f.ID, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return fmt.Errorf("failed to commit transaction: %w", err)
|
||||
}
|
||||
|
||||
// Update the offset in state and save after each batch
|
||||
offset += batchSize
|
||||
m.state.FolderParentOffset = offset
|
||||
if err := m.saveState(); err != nil {
|
||||
m.l.Warning("Failed to save state after folder parent batch: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
92
application/migrator/group.go
Normal file
92
application/migrator/group.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package migrator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/application/migrator/model"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/boolset"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/conf"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
func (m *Migrator) migrateGroup() error {
|
||||
m.l.Info("Migrating groups...")
|
||||
|
||||
var groups []model.Group
|
||||
if err := model.DB.Find(&groups).Error; err != nil {
|
||||
return fmt.Errorf("failed to list v3 groups: %w", err)
|
||||
}
|
||||
|
||||
for _, group := range groups {
|
||||
cap := &boolset.BooleanSet{}
|
||||
var (
|
||||
opts model.GroupOption
|
||||
policies []int
|
||||
)
|
||||
if err := json.Unmarshal([]byte(group.Options), &opts); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal options for group %q: %w", group.Name, err)
|
||||
}
|
||||
|
||||
if err := json.Unmarshal([]byte(group.Policies), &policies); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal policies for group %q: %w", group.Name, err)
|
||||
}
|
||||
|
||||
policies = lo.Filter(policies, func(id int, _ int) bool {
|
||||
_, exist := m.state.PolicyIDs[id]
|
||||
return exist
|
||||
})
|
||||
|
||||
newOpts := &types.GroupSetting{
|
||||
CompressSize: int64(opts.CompressSize),
|
||||
DecompressSize: int64(opts.DecompressSize),
|
||||
RemoteDownloadOptions: opts.Aria2Options,
|
||||
SourceBatchSize: opts.SourceBatchSize,
|
||||
RedirectedSource: opts.RedirectedSource,
|
||||
Aria2BatchSize: opts.Aria2BatchSize,
|
||||
MaxWalkedFiles: 100000,
|
||||
TrashRetention: 7 * 24 * 3600,
|
||||
}
|
||||
|
||||
boolset.Sets(map[types.GroupPermission]bool{
|
||||
types.GroupPermissionIsAdmin: group.ID == 1,
|
||||
types.GroupPermissionIsAnonymous: group.ID == 3,
|
||||
types.GroupPermissionShareDownload: opts.ShareDownload,
|
||||
types.GroupPermissionWebDAV: group.WebDAVEnabled,
|
||||
types.GroupPermissionArchiveDownload: opts.ArchiveDownload,
|
||||
types.GroupPermissionArchiveTask: opts.ArchiveTask,
|
||||
types.GroupPermissionWebDAVProxy: opts.WebDAVProxy,
|
||||
types.GroupPermissionRemoteDownload: opts.Aria2,
|
||||
types.GroupPermissionAdvanceDelete: opts.AdvanceDelete,
|
||||
types.GroupPermissionShare: group.ShareEnabled,
|
||||
types.GroupPermissionRedirectedSource: opts.RedirectedSource,
|
||||
}, cap)
|
||||
|
||||
stm := m.v4client.Group.Create().
|
||||
SetRawID(int(group.ID)).
|
||||
SetCreatedAt(formatTime(group.CreatedAt)).
|
||||
SetUpdatedAt(formatTime(group.UpdatedAt)).
|
||||
SetName(group.Name).
|
||||
SetMaxStorage(int64(group.MaxStorage)).
|
||||
SetSpeedLimit(group.SpeedLimit).
|
||||
SetPermissions(cap).
|
||||
SetSettings(newOpts)
|
||||
|
||||
if len(policies) > 0 {
|
||||
stm.SetStoragePoliciesID(policies[0])
|
||||
}
|
||||
|
||||
if _, err := stm.Save(context.Background()); err != nil {
|
||||
return fmt.Errorf("failed to create group %q: %w", group.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
if m.dep.ConfigProvider().Database().Type == conf.PostgresDB {
|
||||
m.l.Info("Resetting group ID sequence for postgres...")
|
||||
m.v4client.Group.ExecContext(context.Background(), "SELECT SETVAL('groups_id_seq', (SELECT MAX(id) FROM groups))")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
314
application/migrator/migrator.go
Normal file
314
application/migrator/migrator.go
Normal file
@@ -0,0 +1,314 @@
|
||||
package migrator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/application/dependency"
|
||||
"github.com/cloudreve/Cloudreve/v4/application/migrator/conf"
|
||||
"github.com/cloudreve/Cloudreve/v4/application/migrator/model"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/logging"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/util"
|
||||
)
|
||||
|
||||
// State stores the migration progress
|
||||
type State struct {
|
||||
PolicyIDs map[int]bool `json:"policy_ids,omitempty"`
|
||||
LocalPolicyIDs map[int]bool `json:"local_policy_ids,omitempty"`
|
||||
UserIDs map[int]bool `json:"user_ids,omitempty"`
|
||||
FolderIDs map[int]bool `json:"folder_ids,omitempty"`
|
||||
EntitySources map[string]int `json:"entity_sources,omitempty"`
|
||||
LastFolderID int `json:"last_folder_id,omitempty"`
|
||||
Step int `json:"step,omitempty"`
|
||||
UserOffset int `json:"user_offset,omitempty"`
|
||||
FolderOffset int `json:"folder_offset,omitempty"`
|
||||
FileOffset int `json:"file_offset,omitempty"`
|
||||
ShareOffset int `json:"share_offset,omitempty"`
|
||||
GiftCodeOffset int `json:"gift_code_offset,omitempty"`
|
||||
DirectLinkOffset int `json:"direct_link_offset,omitempty"`
|
||||
WebdavOffset int `json:"webdav_offset,omitempty"`
|
||||
StoragePackOffset int `json:"storage_pack_offset,omitempty"`
|
||||
FileConflictRename map[uint]string `json:"file_conflict_rename,omitempty"`
|
||||
FolderParentOffset int `json:"folder_parent_offset,omitempty"`
|
||||
ThumbSuffix string `json:"thumb_suffix,omitempty"`
|
||||
V3AvatarPath string `json:"v3_avatar_path,omitempty"`
|
||||
}
|
||||
|
||||
// Step identifiers for migration phases
|
||||
const (
|
||||
StepInitial = 0
|
||||
StepSchema = 1
|
||||
StepSettings = 2
|
||||
StepNode = 3
|
||||
StepPolicy = 4
|
||||
StepGroup = 5
|
||||
StepUser = 6
|
||||
StepFolders = 7
|
||||
StepFolderParent = 8
|
||||
StepFile = 9
|
||||
StepShare = 10
|
||||
StepDirectLink = 11
|
||||
Step_CommunityPlaceholder1 = 12
|
||||
Step_CommunityPlaceholder2 = 13
|
||||
StepAvatar = 14
|
||||
StepWebdav = 15
|
||||
StepCompleted = 16
|
||||
StateFileName = "migration_state.json"
|
||||
)
|
||||
|
||||
type Migrator struct {
|
||||
dep dependency.Dep
|
||||
l logging.Logger
|
||||
v4client *ent.Client
|
||||
state *State
|
||||
statePath string
|
||||
}
|
||||
|
||||
func NewMigrator(dep dependency.Dep, v3ConfPath string) (*Migrator, error) {
|
||||
m := &Migrator{
|
||||
dep: dep,
|
||||
l: dep.Logger(),
|
||||
state: &State{
|
||||
PolicyIDs: make(map[int]bool),
|
||||
UserIDs: make(map[int]bool),
|
||||
Step: StepInitial,
|
||||
UserOffset: 0,
|
||||
FolderOffset: 0,
|
||||
},
|
||||
}
|
||||
|
||||
// Determine state file path
|
||||
configDir := filepath.Dir(v3ConfPath)
|
||||
m.statePath = filepath.Join(configDir, StateFileName)
|
||||
|
||||
// Try to load existing state
|
||||
if util.Exists(m.statePath) {
|
||||
m.l.Info("Found existing migration state file, loading from %s", m.statePath)
|
||||
if err := m.loadState(); err != nil {
|
||||
return nil, fmt.Errorf("failed to load migration state: %w", err)
|
||||
}
|
||||
|
||||
stepName := "unknown"
|
||||
switch m.state.Step {
|
||||
case StepInitial:
|
||||
stepName = "initial"
|
||||
case StepSchema:
|
||||
stepName = "schema creation"
|
||||
case StepSettings:
|
||||
stepName = "settings migration"
|
||||
case StepNode:
|
||||
stepName = "node migration"
|
||||
case StepPolicy:
|
||||
stepName = "policy migration"
|
||||
case StepGroup:
|
||||
stepName = "group migration"
|
||||
case StepUser:
|
||||
stepName = "user migration"
|
||||
case StepFolders:
|
||||
stepName = "folders migration"
|
||||
case StepCompleted:
|
||||
stepName = "completed"
|
||||
case StepWebdav:
|
||||
stepName = "webdav migration"
|
||||
case StepAvatar:
|
||||
stepName = "avatar migration"
|
||||
|
||||
}
|
||||
|
||||
m.l.Info("Resumed migration from step %d (%s)", m.state.Step, stepName)
|
||||
|
||||
// Log batch information if applicable
|
||||
if m.state.Step == StepUser && m.state.UserOffset > 0 {
|
||||
m.l.Info("Will resume user migration from batch offset %d", m.state.UserOffset)
|
||||
}
|
||||
if m.state.Step == StepFolders && m.state.FolderOffset > 0 {
|
||||
m.l.Info("Will resume folder migration from batch offset %d", m.state.FolderOffset)
|
||||
}
|
||||
}
|
||||
|
||||
err := conf.Init(m.dep.Logger(), v3ConfPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = model.Init()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
v4client, err := inventory.NewRawEntClient(m.l, m.dep.ConfigProvider())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m.v4client = v4client
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// saveState persists migration state to file
|
||||
func (m *Migrator) saveState() error {
|
||||
data, err := json.Marshal(m.state)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal state: %w", err)
|
||||
}
|
||||
|
||||
return os.WriteFile(m.statePath, data, 0644)
|
||||
}
|
||||
|
||||
// loadState reads migration state from file
|
||||
func (m *Migrator) loadState() error {
|
||||
data, err := os.ReadFile(m.statePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read state file: %w", err)
|
||||
}
|
||||
|
||||
return json.Unmarshal(data, m.state)
|
||||
}
|
||||
|
||||
// updateStep updates current step and persists state
|
||||
func (m *Migrator) updateStep(step int) error {
|
||||
m.state.Step = step
|
||||
return m.saveState()
|
||||
}
|
||||
|
||||
func (m *Migrator) Migrate() error {
|
||||
// Continue from the current step
|
||||
if m.state.Step <= StepSchema {
|
||||
m.l.Info("Creating basic v4 table schema...")
|
||||
if err := m.v4client.Schema.Create(context.Background()); err != nil {
|
||||
return fmt.Errorf("failed creating schema resources: %w", err)
|
||||
}
|
||||
if err := m.updateStep(StepSettings); err != nil {
|
||||
return fmt.Errorf("failed to update step: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if m.state.Step <= StepSettings {
|
||||
if err := m.migrateSettings(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := m.updateStep(StepNode); err != nil {
|
||||
return fmt.Errorf("failed to update step: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if m.state.Step <= StepNode {
|
||||
if err := m.migrateNode(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := m.updateStep(StepPolicy); err != nil {
|
||||
return fmt.Errorf("failed to update step: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if m.state.Step <= StepPolicy {
|
||||
allPolicyIDs, err := m.migratePolicy()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
m.state.PolicyIDs = allPolicyIDs
|
||||
if err := m.updateStep(StepGroup); err != nil {
|
||||
return fmt.Errorf("failed to update step: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if m.state.Step <= StepGroup {
|
||||
if err := m.migrateGroup(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := m.updateStep(StepUser); err != nil {
|
||||
return fmt.Errorf("failed to update step: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if m.state.Step <= StepUser {
|
||||
if err := m.migrateUser(); err != nil {
|
||||
m.saveState()
|
||||
return err
|
||||
}
|
||||
// Reset user offset after completion
|
||||
m.state.UserOffset = 0
|
||||
if err := m.updateStep(StepFolders); err != nil {
|
||||
return fmt.Errorf("failed to update step: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if m.state.Step <= StepFolders {
|
||||
if err := m.migrateFolders(); err != nil {
|
||||
m.saveState()
|
||||
return err
|
||||
}
|
||||
// Reset folder offset after completion
|
||||
m.state.FolderOffset = 0
|
||||
if err := m.updateStep(StepFolderParent); err != nil {
|
||||
return fmt.Errorf("failed to update step: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if m.state.Step <= StepFolderParent {
|
||||
if err := m.migrateFolderParent(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := m.updateStep(StepFile); err != nil {
|
||||
return fmt.Errorf("failed to update step: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if m.state.Step <= StepFile {
|
||||
if err := m.migrateFile(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := m.updateStep(StepShare); err != nil {
|
||||
return fmt.Errorf("failed to update step: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if m.state.Step <= StepShare {
|
||||
if err := m.migrateShare(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := m.updateStep(StepDirectLink); err != nil {
|
||||
return fmt.Errorf("failed to update step: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if m.state.Step <= StepDirectLink {
|
||||
if err := m.migrateDirectLink(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := m.updateStep(StepAvatar); err != nil {
|
||||
return fmt.Errorf("failed to update step: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if m.state.Step <= StepAvatar {
|
||||
if err := migrateAvatars(m); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := m.updateStep(StepWebdav); err != nil {
|
||||
return fmt.Errorf("failed to update step: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if m.state.Step <= StepWebdav {
|
||||
if err := m.migrateWebdav(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := m.updateStep(StepCompleted); err != nil {
|
||||
return fmt.Errorf("failed to update step: %w", err)
|
||||
}
|
||||
}
|
||||
m.l.Info("Migration completed successfully")
|
||||
return nil
|
||||
}
|
||||
|
||||
func formatTime(t time.Time) time.Time {
|
||||
newTime := time.UnixMilli(t.UnixMilli())
|
||||
return newTime
|
||||
}
|
||||
39
application/migrator/model/file.go
Normal file
39
application/migrator/model/file.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
// File 文件
|
||||
type File struct {
|
||||
// 表字段
|
||||
gorm.Model
|
||||
Name string `gorm:"unique_index:idx_only_one"`
|
||||
SourceName string `gorm:"type:text"`
|
||||
UserID uint `gorm:"index:user_id;unique_index:idx_only_one"`
|
||||
Size uint64
|
||||
PicInfo string
|
||||
FolderID uint `gorm:"index:folder_id;unique_index:idx_only_one"`
|
||||
PolicyID uint
|
||||
UploadSessionID *string `gorm:"index:session_id;unique_index:session_only_one"`
|
||||
Metadata string `gorm:"type:text"`
|
||||
|
||||
// 关联模型
|
||||
Policy Policy `gorm:"PRELOAD:false,association_autoupdate:false"`
|
||||
|
||||
// 数据库忽略字段
|
||||
Position string `gorm:"-"`
|
||||
MetadataSerialized map[string]string `gorm:"-"`
|
||||
}
|
||||
|
||||
// Thumb related metadata
|
||||
const (
|
||||
ThumbStatusNotExist = ""
|
||||
ThumbStatusExist = "exist"
|
||||
ThumbStatusNotAvailable = "not_available"
|
||||
|
||||
ThumbStatusMetadataKey = "thumb_status"
|
||||
ThumbSidecarMetadataKey = "thumb_sidecar"
|
||||
|
||||
ChecksumMetadataKey = "webdav_checksum"
|
||||
)
|
||||
18
application/migrator/model/folder.go
Normal file
18
application/migrator/model/folder.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
// Folder 目录
|
||||
type Folder struct {
|
||||
// 表字段
|
||||
gorm.Model
|
||||
Name string `gorm:"unique_index:idx_only_one_name"`
|
||||
ParentID *uint `gorm:"index:parent_id;unique_index:idx_only_one_name"`
|
||||
OwnerID uint `gorm:"index:owner_id"`
|
||||
|
||||
// 数据库忽略字段
|
||||
Position string `gorm:"-"`
|
||||
WebdavDstName string `gorm:"-"`
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
@@ -35,49 +34,5 @@ type GroupOption struct {
|
||||
RedirectedSource bool `json:"redirected_source,omitempty"`
|
||||
Aria2BatchSize int `json:"aria2_batch,omitempty"`
|
||||
AdvanceDelete bool `json:"advance_delete,omitempty"`
|
||||
}
|
||||
|
||||
// GetGroupByID 用ID获取用户组
|
||||
func GetGroupByID(ID interface{}) (Group, error) {
|
||||
var group Group
|
||||
result := DB.First(&group, ID)
|
||||
return group, result.Error
|
||||
}
|
||||
|
||||
// AfterFind 找到用户组后的钩子,处理Policy列表
|
||||
func (group *Group) AfterFind() (err error) {
|
||||
// 解析用户组策略列表
|
||||
if group.Policies != "" {
|
||||
err = json.Unmarshal([]byte(group.Policies), &group.PolicyList)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 解析用户组设置
|
||||
if group.Options != "" {
|
||||
err = json.Unmarshal([]byte(group.Options), &group.OptionsSerialized)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// BeforeSave Save用户前的钩子
|
||||
func (group *Group) BeforeSave() (err error) {
|
||||
err = group.SerializePolicyList()
|
||||
return err
|
||||
}
|
||||
|
||||
// SerializePolicyList 将序列后的可选策略列表、配置写入数据库字段
|
||||
// TODO 完善测试
|
||||
func (group *Group) SerializePolicyList() (err error) {
|
||||
policies, err := json.Marshal(&group.PolicyList)
|
||||
group.Policies = string(policies)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
optionsValue, err := json.Marshal(&group.OptionsSerialized)
|
||||
group.Options = string(optionsValue)
|
||||
return err
|
||||
WebDAVProxy bool `json:"webdav_proxy,omitempty"`
|
||||
}
|
||||
96
application/migrator/model/init.go
Normal file
96
application/migrator/model/init.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/application/migrator/conf"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/util"
|
||||
_ "github.com/jinzhu/gorm/dialects/mssql"
|
||||
_ "github.com/jinzhu/gorm/dialects/mysql"
|
||||
_ "github.com/jinzhu/gorm/dialects/postgres"
|
||||
)
|
||||
|
||||
// DB 数据库链接单例
|
||||
var DB *gorm.DB
|
||||
|
||||
// Init 初始化 MySQL 链接
|
||||
func Init() error {
|
||||
var (
|
||||
db *gorm.DB
|
||||
err error
|
||||
confDBType string = conf.DatabaseConfig.Type
|
||||
)
|
||||
|
||||
// 兼容已有配置中的 "sqlite3" 配置项
|
||||
if confDBType == "sqlite3" {
|
||||
confDBType = "sqlite"
|
||||
}
|
||||
|
||||
// 兼容 "mariadb" 数据库
|
||||
if confDBType == "mariadb" {
|
||||
confDBType = "mysql"
|
||||
}
|
||||
|
||||
switch confDBType {
|
||||
case "UNSET", "sqlite":
|
||||
// 未指定数据库或者明确指定为 sqlite 时,使用 SQLite 数据库
|
||||
db, err = gorm.Open("sqlite3", util.RelativePath(conf.DatabaseConfig.DBFile))
|
||||
case "postgres":
|
||||
db, err = gorm.Open(confDBType, fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=disable",
|
||||
conf.DatabaseConfig.Host,
|
||||
conf.DatabaseConfig.User,
|
||||
conf.DatabaseConfig.Password,
|
||||
conf.DatabaseConfig.Name,
|
||||
conf.DatabaseConfig.Port))
|
||||
case "mysql", "mssql":
|
||||
var host string
|
||||
if conf.DatabaseConfig.UnixSocket {
|
||||
host = fmt.Sprintf("unix(%s)",
|
||||
conf.DatabaseConfig.Host)
|
||||
} else {
|
||||
host = fmt.Sprintf("(%s:%d)",
|
||||
conf.DatabaseConfig.Host,
|
||||
conf.DatabaseConfig.Port)
|
||||
}
|
||||
|
||||
db, err = gorm.Open(confDBType, fmt.Sprintf("%s:%s@%s/%s?charset=%s&parseTime=True&loc=Local",
|
||||
conf.DatabaseConfig.User,
|
||||
conf.DatabaseConfig.Password,
|
||||
host,
|
||||
conf.DatabaseConfig.Name,
|
||||
conf.DatabaseConfig.Charset))
|
||||
default:
|
||||
return fmt.Errorf("unsupported database type %q", confDBType)
|
||||
}
|
||||
|
||||
//db.SetLogger(util.Log())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to connect to database: %w", err)
|
||||
}
|
||||
|
||||
// 处理表前缀
|
||||
gorm.DefaultTableNameHandler = func(db *gorm.DB, defaultTableName string) string {
|
||||
return conf.DatabaseConfig.TablePrefix + defaultTableName
|
||||
}
|
||||
|
||||
// Debug模式下,输出所有 SQL 日志
|
||||
db.LogMode(true)
|
||||
|
||||
//设置连接池
|
||||
db.DB().SetMaxIdleConns(50)
|
||||
if confDBType == "sqlite" || confDBType == "UNSET" {
|
||||
db.DB().SetMaxOpenConns(1)
|
||||
} else {
|
||||
db.DB().SetMaxOpenConns(100)
|
||||
}
|
||||
|
||||
//超时
|
||||
db.DB().SetConnMaxLifetime(time.Second * 30)
|
||||
|
||||
DB = db
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
@@ -50,42 +49,3 @@ const (
|
||||
SlaveNodeType ModelType = iota
|
||||
MasterNodeType
|
||||
)
|
||||
|
||||
// GetNodeByID 用ID获取节点
|
||||
func GetNodeByID(ID interface{}) (Node, error) {
|
||||
var node Node
|
||||
result := DB.First(&node, ID)
|
||||
return node, result.Error
|
||||
}
|
||||
|
||||
// GetNodesByStatus 根据给定状态获取节点
|
||||
func GetNodesByStatus(status ...NodeStatus) ([]Node, error) {
|
||||
var nodes []Node
|
||||
result := DB.Where("status in (?)", status).Find(&nodes)
|
||||
return nodes, result.Error
|
||||
}
|
||||
|
||||
// AfterFind 找到节点后的钩子
|
||||
func (node *Node) AfterFind() (err error) {
|
||||
// 解析离线下载设置到 Aria2OptionsSerialized
|
||||
if node.Aria2Options != "" {
|
||||
err = json.Unmarshal([]byte(node.Aria2Options), &node.Aria2OptionsSerialized)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// BeforeSave Save策略前的钩子
|
||||
func (node *Node) BeforeSave() (err error) {
|
||||
optionsValue, err := json.Marshal(&node.Aria2OptionsSerialized)
|
||||
node.Aria2Options = string(optionsValue)
|
||||
return err
|
||||
}
|
||||
|
||||
// SetStatus 设置节点启用状态
|
||||
func (node *Node) SetStatus(status NodeStatus) error {
|
||||
node.Status = status
|
||||
return DB.Model(node).Updates(map[string]interface{}{
|
||||
"status": status,
|
||||
}).Error
|
||||
}
|
||||
62
application/migrator/model/policy.go
Normal file
62
application/migrator/model/policy.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
// Policy 存储策略
|
||||
type Policy struct {
|
||||
// 表字段
|
||||
gorm.Model
|
||||
Name string
|
||||
Type string
|
||||
Server string
|
||||
BucketName string
|
||||
IsPrivate bool
|
||||
BaseURL string
|
||||
AccessKey string `gorm:"type:text"`
|
||||
SecretKey string `gorm:"type:text"`
|
||||
MaxSize uint64
|
||||
AutoRename bool
|
||||
DirNameRule string
|
||||
FileNameRule string
|
||||
IsOriginLinkEnable bool
|
||||
Options string `gorm:"type:text"`
|
||||
|
||||
// 数据库忽略字段
|
||||
OptionsSerialized PolicyOption `gorm:"-"`
|
||||
MasterID string `gorm:"-"`
|
||||
}
|
||||
|
||||
// PolicyOption 非公有的存储策略属性
|
||||
type PolicyOption struct {
|
||||
// Upyun访问Token
|
||||
Token string `json:"token"`
|
||||
// 允许的文件扩展名
|
||||
FileType []string `json:"file_type"`
|
||||
// MimeType
|
||||
MimeType string `json:"mimetype"`
|
||||
// OauthRedirect Oauth 重定向地址
|
||||
OauthRedirect string `json:"od_redirect,omitempty"`
|
||||
// OdProxy Onedrive 反代地址
|
||||
OdProxy string `json:"od_proxy,omitempty"`
|
||||
// OdDriver OneDrive 驱动器定位符
|
||||
OdDriver string `json:"od_driver,omitempty"`
|
||||
// Region 区域代码
|
||||
Region string `json:"region,omitempty"`
|
||||
// ServerSideEndpoint 服务端请求使用的 Endpoint,为空时使用 Policy.Server 字段
|
||||
ServerSideEndpoint string `json:"server_side_endpoint,omitempty"`
|
||||
// 分片上传的分片大小
|
||||
ChunkSize uint64 `json:"chunk_size,omitempty"`
|
||||
// 分片上传时是否需要预留空间
|
||||
PlaceholderWithSize bool `json:"placeholder_with_size,omitempty"`
|
||||
// 每秒对存储端的 API 请求上限
|
||||
TPSLimit float64 `json:"tps_limit,omitempty"`
|
||||
// 每秒 API 请求爆发上限
|
||||
TPSLimitBurst int `json:"tps_limit_burst,omitempty"`
|
||||
// Set this to `true` to force the request to use path-style addressing,
|
||||
// i.e., `http://s3.amazonaws.com/BUCKET/KEY `
|
||||
S3ForcePathStyle bool `json:"s3_path_style"`
|
||||
// File extensions that support thumbnail generation using native policy API.
|
||||
ThumbExts []string `json:"thumb_exts,omitempty"`
|
||||
}
|
||||
13
application/migrator/model/setting.go
Normal file
13
application/migrator/model/setting.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
// Setting 系统设置模型
|
||||
type Setting struct {
|
||||
gorm.Model
|
||||
Type string `gorm:"not null"`
|
||||
Name string `gorm:"unique;not null;index:setting_key"`
|
||||
Value string `gorm:"size:65535"`
|
||||
}
|
||||
27
application/migrator/model/share.go
Normal file
27
application/migrator/model/share.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
// Share 分享模型
|
||||
type Share struct {
|
||||
gorm.Model
|
||||
Password string // 分享密码,空值为非加密分享
|
||||
IsDir bool // 原始资源是否为目录
|
||||
UserID uint // 创建用户ID
|
||||
SourceID uint // 原始资源ID
|
||||
Views int // 浏览数
|
||||
Downloads int // 下载数
|
||||
RemainDownloads int // 剩余下载配额,负值标识无限制
|
||||
Expires *time.Time // 过期时间,空值表示无过期时间
|
||||
PreviewEnabled bool // 是否允许直接预览
|
||||
SourceName string `gorm:"index:source"` // 用于搜索的字段
|
||||
|
||||
// 数据库忽略字段
|
||||
User User `gorm:"PRELOAD:false,association_autoupdate:false"`
|
||||
File File `gorm:"PRELOAD:false,association_autoupdate:false"`
|
||||
Folder Folder `gorm:"PRELOAD:false,association_autoupdate:false"`
|
||||
}
|
||||
16
application/migrator/model/source_link.go
Normal file
16
application/migrator/model/source_link.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
// SourceLink represent a shared file source link
|
||||
type SourceLink struct {
|
||||
gorm.Model
|
||||
FileID uint // corresponding file ID
|
||||
Name string // name of the file while creating the source link, for annotation
|
||||
Downloads int // 下载数
|
||||
|
||||
// 关联模型
|
||||
File File `gorm:"save_associations:false:false"`
|
||||
}
|
||||
23
application/migrator/model/tag.go
Normal file
23
application/migrator/model/tag.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
// Tag 用户自定义标签
|
||||
type Tag struct {
|
||||
gorm.Model
|
||||
Name string // 标签名
|
||||
Icon string // 图标标识
|
||||
Color string // 图标颜色
|
||||
Type int // 标签类型(文件分类/目录直达)
|
||||
Expression string `gorm:"type:text"` // 搜索表表达式/直达路径
|
||||
UserID uint // 创建者ID
|
||||
}
|
||||
|
||||
const (
|
||||
// FileTagType 文件分类标签
|
||||
FileTagType = iota
|
||||
// DirectoryLinkType 目录快捷方式标签
|
||||
DirectoryLinkType
|
||||
)
|
||||
16
application/migrator/model/task.go
Normal file
16
application/migrator/model/task.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
// Task 任务模型
|
||||
type Task struct {
|
||||
gorm.Model
|
||||
Status int // 任务状态
|
||||
Type int // 任务类型
|
||||
UserID uint // 发起者UID,0表示为系统发起
|
||||
Progress int // 进度
|
||||
Error string `gorm:"type:text"` // 错误信息
|
||||
Props string `gorm:"type:text"` // 任务属性
|
||||
}
|
||||
45
application/migrator/model/user.go
Normal file
45
application/migrator/model/user.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
const (
|
||||
// Active 账户正常状态
|
||||
Active = iota
|
||||
// NotActivicated 未激活
|
||||
NotActivicated
|
||||
// Baned 被封禁
|
||||
Baned
|
||||
// OveruseBaned 超额使用被封禁
|
||||
OveruseBaned
|
||||
)
|
||||
|
||||
// User 用户模型
|
||||
type User struct {
|
||||
// 表字段
|
||||
gorm.Model
|
||||
Email string `gorm:"type:varchar(100);unique_index"`
|
||||
Nick string `gorm:"size:50"`
|
||||
Password string `json:"-"`
|
||||
Status int
|
||||
GroupID uint
|
||||
Storage uint64
|
||||
TwoFactor string
|
||||
Avatar string
|
||||
Options string `json:"-" gorm:"size:4294967295"`
|
||||
Authn string `gorm:"size:4294967295"`
|
||||
|
||||
// 关联模型
|
||||
Group Group `gorm:"save_associations:false:false"`
|
||||
Policy Policy `gorm:"PRELOAD:false,association_autoupdate:false"`
|
||||
|
||||
// 数据库忽略字段
|
||||
OptionsSerialized UserOption `gorm:"-"`
|
||||
}
|
||||
|
||||
// UserOption 用户个性化配置字段
|
||||
type UserOption struct {
|
||||
ProfileOff bool `json:"profile_off,omitempty"`
|
||||
PreferredTheme string `json:"preferred_theme,omitempty"`
|
||||
}
|
||||
16
application/migrator/model/webdav.go
Normal file
16
application/migrator/model/webdav.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"github.com/jinzhu/gorm"
|
||||
)
|
||||
|
||||
// Webdav 应用账户
|
||||
type Webdav struct {
|
||||
gorm.Model
|
||||
Name string // 应用名称
|
||||
Password string `gorm:"unique_index:password_only_on"` // 应用密码
|
||||
UserID uint `gorm:"unique_index:password_only_on"` // 用户ID
|
||||
Root string `gorm:"type:text"` // 根目录
|
||||
Readonly bool `gorm:"type:bool"` // 是否只读
|
||||
UseProxy bool `gorm:"type:bool"` // 是否进行反代
|
||||
}
|
||||
89
application/migrator/node.go
Normal file
89
application/migrator/node.go
Normal file
@@ -0,0 +1,89 @@
|
||||
package migrator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/application/migrator/model"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/node"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/boolset"
|
||||
)
|
||||
|
||||
func (m *Migrator) migrateNode() error {
|
||||
m.l.Info("Migrating nodes...")
|
||||
|
||||
var nodes []model.Node
|
||||
if err := model.DB.Find(&nodes).Error; err != nil {
|
||||
return fmt.Errorf("failed to list v3 nodes: %w", err)
|
||||
}
|
||||
|
||||
for _, n := range nodes {
|
||||
nodeType := node.TypeSlave
|
||||
nodeStatus := node.StatusSuspended
|
||||
if n.Type == model.MasterNodeType {
|
||||
nodeType = node.TypeMaster
|
||||
}
|
||||
if n.Status == model.NodeActive {
|
||||
nodeStatus = node.StatusActive
|
||||
}
|
||||
|
||||
cap := &boolset.BooleanSet{}
|
||||
settings := &types.NodeSetting{
|
||||
Provider: types.DownloaderProviderAria2,
|
||||
}
|
||||
|
||||
if n.Aria2Enabled {
|
||||
boolset.Sets(map[types.NodeCapability]bool{
|
||||
types.NodeCapabilityRemoteDownload: true,
|
||||
}, cap)
|
||||
|
||||
aria2Options := &model.Aria2Option{}
|
||||
if err := json.Unmarshal([]byte(n.Aria2Options), aria2Options); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal aria2 options: %w", err)
|
||||
}
|
||||
|
||||
downloaderOptions := map[string]any{}
|
||||
if aria2Options.Options != "" {
|
||||
if err := json.Unmarshal([]byte(aria2Options.Options), &downloaderOptions); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal aria2 options: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
settings.Aria2Setting = &types.Aria2Setting{
|
||||
Server: aria2Options.Server,
|
||||
Token: aria2Options.Token,
|
||||
Options: downloaderOptions,
|
||||
TempPath: aria2Options.TempPath,
|
||||
}
|
||||
}
|
||||
|
||||
if n.Type == model.MasterNodeType {
|
||||
boolset.Sets(map[types.NodeCapability]bool{
|
||||
types.NodeCapabilityExtractArchive: true,
|
||||
types.NodeCapabilityCreateArchive: true,
|
||||
}, cap)
|
||||
}
|
||||
|
||||
stm := m.v4client.Node.Create().
|
||||
SetRawID(int(n.ID)).
|
||||
SetCreatedAt(formatTime(n.CreatedAt)).
|
||||
SetUpdatedAt(formatTime(n.UpdatedAt)).
|
||||
SetName(n.Name).
|
||||
SetType(nodeType).
|
||||
SetStatus(nodeStatus).
|
||||
SetServer(n.Server).
|
||||
SetSlaveKey(n.SlaveKey).
|
||||
SetCapabilities(cap).
|
||||
SetSettings(settings).
|
||||
SetWeight(n.Rank)
|
||||
|
||||
if err := stm.Exec(context.Background()); err != nil {
|
||||
return fmt.Errorf("failed to create node %q: %w", n.Name, err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
196
application/migrator/policy.go
Normal file
196
application/migrator/policy.go
Normal file
@@ -0,0 +1,196 @@
|
||||
package migrator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/application/migrator/model"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/node"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/boolset"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/conf"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/setting"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
func (m *Migrator) migratePolicy() (map[int]bool, error) {
|
||||
m.l.Info("Migrating storage policies...")
|
||||
var policies []model.Policy
|
||||
if err := model.DB.Find(&policies).Error; err != nil {
|
||||
return nil, fmt.Errorf("failed to list v3 storage policies: %w", err)
|
||||
}
|
||||
|
||||
if m.state.LocalPolicyIDs == nil {
|
||||
m.state.LocalPolicyIDs = make(map[int]bool)
|
||||
}
|
||||
|
||||
if m.state.PolicyIDs == nil {
|
||||
m.state.PolicyIDs = make(map[int]bool)
|
||||
}
|
||||
|
||||
m.l.Info("Found %d v3 storage policies to be migrated.", len(policies))
|
||||
|
||||
// get thumb proxy settings
|
||||
var (
|
||||
thumbProxySettings []model.Setting
|
||||
thumbProxyEnabled bool
|
||||
thumbProxyPolicy []int
|
||||
)
|
||||
if err := model.DB.Where("name in (?)", []string{"thumb_proxy_enabled", "thumb_proxy_policy"}).Find(&thumbProxySettings).Error; err != nil {
|
||||
m.l.Warning("Failed to list v3 thumb proxy settings: %w", err)
|
||||
}
|
||||
|
||||
tx, err := m.v4client.Tx(context.Background())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to start transaction: %w", err)
|
||||
}
|
||||
|
||||
for _, s := range thumbProxySettings {
|
||||
if s.Name == "thumb_proxy_enabled" {
|
||||
thumbProxyEnabled = setting.IsTrueValue(s.Value)
|
||||
} else if s.Name == "thumb_proxy_policy" {
|
||||
if err := json.Unmarshal([]byte(s.Value), &thumbProxyPolicy); err != nil {
|
||||
m.l.Warning("Failed to unmarshal v3 thumb proxy policy: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, policy := range policies {
|
||||
m.l.Info("Migrating storage policy %q...", policy.Name)
|
||||
if err := json.Unmarshal([]byte(policy.Options), &policy.OptionsSerialized); err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal options for policy %q: %w", policy.Name, err)
|
||||
}
|
||||
|
||||
settings := &types.PolicySetting{
|
||||
Token: policy.OptionsSerialized.Token,
|
||||
FileType: policy.OptionsSerialized.FileType,
|
||||
OauthRedirect: policy.OptionsSerialized.OauthRedirect,
|
||||
OdDriver: policy.OptionsSerialized.OdDriver,
|
||||
Region: policy.OptionsSerialized.Region,
|
||||
ServerSideEndpoint: policy.OptionsSerialized.ServerSideEndpoint,
|
||||
ChunkSize: int64(policy.OptionsSerialized.ChunkSize),
|
||||
TPSLimit: policy.OptionsSerialized.TPSLimit,
|
||||
TPSLimitBurst: policy.OptionsSerialized.TPSLimitBurst,
|
||||
S3ForcePathStyle: policy.OptionsSerialized.S3ForcePathStyle,
|
||||
ThumbExts: policy.OptionsSerialized.ThumbExts,
|
||||
}
|
||||
|
||||
if policy.Type == types.PolicyTypeOd {
|
||||
settings.ThumbSupportAllExts = true
|
||||
} else {
|
||||
switch policy.Type {
|
||||
case types.PolicyTypeCos:
|
||||
settings.ThumbExts = []string{"png", "jpg", "jpeg", "gif", "bmp", "webp", "heif", "heic"}
|
||||
case types.PolicyTypeOss:
|
||||
settings.ThumbExts = []string{"png", "jpg", "jpeg", "gif", "bmp", "webp", "heic", "tiff", "avif"}
|
||||
case types.PolicyTypeUpyun:
|
||||
settings.ThumbExts = []string{"png", "jpg", "jpeg", "gif", "bmp", "webp", "svg"}
|
||||
case types.PolicyTypeQiniu:
|
||||
settings.ThumbExts = []string{"png", "jpg", "jpeg", "gif", "bmp", "webp", "tiff", "avif", "psd"}
|
||||
case types.PolicyTypeRemote:
|
||||
settings.ThumbExts = []string{"png", "jpg", "jpeg", "gif"}
|
||||
}
|
||||
}
|
||||
|
||||
if policy.Type != types.PolicyTypeOd && policy.BaseURL != "" {
|
||||
settings.CustomProxy = true
|
||||
settings.ProxyServer = policy.BaseURL
|
||||
} else if policy.OptionsSerialized.OdProxy != "" {
|
||||
settings.CustomProxy = true
|
||||
settings.ProxyServer = policy.OptionsSerialized.OdProxy
|
||||
}
|
||||
|
||||
if policy.Type == types.PolicyTypeCos {
|
||||
settings.ChunkSize = 1024 * 1024 * 25
|
||||
}
|
||||
|
||||
if thumbProxyEnabled && lo.Contains(thumbProxyPolicy, int(policy.ID)) {
|
||||
settings.ThumbGeneratorProxy = true
|
||||
}
|
||||
|
||||
mustContain := []string{"{randomkey16}", "{randomkey8}", "{uuid}"}
|
||||
hasRandomElement := false
|
||||
for _, c := range mustContain {
|
||||
if strings.Contains(policy.FileNameRule, c) {
|
||||
hasRandomElement = true
|
||||
break
|
||||
}
|
||||
|
||||
if strings.Contains(policy.DirNameRule, c) {
|
||||
hasRandomElement = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !hasRandomElement {
|
||||
if policy.DirNameRule == "" {
|
||||
policy.DirNameRule = "uploads/{uid}/{path}"
|
||||
}
|
||||
policy.FileNameRule = "{uid}_{randomkey8}_{originname}"
|
||||
m.l.Warning("Storage policy %q has no random element in file name rule, using default file name rule.", policy.Name)
|
||||
}
|
||||
|
||||
stm := tx.StoragePolicy.Create().
|
||||
SetRawID(int(policy.ID)).
|
||||
SetCreatedAt(formatTime(policy.CreatedAt)).
|
||||
SetUpdatedAt(formatTime(policy.UpdatedAt)).
|
||||
SetName(policy.Name).
|
||||
SetType(policy.Type).
|
||||
SetServer(policy.Server).
|
||||
SetBucketName(policy.BucketName).
|
||||
SetIsPrivate(policy.IsPrivate).
|
||||
SetAccessKey(policy.AccessKey).
|
||||
SetSecretKey(policy.SecretKey).
|
||||
SetMaxSize(int64(policy.MaxSize)).
|
||||
SetDirNameRule(policy.DirNameRule).
|
||||
SetFileNameRule(policy.FileNameRule).
|
||||
SetSettings(settings)
|
||||
|
||||
if policy.Type == types.PolicyTypeRemote {
|
||||
m.l.Info("Storage policy %q is remote, creating node for it...", policy.Name)
|
||||
bs := &boolset.BooleanSet{}
|
||||
n, err := tx.Node.Create().
|
||||
SetName(policy.Name).
|
||||
SetStatus(node.StatusActive).
|
||||
SetServer(policy.Server).
|
||||
SetSlaveKey(policy.SecretKey).
|
||||
SetType(node.TypeSlave).
|
||||
SetCapabilities(bs).
|
||||
SetSettings(&types.NodeSetting{
|
||||
Provider: types.DownloaderProviderAria2,
|
||||
}).
|
||||
Save(context.Background())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create node for storage policy %q: %w", policy.Name, err)
|
||||
}
|
||||
|
||||
stm.SetNodeID(n.ID)
|
||||
}
|
||||
|
||||
if _, err := stm.Save(context.Background()); err != nil {
|
||||
return nil, fmt.Errorf("failed to create storage policy %q: %w", policy.Name, err)
|
||||
}
|
||||
|
||||
m.state.PolicyIDs[int(policy.ID)] = true
|
||||
if policy.Type == types.PolicyTypeLocal {
|
||||
m.state.LocalPolicyIDs[int(policy.ID)] = true
|
||||
}
|
||||
}
|
||||
if err := tx.Commit(); err != nil {
|
||||
return nil, fmt.Errorf("failed to commit transaction: %w", err)
|
||||
}
|
||||
|
||||
if m.dep.ConfigProvider().Database().Type == conf.PostgresDB {
|
||||
m.l.Info("Resetting storage policy ID sequence for postgres...")
|
||||
m.v4client.StoragePolicy.ExecContext(context.Background(), "SELECT SETVAL('storage_policies_id_seq', (SELECT MAX(id) FROM storage_policies))")
|
||||
}
|
||||
|
||||
if m.dep.ConfigProvider().Database().Type == conf.PostgresDB {
|
||||
m.l.Info("Resetting node ID sequence for postgres...")
|
||||
m.v4client.Node.ExecContext(context.Background(), "SELECT SETVAL('nodes_id_seq', (SELECT MAX(id) FROM nodes))")
|
||||
}
|
||||
|
||||
return m.state.PolicyIDs, nil
|
||||
}
|
||||
213
application/migrator/settings.go
Normal file
213
application/migrator/settings.go
Normal file
@@ -0,0 +1,213 @@
|
||||
package migrator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/cloudreve/Cloudreve/v4/application/migrator/conf"
|
||||
"github.com/cloudreve/Cloudreve/v4/application/migrator/model"
|
||||
)
|
||||
|
||||
// TODO:
|
||||
// 1. Policy thumb proxy migration
|
||||
|
||||
type (
|
||||
settignMigrator func(allSettings map[string]string, name, value string) ([]settingMigrated, error)
|
||||
settingMigrated struct {
|
||||
name string
|
||||
value string
|
||||
}
|
||||
// PackProduct 容量包商品
|
||||
PackProduct struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Size uint64 `json:"size"`
|
||||
Time int64 `json:"time"`
|
||||
Price int `json:"price"`
|
||||
Score int `json:"score"`
|
||||
}
|
||||
GroupProducts struct {
|
||||
ID int64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
GroupID uint `json:"group_id"`
|
||||
Time int64 `json:"time"`
|
||||
Price int `json:"price"`
|
||||
Score int `json:"score"`
|
||||
Des []string `json:"des"`
|
||||
Highlight bool `json:"highlight"`
|
||||
}
|
||||
)
|
||||
|
||||
var noopMigrator = func(allSettings map[string]string, name, value string) ([]settingMigrated, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var migrators = map[string]settignMigrator{
|
||||
"siteKeywords": noopMigrator,
|
||||
"over_used_template": noopMigrator,
|
||||
"download_timeout": noopMigrator,
|
||||
"preview_timeout": noopMigrator,
|
||||
"doc_preview_timeout": noopMigrator,
|
||||
"slave_node_retry": noopMigrator,
|
||||
"slave_ping_interval": noopMigrator,
|
||||
"slave_recover_interval": noopMigrator,
|
||||
"slave_transfer_timeout": noopMigrator,
|
||||
"onedrive_monitor_timeout": noopMigrator,
|
||||
"onedrive_source_timeout": noopMigrator,
|
||||
"share_download_session_timeout": noopMigrator,
|
||||
"onedrive_callback_check": noopMigrator,
|
||||
"mail_activation_template": noopMigrator,
|
||||
"mail_reset_pwd_template": noopMigrator,
|
||||
"appid": noopMigrator,
|
||||
"appkey": noopMigrator,
|
||||
"wechat_enabled": noopMigrator,
|
||||
"wechat_appid": noopMigrator,
|
||||
"wechat_mchid": noopMigrator,
|
||||
"wechat_serial_no": noopMigrator,
|
||||
"wechat_api_key": noopMigrator,
|
||||
"wechat_pk_content": noopMigrator,
|
||||
"hot_share_num": noopMigrator,
|
||||
"defaultTheme": noopMigrator,
|
||||
"theme_options": noopMigrator,
|
||||
"max_worker_num": noopMigrator,
|
||||
"max_parallel_transfer": noopMigrator,
|
||||
"secret_key": noopMigrator,
|
||||
"avatar_size_m": noopMigrator,
|
||||
"avatar_size_s": noopMigrator,
|
||||
"home_view_method": noopMigrator,
|
||||
"share_view_method": noopMigrator,
|
||||
"cron_recycle_upload_session": noopMigrator,
|
||||
"captcha_type": func(allSettings map[string]string, name, value string) ([]settingMigrated, error) {
|
||||
if value == "tcaptcha" {
|
||||
value = "normal"
|
||||
}
|
||||
return []settingMigrated{
|
||||
{
|
||||
name: "captcha_type",
|
||||
value: value,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
"captcha_TCaptcha_CaptchaAppId": noopMigrator,
|
||||
"captcha_TCaptcha_AppSecretKey": noopMigrator,
|
||||
"captcha_TCaptcha_SecretId": noopMigrator,
|
||||
"captcha_TCaptcha_SecretKey": noopMigrator,
|
||||
"thumb_file_suffix": func(allSettings map[string]string, name, value string) ([]settingMigrated, error) {
|
||||
return []settingMigrated{
|
||||
{
|
||||
name: "thumb_entity_suffix",
|
||||
value: value,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
"thumb_max_src_size": func(allSettings map[string]string, name, value string) ([]settingMigrated, error) {
|
||||
return []settingMigrated{
|
||||
{
|
||||
name: "thumb_music_cover_max_size",
|
||||
value: value,
|
||||
},
|
||||
{
|
||||
name: "thumb_libreoffice_max_size",
|
||||
value: value,
|
||||
},
|
||||
{
|
||||
name: "thumb_ffmpeg_max_size",
|
||||
value: value,
|
||||
},
|
||||
{
|
||||
name: "thumb_vips_max_size",
|
||||
value: value,
|
||||
},
|
||||
{
|
||||
name: "thumb_builtin_max_size",
|
||||
value: value,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
"initial_files": noopMigrator,
|
||||
"office_preview_service": noopMigrator,
|
||||
"phone_required": noopMigrator,
|
||||
"phone_enabled": noopMigrator,
|
||||
"wopi_session_timeout": func(allSettings map[string]string, name, value string) ([]settingMigrated, error) {
|
||||
return []settingMigrated{
|
||||
{
|
||||
name: "viewer_session_timeout",
|
||||
value: value,
|
||||
},
|
||||
}, nil
|
||||
},
|
||||
"custom_payment_enabled": noopMigrator,
|
||||
"custom_payment_endpoint": noopMigrator,
|
||||
"custom_payment_secret": noopMigrator,
|
||||
"custom_payment_name": noopMigrator,
|
||||
}
|
||||
|
||||
func (m *Migrator) migrateSettings() error {
|
||||
m.l.Info("Migrating settings...")
|
||||
// 1. List all settings
|
||||
var settings []model.Setting
|
||||
if err := model.DB.Find(&settings).Error; err != nil {
|
||||
return fmt.Errorf("failed to list v3 settings: %w", err)
|
||||
}
|
||||
|
||||
m.l.Info("Found %d v3 setting pairs to be migrated.", len(settings))
|
||||
|
||||
allSettings := make(map[string]string)
|
||||
for _, s := range settings {
|
||||
allSettings[s.Name] = s.Value
|
||||
}
|
||||
|
||||
migratedSettings := make([]settingMigrated, 0)
|
||||
for _, s := range settings {
|
||||
if s.Name == "thumb_file_suffix" {
|
||||
m.state.ThumbSuffix = s.Value
|
||||
}
|
||||
if s.Name == "avatar_path" {
|
||||
m.state.V3AvatarPath = s.Value
|
||||
}
|
||||
migrator, ok := migrators[s.Name]
|
||||
if ok {
|
||||
newSettings, err := migrator(allSettings, s.Name, s.Value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to migrate setting %q: %w", s.Name, err)
|
||||
}
|
||||
migratedSettings = append(migratedSettings, newSettings...)
|
||||
} else {
|
||||
migratedSettings = append(migratedSettings, settingMigrated{
|
||||
name: s.Name,
|
||||
value: s.Value,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
tx, err := m.v4client.Tx(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to start transaction: %w", err)
|
||||
}
|
||||
|
||||
// Insert hash_id_salt
|
||||
if conf.SystemConfig.HashIDSalt != "" {
|
||||
if err := tx.Setting.Create().SetName("hash_id_salt").SetValue(conf.SystemConfig.HashIDSalt).Exec(context.Background()); err != nil {
|
||||
if err := tx.Rollback(); err != nil {
|
||||
return fmt.Errorf("failed to rollback transaction: %w", err)
|
||||
}
|
||||
return fmt.Errorf("failed to create setting hash_id_salt: %w", err)
|
||||
}
|
||||
} else {
|
||||
return fmt.Errorf("hash ID salt is not set, please set it from v3 conf file")
|
||||
}
|
||||
|
||||
for _, s := range migratedSettings {
|
||||
if err := tx.Setting.Create().SetName(s.name).SetValue(s.value).Exec(context.Background()); err != nil {
|
||||
if err := tx.Rollback(); err != nil {
|
||||
return fmt.Errorf("failed to rollback transaction: %w", err)
|
||||
}
|
||||
return fmt.Errorf("failed to create setting %q: %w", s.name, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return fmt.Errorf("failed to commit transaction: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
102
application/migrator/share.go
Normal file
102
application/migrator/share.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package migrator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/application/migrator/model"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/file"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/conf"
|
||||
)
|
||||
|
||||
func (m *Migrator) migrateShare() error {
|
||||
m.l.Info("Migrating shares...")
|
||||
batchSize := 1000
|
||||
offset := m.state.ShareOffset
|
||||
ctx := context.Background()
|
||||
|
||||
if offset > 0 {
|
||||
m.l.Info("Resuming share migration from offset %d", offset)
|
||||
}
|
||||
|
||||
for {
|
||||
m.l.Info("Migrating shares with offset %d", offset)
|
||||
var shares []model.Share
|
||||
if err := model.DB.Limit(batchSize).Offset(offset).Find(&shares).Error; err != nil {
|
||||
return fmt.Errorf("failed to list v3 shares: %w", err)
|
||||
}
|
||||
|
||||
if len(shares) == 0 {
|
||||
if m.dep.ConfigProvider().Database().Type == conf.PostgresDB {
|
||||
m.l.Info("Resetting share ID sequence for postgres...")
|
||||
m.v4client.Share.ExecContext(ctx, "SELECT SETVAL('shares_id_seq', (SELECT MAX(id) FROM shares))")
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
tx, err := m.v4client.Tx(ctx)
|
||||
if err != nil {
|
||||
_ = tx.Rollback()
|
||||
return fmt.Errorf("failed to start transaction: %w", err)
|
||||
}
|
||||
|
||||
for _, s := range shares {
|
||||
sourceId := int(s.SourceID)
|
||||
if !s.IsDir {
|
||||
sourceId += m.state.LastFolderID
|
||||
}
|
||||
|
||||
// check if file exists
|
||||
_, err = tx.File.Query().Where(file.ID(sourceId)).First(ctx)
|
||||
if err != nil {
|
||||
m.l.Warning("File %d not found, skipping share %d", sourceId, s.ID)
|
||||
continue
|
||||
}
|
||||
|
||||
// check if user exist
|
||||
if _, ok := m.state.UserIDs[int(s.UserID)]; !ok {
|
||||
m.l.Warning("User %d not found, skipping share %d", s.UserID, s.ID)
|
||||
continue
|
||||
}
|
||||
|
||||
stm := tx.Share.Create().
|
||||
SetCreatedAt(formatTime(s.CreatedAt)).
|
||||
SetUpdatedAt(formatTime(s.UpdatedAt)).
|
||||
SetViews(s.Views).
|
||||
SetRawID(int(s.ID)).
|
||||
SetDownloads(s.Downloads).
|
||||
SetFileID(sourceId).
|
||||
SetUserID(int(s.UserID))
|
||||
|
||||
if s.Password != "" {
|
||||
stm.SetPassword(s.Password)
|
||||
}
|
||||
|
||||
if s.Expires != nil {
|
||||
stm.SetNillableExpires(s.Expires)
|
||||
}
|
||||
|
||||
if s.RemainDownloads >= 0 {
|
||||
stm.SetRemainDownloads(s.RemainDownloads)
|
||||
}
|
||||
|
||||
if _, err := stm.Save(ctx); err != nil {
|
||||
_ = tx.Rollback()
|
||||
return fmt.Errorf("failed to create share %d: %w", s.ID, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return fmt.Errorf("failed to commit transaction: %w", err)
|
||||
}
|
||||
|
||||
offset += batchSize
|
||||
m.state.ShareOffset = offset
|
||||
if err := m.saveState(); err != nil {
|
||||
m.l.Warning("Failed to save state after share batch: %s", err)
|
||||
} else {
|
||||
m.l.Info("Saved migration state after processing this batch")
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
109
application/migrator/user.go
Normal file
109
application/migrator/user.go
Normal file
@@ -0,0 +1,109 @@
|
||||
package migrator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/cloudreve/Cloudreve/v4/application/migrator/model"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/user"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/conf"
|
||||
)
|
||||
|
||||
func (m *Migrator) migrateUser() error {
|
||||
m.l.Info("Migrating users...")
|
||||
batchSize := 1000
|
||||
// Start from the saved offset if available
|
||||
offset := m.state.UserOffset
|
||||
ctx := context.Background()
|
||||
if m.state.UserIDs == nil {
|
||||
m.state.UserIDs = make(map[int]bool)
|
||||
}
|
||||
|
||||
// If we're resuming, load existing user IDs
|
||||
if len(m.state.UserIDs) > 0 {
|
||||
m.l.Info("Resuming user migration from offset %d, %d users already migrated", offset, len(m.state.UserIDs))
|
||||
}
|
||||
|
||||
for {
|
||||
m.l.Info("Migrating users with offset %d", offset)
|
||||
var users []model.User
|
||||
if err := model.DB.Limit(batchSize).Offset(offset).Find(&users).Error; err != nil {
|
||||
return fmt.Errorf("failed to list v3 users: %w", err)
|
||||
}
|
||||
|
||||
if len(users) == 0 {
|
||||
if m.dep.ConfigProvider().Database().Type == conf.PostgresDB {
|
||||
m.l.Info("Resetting user ID sequence for postgres...")
|
||||
m.v4client.User.ExecContext(ctx, "SELECT SETVAL('users_id_seq', (SELECT MAX(id) FROM users))")
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
tx, err := m.v4client.Tx(context.Background())
|
||||
if err != nil {
|
||||
_ = tx.Rollback()
|
||||
return fmt.Errorf("failed to start transaction: %w", err)
|
||||
}
|
||||
|
||||
for _, u := range users {
|
||||
userStatus := user.StatusActive
|
||||
switch u.Status {
|
||||
case model.Active:
|
||||
userStatus = user.StatusActive
|
||||
case model.NotActivicated:
|
||||
userStatus = user.StatusInactive
|
||||
case model.Baned:
|
||||
userStatus = user.StatusManualBanned
|
||||
case model.OveruseBaned:
|
||||
userStatus = user.StatusSysBanned
|
||||
}
|
||||
|
||||
setting := &types.UserSetting{
|
||||
VersionRetention: true,
|
||||
VersionRetentionMax: 10,
|
||||
}
|
||||
|
||||
stm := tx.User.Create().
|
||||
SetRawID(int(u.ID)).
|
||||
SetCreatedAt(formatTime(u.CreatedAt)).
|
||||
SetUpdatedAt(formatTime(u.UpdatedAt)).
|
||||
SetEmail(u.Email).
|
||||
SetNick(u.Nick).
|
||||
SetStatus(userStatus).
|
||||
SetStorage(int64(u.Storage)).
|
||||
SetGroupID(int(u.GroupID)).
|
||||
SetSettings(setting).
|
||||
SetPassword(u.Password)
|
||||
|
||||
if u.TwoFactor != "" {
|
||||
stm.SetTwoFactorSecret(u.TwoFactor)
|
||||
}
|
||||
|
||||
if u.Avatar != "" {
|
||||
stm.SetAvatar(u.Avatar)
|
||||
}
|
||||
|
||||
if _, err := stm.Save(ctx); err != nil {
|
||||
_ = tx.Rollback()
|
||||
return fmt.Errorf("failed to create user %d: %w", u.ID, err)
|
||||
}
|
||||
|
||||
m.state.UserIDs[int(u.ID)] = true
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return fmt.Errorf("failed to commit transaction: %w", err)
|
||||
}
|
||||
|
||||
// Update the offset in state and save after each batch
|
||||
offset += batchSize
|
||||
m.state.UserOffset = offset
|
||||
if err := m.saveState(); err != nil {
|
||||
m.l.Warning("Failed to save state after user batch: %s", err)
|
||||
} else {
|
||||
m.l.Info("Saved migration state after processing %d users", offset)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
93
application/migrator/webdav.go
Normal file
93
application/migrator/webdav.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package migrator
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/application/migrator/model"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/boolset"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/conf"
|
||||
)
|
||||
|
||||
func (m *Migrator) migrateWebdav() error {
|
||||
m.l.Info("Migrating webdav accounts...")
|
||||
|
||||
batchSize := 1000
|
||||
offset := m.state.WebdavOffset
|
||||
ctx := context.Background()
|
||||
|
||||
if m.state.WebdavOffset > 0 {
|
||||
m.l.Info("Resuming webdav migration from offset %d", offset)
|
||||
}
|
||||
|
||||
for {
|
||||
m.l.Info("Migrating webdav accounts with offset %d", offset)
|
||||
var webdavAccounts []model.Webdav
|
||||
if err := model.DB.Limit(batchSize).Offset(offset).Find(&webdavAccounts).Error; err != nil {
|
||||
return fmt.Errorf("failed to list v3 webdav accounts: %w", err)
|
||||
}
|
||||
|
||||
if len(webdavAccounts) == 0 {
|
||||
if m.dep.ConfigProvider().Database().Type == conf.PostgresDB {
|
||||
m.l.Info("Resetting webdav account ID sequence for postgres...")
|
||||
m.v4client.DavAccount.ExecContext(ctx, "SELECT SETVAL('dav_accounts_id_seq', (SELECT MAX(id) FROM dav_accounts))")
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
tx, err := m.v4client.Tx(ctx)
|
||||
if err != nil {
|
||||
_ = tx.Rollback()
|
||||
return fmt.Errorf("failed to start transaction: %w", err)
|
||||
}
|
||||
|
||||
for _, webdavAccount := range webdavAccounts {
|
||||
if _, ok := m.state.UserIDs[int(webdavAccount.UserID)]; !ok {
|
||||
m.l.Warning("User %d not found, skipping webdav account %d", webdavAccount.UserID, webdavAccount.ID)
|
||||
continue
|
||||
}
|
||||
|
||||
props := types.DavAccountProps{}
|
||||
options := boolset.BooleanSet{}
|
||||
|
||||
if webdavAccount.Readonly {
|
||||
boolset.Set(int(types.DavAccountReadOnly), true, &options)
|
||||
}
|
||||
|
||||
if webdavAccount.UseProxy {
|
||||
boolset.Set(int(types.DavAccountProxy), true, &options)
|
||||
}
|
||||
|
||||
stm := tx.DavAccount.Create().
|
||||
SetCreatedAt(formatTime(webdavAccount.CreatedAt)).
|
||||
SetUpdatedAt(formatTime(webdavAccount.UpdatedAt)).
|
||||
SetRawID(int(webdavAccount.ID)).
|
||||
SetName(webdavAccount.Name).
|
||||
SetURI("cloudreve://my" + webdavAccount.Root).
|
||||
SetPassword(webdavAccount.Password).
|
||||
SetProps(&props).
|
||||
SetOptions(&options).
|
||||
SetOwnerID(int(webdavAccount.UserID))
|
||||
|
||||
if _, err := stm.Save(ctx); err != nil {
|
||||
_ = tx.Rollback()
|
||||
return fmt.Errorf("failed to create webdav account %d: %w", webdavAccount.ID, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
return fmt.Errorf("failed to commit transaction: %w", err)
|
||||
}
|
||||
|
||||
offset += batchSize
|
||||
m.state.WebdavOffset = offset
|
||||
if err := m.saveState(); err != nil {
|
||||
m.l.Warning("Failed to save state after webdav batch: %s", err)
|
||||
} else {
|
||||
m.l.Info("Saved migration state after processing this batch")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -126,7 +126,7 @@
|
||||
// To support tools that analyze Go packages, the patterns found in //go:embed lines
|
||||
// are available in “go list” output. See the EmbedPatterns, TestEmbedPatterns,
|
||||
// and XTestEmbedPatterns fields in the “go help list” output.
|
||||
package bootstrap
|
||||
package statics
|
||||
|
||||
import (
|
||||
"errors"
|
||||
@@ -218,9 +218,10 @@ var (
|
||||
type file struct {
|
||||
// The compiler knows the layout of this struct.
|
||||
// See cmd/compile/internal/staticdata's WriteEmbed.
|
||||
name string
|
||||
data string
|
||||
hash [16]byte // truncated SHA256 hash
|
||||
name string
|
||||
data string
|
||||
hash [16]byte // truncated SHA256 hash
|
||||
modTime time.Time
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -230,7 +231,7 @@ var (
|
||||
|
||||
func (f *file) Name() string { _, elem, _ := split(f.name); return elem }
|
||||
func (f *file) Size() int64 { return int64(len(f.data)) }
|
||||
func (f *file) ModTime() time.Time { return time.Time{} }
|
||||
func (f *file) ModTime() time.Time { return f.modTime }
|
||||
func (f *file) IsDir() bool { _, _, isDir := split(f.name); return isDir }
|
||||
func (f *file) Sys() any { return nil }
|
||||
func (f *file) Type() fs.FileMode { return f.Mode().Type() }
|
||||
230
application/statics/statics.go
Normal file
230
application/statics/statics.go
Normal file
@@ -0,0 +1,230 @@
|
||||
package statics
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"bufio"
|
||||
"crypto/sha256"
|
||||
"debug/buildinfo"
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/cloudreve/Cloudreve/v4/application/constants"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/logging"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/util"
|
||||
"github.com/gin-contrib/static"
|
||||
"io"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const StaticFolder = "statics"
|
||||
|
||||
//go:embed assets.zip
|
||||
var zipContent string
|
||||
|
||||
type GinFS struct {
|
||||
FS http.FileSystem
|
||||
}
|
||||
|
||||
type version struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
// Open 打开文件
|
||||
func (b *GinFS) Open(name string) (http.File, error) {
|
||||
return b.FS.Open(name)
|
||||
}
|
||||
|
||||
// Exists 文件是否存在
|
||||
func (b *GinFS) Exists(prefix string, filepath string) bool {
|
||||
if _, err := b.FS.Open(filepath); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// NewServerStaticFS 初始化静态资源文件
|
||||
func NewServerStaticFS(l logging.Logger, statics fs.FS, isPro bool) (static.ServeFileSystem, error) {
|
||||
var staticFS static.ServeFileSystem
|
||||
if util.Exists(util.DataPath(StaticFolder)) {
|
||||
l.Info("Folder with %q already exists, it will be used to serve static files.", util.DataPath(StaticFolder))
|
||||
staticFS = static.LocalFile(util.DataPath(StaticFolder), false)
|
||||
} else {
|
||||
// 初始化静态资源
|
||||
embedFS, err := fs.Sub(statics, "assets/build")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to initialize static resources: %w", err)
|
||||
}
|
||||
|
||||
staticFS = &GinFS{
|
||||
FS: http.FS(embedFS),
|
||||
}
|
||||
}
|
||||
// 检查静态资源的版本
|
||||
f, err := staticFS.Open("version.json")
|
||||
if err != nil {
|
||||
l.Warning("Missing version identifier file in static resources, please delete \"statics\" folder and rebuild it.")
|
||||
return staticFS, nil
|
||||
}
|
||||
|
||||
b, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
l.Warning("Failed to read version identifier file in static resources, please delete \"statics\" folder and rebuild it.")
|
||||
return staticFS, nil
|
||||
}
|
||||
|
||||
var v version
|
||||
if err := json.Unmarshal(b, &v); err != nil {
|
||||
l.Warning("Failed to parse version identifier file in static resources: %s", err)
|
||||
return staticFS, nil
|
||||
}
|
||||
|
||||
staticName := "cloudreve-frontend"
|
||||
if isPro {
|
||||
staticName += "-pro"
|
||||
}
|
||||
|
||||
if v.Name != staticName {
|
||||
l.Error("Static resource version mismatch, please delete \"statics\" folder and rebuild it.")
|
||||
}
|
||||
|
||||
if v.Version != constants.BackendVersion {
|
||||
l.Error("Static resource version mismatch [Current %s, Desired: %s],please delete \"statics\" folder and rebuild it.", v.Version, constants.BackendVersion)
|
||||
}
|
||||
|
||||
return staticFS, nil
|
||||
}
|
||||
|
||||
func NewStaticFS(l logging.Logger) fs.FS {
|
||||
zipReader, err := zip.NewReader(strings.NewReader(zipContent), int64(len(zipContent)))
|
||||
if err != nil {
|
||||
l.Panic("Static resource is not a valid zip file: %s", err)
|
||||
}
|
||||
|
||||
var files []file
|
||||
modTime := getBuildTime()
|
||||
err = fs.WalkDir(zipReader, ".", func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot walk into %q: %w", path, err)
|
||||
}
|
||||
|
||||
if path == "." {
|
||||
return nil
|
||||
}
|
||||
|
||||
f := file{modTime: modTime}
|
||||
if d.IsDir() {
|
||||
f.name = path + "/"
|
||||
} else {
|
||||
f.name = path
|
||||
|
||||
rc, err := zipReader.Open(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("canot open %q: %w", path, err)
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
data, err := io.ReadAll(rc)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot read %q: %w", path, err)
|
||||
}
|
||||
|
||||
f.data = string(data)
|
||||
|
||||
hash := sha256.Sum256(data)
|
||||
for i := range f.hash {
|
||||
f.hash[i] = ^hash[i]
|
||||
}
|
||||
}
|
||||
files = append(files, f)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
l.Panic("Failed to initialize static resources: %s", err)
|
||||
}
|
||||
|
||||
sort.Slice(files, func(i, j int) bool {
|
||||
fi, fj := files[i], files[j]
|
||||
di, ei, _ := split(fi.name)
|
||||
dj, ej, _ := split(fj.name)
|
||||
|
||||
if di != dj {
|
||||
return di < dj
|
||||
}
|
||||
return ei < ej
|
||||
})
|
||||
|
||||
var embedFS FS
|
||||
embedFS.files = &files
|
||||
return embedFS
|
||||
}
|
||||
|
||||
// Eject 抽离内置静态资源
|
||||
func Eject(l logging.Logger, statics fs.FS) error {
|
||||
// 初始化静态资源
|
||||
embedFS, err := fs.Sub(statics, "assets/build")
|
||||
if err != nil {
|
||||
l.Panic("Failed to initialize static resources: %s", err)
|
||||
}
|
||||
|
||||
var walk func(relPath string, d fs.DirEntry, err error) error
|
||||
walk = func(relPath string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read info of %q: %s, skipping...", relPath, err)
|
||||
}
|
||||
|
||||
if !d.IsDir() {
|
||||
// 写入文件
|
||||
dst := util.DataPath(filepath.Join(StaticFolder, relPath))
|
||||
out, err := util.CreatNestedFile(dst)
|
||||
defer out.Close()
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create file %q: %s, skipping...", dst, err)
|
||||
}
|
||||
|
||||
l.Info("Ejecting %q...", dst)
|
||||
obj, _ := embedFS.Open(relPath)
|
||||
if _, err := io.Copy(out, bufio.NewReader(obj)); err != nil {
|
||||
return fmt.Errorf("cannot write file %q: %s, skipping...", relPath, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// util.Log().Info("开始导出内置静态资源...")
|
||||
err = fs.WalkDir(embedFS, ".", walk)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to eject static resources: %w", err)
|
||||
}
|
||||
|
||||
l.Info("Finish ejecting static resources.")
|
||||
return nil
|
||||
}
|
||||
|
||||
func getBuildTime() (buildTime time.Time) {
|
||||
buildTime = time.Now()
|
||||
exe, err := os.Executable()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
info, err := buildinfo.ReadFile(exe)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, s := range info.Settings {
|
||||
if s.Key == "vcs.time" && s.Value != "" {
|
||||
if t, err := time.Parse(time.RFC3339, s.Value); err == nil {
|
||||
buildTime = t
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
2
assets
2
assets
Submodule assets updated: 0feca325f4...8f98777045
BIN
assets.zip
BIN
assets.zip
Binary file not shown.
47
azure-pipelines.yml
Normal file
47
azure-pipelines.yml
Normal file
@@ -0,0 +1,47 @@
|
||||
trigger:
|
||||
tags:
|
||||
include:
|
||||
- '*'
|
||||
variables:
|
||||
GO_VERSION: "1.25.5"
|
||||
NODE_VERSION: "22.x"
|
||||
DOCKER_BUILDKIT: 1
|
||||
|
||||
pool:
|
||||
name: Default
|
||||
|
||||
jobs:
|
||||
- job: Release
|
||||
steps:
|
||||
- checkout: self
|
||||
submodules: true
|
||||
persistCredentials: true
|
||||
- task: NodeTool@0
|
||||
inputs:
|
||||
versionSpec: '$(NODE_VERSION)'
|
||||
displayName: 'Install Node.js'
|
||||
- task: GoTool@0
|
||||
inputs:
|
||||
version: "$(GO_VERSION)"
|
||||
displayName: Install Go
|
||||
- task: Docker@2
|
||||
inputs:
|
||||
containerRegistry: "CR DockerHub"
|
||||
command: "login"
|
||||
addPipelineData: false
|
||||
addBaseImageData: false
|
||||
- task: CmdLine@2
|
||||
displayName: "Install tonistiigi/binfmt"
|
||||
inputs:
|
||||
script: |
|
||||
docker run --privileged --rm tonistiigi/binfmt --install all
|
||||
- task: goreleaser@0
|
||||
condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/tags/'))
|
||||
inputs:
|
||||
version: "latest"
|
||||
distribution: "goreleaser"
|
||||
workdir: "$(Build.SourcesDirectory)"
|
||||
args: "release --timeout 60m -p 4"
|
||||
env:
|
||||
GITHUB_TOKEN: $(GITHUB_TOKEN)
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/conf"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/request"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/util"
|
||||
"github.com/hashicorp/go-version"
|
||||
)
|
||||
|
||||
// InitApplication 初始化应用常量
|
||||
func InitApplication() {
|
||||
fmt.Print(`
|
||||
___ _ _
|
||||
/ __\ | ___ _ _ __| |_ __ _____ _____
|
||||
/ / | |/ _ \| | | |/ _ | '__/ _ \ \ / / _ \
|
||||
/ /___| | (_) | |_| | (_| | | | __/\ V / __/
|
||||
\____/|_|\___/ \__,_|\__,_|_| \___| \_/ \___|
|
||||
|
||||
V` + conf.BackendVersion + ` Commit #` + conf.LastCommit + ` Pro=` + conf.IsPro + `
|
||||
================================================
|
||||
|
||||
`)
|
||||
go CheckUpdate()
|
||||
}
|
||||
|
||||
type GitHubRelease struct {
|
||||
URL string `json:"html_url"`
|
||||
Name string `json:"name"`
|
||||
Tag string `json:"tag_name"`
|
||||
}
|
||||
|
||||
// CheckUpdate 检查更新
|
||||
func CheckUpdate() {
|
||||
client := request.NewClient()
|
||||
res, err := client.Request("GET", "https://api.github.com/repos/cloudreve/cloudreve/releases", nil).GetResponse()
|
||||
if err != nil {
|
||||
util.Log().Warning("更新检查失败, %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
var list []GitHubRelease
|
||||
if err := json.Unmarshal([]byte(res), &list); err != nil {
|
||||
util.Log().Warning("更新检查失败, %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(list) > 0 {
|
||||
present, err1 := version.NewVersion(conf.BackendVersion)
|
||||
latest, err2 := version.NewVersion(list[0].Tag)
|
||||
if err1 == nil && err2 == nil && latest.GreaterThan(present) {
|
||||
util.Log().Info("有新的版本 [%s] 可用,下载:%s", list[0].Name, list[0].URL)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"crypto/sha256"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/util"
|
||||
"github.com/pkg/errors"
|
||||
"io"
|
||||
"io/fs"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func NewFS(zipContent string) fs.FS {
|
||||
zipReader, err := zip.NewReader(strings.NewReader(zipContent), int64(len(zipContent)))
|
||||
if err != nil {
|
||||
util.Log().Panic("Static resource is not a valid zip file: %s", err)
|
||||
}
|
||||
|
||||
var files []file
|
||||
err = fs.WalkDir(zipReader, ".", func(path string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return errors.Errorf("无法获取[%s]的信息, %s, 跳过...", path, err)
|
||||
}
|
||||
|
||||
if path == "." {
|
||||
return nil
|
||||
}
|
||||
|
||||
var f file
|
||||
if d.IsDir() {
|
||||
f.name = path + "/"
|
||||
} else {
|
||||
f.name = path
|
||||
|
||||
rc, err := zipReader.Open(path)
|
||||
if err != nil {
|
||||
return errors.Errorf("无法打开文件[%s], %s, 跳过...", path, err)
|
||||
}
|
||||
defer rc.Close()
|
||||
|
||||
data, err := io.ReadAll(rc)
|
||||
if err != nil {
|
||||
return errors.Errorf("无法读取文件[%s], %s, 跳过...", path, err)
|
||||
}
|
||||
|
||||
f.data = string(data)
|
||||
|
||||
hash := sha256.Sum256(data)
|
||||
for i := range f.hash {
|
||||
f.hash[i] = ^hash[i]
|
||||
}
|
||||
}
|
||||
files = append(files, f)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
util.Log().Panic("初始化静态资源失败: %s", err)
|
||||
}
|
||||
|
||||
sort.Slice(files, func(i, j int) bool {
|
||||
fi, fj := files[i], files[j]
|
||||
di, ei, _ := split(fi.name)
|
||||
dj, ej, _ := split(fj.name)
|
||||
|
||||
if di != dj {
|
||||
return di < dj
|
||||
}
|
||||
return ei < ej
|
||||
})
|
||||
|
||||
var embedFS FS
|
||||
embedFS.files = &files
|
||||
return embedFS
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
model "github.com/cloudreve/Cloudreve/v3/models"
|
||||
"github.com/cloudreve/Cloudreve/v3/models/scripts"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/aria2"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/auth"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/cache"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/cluster"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/conf"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/crontab"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/email"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/mq"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/task"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/wopi"
|
||||
"github.com/gin-gonic/gin"
|
||||
"io/fs"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// Init 初始化启动
|
||||
func Init(path string, statics fs.FS) {
|
||||
InitApplication()
|
||||
conf.Init(path)
|
||||
// Debug 关闭时,切换为生产模式
|
||||
if !conf.SystemConfig.Debug {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
}
|
||||
|
||||
dependencies := []struct {
|
||||
mode string
|
||||
factory func()
|
||||
}{
|
||||
{
|
||||
"both",
|
||||
func() {
|
||||
scripts.Init()
|
||||
},
|
||||
},
|
||||
{
|
||||
"both",
|
||||
func() {
|
||||
cache.Init()
|
||||
},
|
||||
},
|
||||
{
|
||||
"slave",
|
||||
func() {
|
||||
model.InitSlaveDefaults()
|
||||
},
|
||||
},
|
||||
{
|
||||
"slave",
|
||||
func() {
|
||||
cache.InitSlaveOverwrites()
|
||||
},
|
||||
},
|
||||
{
|
||||
"master",
|
||||
func() {
|
||||
model.Init()
|
||||
},
|
||||
},
|
||||
{
|
||||
"both",
|
||||
func() {
|
||||
cache.Restore(filepath.Join(model.GetSettingByName("temp_path"), cache.DefaultCacheFile))
|
||||
},
|
||||
},
|
||||
{
|
||||
"both",
|
||||
func() {
|
||||
task.Init()
|
||||
},
|
||||
},
|
||||
{
|
||||
"master",
|
||||
func() {
|
||||
cluster.Init()
|
||||
},
|
||||
},
|
||||
{
|
||||
"master",
|
||||
func() {
|
||||
aria2.Init(false, cluster.Default, mq.GlobalMQ)
|
||||
},
|
||||
},
|
||||
{
|
||||
"master",
|
||||
func() {
|
||||
email.Init()
|
||||
},
|
||||
},
|
||||
{
|
||||
"master",
|
||||
func() {
|
||||
crontab.Init()
|
||||
},
|
||||
},
|
||||
{
|
||||
"master",
|
||||
func() {
|
||||
InitStatic(statics)
|
||||
},
|
||||
},
|
||||
{
|
||||
"slave",
|
||||
func() {
|
||||
cluster.InitController()
|
||||
},
|
||||
},
|
||||
{
|
||||
"both",
|
||||
func() {
|
||||
auth.Init()
|
||||
},
|
||||
},
|
||||
{
|
||||
"master",
|
||||
func() {
|
||||
wopi.Init()
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, dependency := range dependencies {
|
||||
if dependency.mode == conf.SystemConfig.Mode || dependency.mode == "both" {
|
||||
dependency.factory()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/cloudreve/Cloudreve/v3/models/scripts/invoker"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/util"
|
||||
)
|
||||
|
||||
func RunScript(name string) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
if err := invoker.RunDBScript(name, ctx); err != nil {
|
||||
util.Log().Error("Failed to execute database script: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
util.Log().Info("Finish executing database script %q.", name)
|
||||
}
|
||||
@@ -1,136 +0,0 @@
|
||||
package bootstrap
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/conf"
|
||||
"github.com/cloudreve/Cloudreve/v3/pkg/util"
|
||||
|
||||
"github.com/gin-contrib/static"
|
||||
)
|
||||
|
||||
const StaticFolder = "statics"
|
||||
|
||||
type GinFS struct {
|
||||
FS http.FileSystem
|
||||
}
|
||||
|
||||
type staticVersion struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
|
||||
// StaticFS 内置静态文件资源
|
||||
var StaticFS static.ServeFileSystem
|
||||
|
||||
// Open 打开文件
|
||||
func (b *GinFS) Open(name string) (http.File, error) {
|
||||
return b.FS.Open(name)
|
||||
}
|
||||
|
||||
// Exists 文件是否存在
|
||||
func (b *GinFS) Exists(prefix string, filepath string) bool {
|
||||
if _, err := b.FS.Open(filepath); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// InitStatic 初始化静态资源文件
|
||||
func InitStatic(statics fs.FS) {
|
||||
if util.Exists(util.RelativePath(StaticFolder)) {
|
||||
util.Log().Info("Folder with name \"statics\" already exists, it will be used to serve static files.")
|
||||
StaticFS = static.LocalFile(util.RelativePath("statics"), false)
|
||||
} else {
|
||||
// 初始化静态资源
|
||||
embedFS, err := fs.Sub(statics, "assets/build")
|
||||
if err != nil {
|
||||
util.Log().Panic("Failed to initialize static resources: %s", err)
|
||||
}
|
||||
|
||||
StaticFS = &GinFS{
|
||||
FS: http.FS(embedFS),
|
||||
}
|
||||
}
|
||||
// 检查静态资源的版本
|
||||
f, err := StaticFS.Open("version.json")
|
||||
if err != nil {
|
||||
util.Log().Warning("Missing version identifier file in static resources, please delete \"statics\" folder and rebuild it.")
|
||||
return
|
||||
}
|
||||
|
||||
b, err := io.ReadAll(f)
|
||||
if err != nil {
|
||||
util.Log().Warning("Failed to read version identifier file in static resources, please delete \"statics\" folder and rebuild it.")
|
||||
return
|
||||
}
|
||||
|
||||
var v staticVersion
|
||||
if err := json.Unmarshal(b, &v); err != nil {
|
||||
util.Log().Warning("Failed to parse version identifier file in static resources: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
staticName := "cloudreve-frontend"
|
||||
if conf.IsPro == "true" {
|
||||
staticName += "-pro"
|
||||
}
|
||||
|
||||
if v.Name != staticName {
|
||||
util.Log().Warning("Static resource version mismatch, please delete \"statics\" folder and rebuild it.")
|
||||
return
|
||||
}
|
||||
|
||||
if v.Version != conf.RequiredStaticVersion {
|
||||
util.Log().Warning("Static resource version mismatch [Current %s, Desired: %s],please delete \"statics\" folder and rebuild it.", v.Version, conf.RequiredStaticVersion)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Eject 抽离内置静态资源
|
||||
func Eject(statics fs.FS) {
|
||||
// 初始化静态资源
|
||||
embedFS, err := fs.Sub(statics, "assets/build")
|
||||
if err != nil {
|
||||
util.Log().Panic("Failed to initialize static resources: %s", err)
|
||||
}
|
||||
|
||||
var walk func(relPath string, d fs.DirEntry, err error) error
|
||||
walk = func(relPath string, d fs.DirEntry, err error) error {
|
||||
if err != nil {
|
||||
return errors.Errorf("Failed to read info of %q: %s, skipping...", relPath, err)
|
||||
}
|
||||
|
||||
if !d.IsDir() {
|
||||
// 写入文件
|
||||
out, err := util.CreatNestedFile(filepath.Join(util.RelativePath(""), StaticFolder, relPath))
|
||||
defer out.Close()
|
||||
|
||||
if err != nil {
|
||||
return errors.Errorf("Failed to create file %q: %s, skipping...", relPath, err)
|
||||
}
|
||||
|
||||
util.Log().Info("Ejecting %q...", relPath)
|
||||
obj, _ := embedFS.Open(relPath)
|
||||
if _, err := io.Copy(out, bufio.NewReader(obj)); err != nil {
|
||||
return errors.Errorf("Cannot write file %q: %s, skipping...", relPath, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// util.Log().Info("开始导出内置静态资源...")
|
||||
err = fs.WalkDir(embedFS, ".", walk)
|
||||
if err != nil {
|
||||
util.Log().Error("Error occurs while ejecting static resources: %s", err)
|
||||
return
|
||||
}
|
||||
util.Log().Info("Finish ejecting static resources.")
|
||||
}
|
||||
30
cmd/eject.go
Normal file
30
cmd/eject.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/cloudreve/Cloudreve/v4/application/constants"
|
||||
"github.com/cloudreve/Cloudreve/v4/application/dependency"
|
||||
"github.com/cloudreve/Cloudreve/v4/application/statics"
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(ejectCmd)
|
||||
}
|
||||
|
||||
var ejectCmd = &cobra.Command{
|
||||
Use: "eject",
|
||||
Short: "Eject all embedded static files",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
dep := dependency.NewDependency(
|
||||
dependency.WithConfigPath(confPath),
|
||||
dependency.WithProFlag(constants.IsPro == "true"),
|
||||
)
|
||||
logger := dep.Logger()
|
||||
|
||||
if err := statics.Eject(dep.Logger(), dep.Statics()); err != nil {
|
||||
logger.Error("Failed to eject static files: %s", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
},
|
||||
}
|
||||
230
cmd/masterkey.go
Normal file
230
cmd/masterkey.go
Normal file
@@ -0,0 +1,230 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/application/dependency"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/entity"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/filemanager/encrypt"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/setting"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
outputToFile string
|
||||
newMasterKeyFile string
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(masterKeyCmd)
|
||||
masterKeyCmd.AddCommand(masterKeyGenerateCmd)
|
||||
masterKeyCmd.AddCommand(masterKeyGetCmd)
|
||||
masterKeyCmd.AddCommand(masterKeyRotateCmd)
|
||||
|
||||
masterKeyGenerateCmd.Flags().StringVarP(&outputToFile, "output", "o", "", "Output master key to file instead of stdout")
|
||||
masterKeyRotateCmd.Flags().StringVarP(&newMasterKeyFile, "new-key", "n", "", "Path to file containing the new master key (base64 encoded).")
|
||||
}
|
||||
|
||||
var masterKeyCmd = &cobra.Command{
|
||||
Use: "master-key",
|
||||
Short: "Master encryption key management",
|
||||
Long: "Manage master encryption keys for file encryption. Use subcommands to generate, get, or rotate keys.",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
_ = cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
var masterKeyGenerateCmd = &cobra.Command{
|
||||
Use: "generate",
|
||||
Short: "Generate a new master encryption key",
|
||||
Long: "Generate a new random 32-byte (256-bit) master encryption key and output it in base64 format.",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
// Generate 32-byte random key
|
||||
key := make([]byte, 32)
|
||||
if _, err := io.ReadFull(rand.Reader, key); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: Failed to generate random key: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Encode to base64
|
||||
encodedKey := base64.StdEncoding.EncodeToString(key)
|
||||
|
||||
if outputToFile != "" {
|
||||
// Write to file
|
||||
if err := os.WriteFile(outputToFile, []byte(encodedKey), 0600); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Error: Failed to write key to file: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Printf("Master key generated and saved to: %s\n", outputToFile)
|
||||
} else {
|
||||
// Output to stdout
|
||||
fmt.Println(encodedKey)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
var masterKeyGetCmd = &cobra.Command{
|
||||
Use: "get",
|
||||
Short: "Get the current master encryption key",
|
||||
Long: "Retrieve and display the current master encryption key from the configured vault (setting, env, or file).",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
ctx := context.Background()
|
||||
dep := dependency.NewDependency(
|
||||
dependency.WithConfigPath(confPath),
|
||||
)
|
||||
logger := dep.Logger()
|
||||
|
||||
// Get the master key vault
|
||||
vault := encrypt.NewMasterEncryptKeyVault(ctx, dep.SettingProvider())
|
||||
|
||||
// Retrieve the master key
|
||||
key, err := vault.GetMasterKey(ctx)
|
||||
if err != nil {
|
||||
logger.Error("Failed to get master key: %s", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Encode to base64 and display
|
||||
encodedKey := base64.StdEncoding.EncodeToString(key)
|
||||
fmt.Println("")
|
||||
fmt.Println(encodedKey)
|
||||
},
|
||||
}
|
||||
|
||||
var masterKeyRotateCmd = &cobra.Command{
|
||||
Use: "rotate",
|
||||
Short: "Rotate the master encryption key",
|
||||
Long: `Rotate the master encryption key by re-encrypting all encrypted file keys with a new master key.
|
||||
This operation:
|
||||
1. Retrieves the current master key
|
||||
2. Loads a new master key from file
|
||||
3. Re-encrypts all file encryption keys with the new master key
|
||||
4. Updates the master key in the settings database
|
||||
|
||||
Warning: This is a critical operation. Make sure to backup your database before proceeding.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
ctx := context.Background()
|
||||
dep := dependency.NewDependency(
|
||||
dependency.WithConfigPath(confPath),
|
||||
)
|
||||
logger := dep.Logger()
|
||||
|
||||
logger.Info("Starting master key rotation...")
|
||||
|
||||
// Get the old master key
|
||||
vault := encrypt.NewMasterEncryptKeyVault(ctx, dep.SettingProvider())
|
||||
oldMasterKey, err := vault.GetMasterKey(ctx)
|
||||
if err != nil {
|
||||
logger.Error("Failed to get current master key: %s", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
logger.Info("Retrieved current master key")
|
||||
|
||||
// Get or generate the new master key
|
||||
var newMasterKey []byte
|
||||
// Load from file
|
||||
keyData, err := os.ReadFile(newMasterKeyFile)
|
||||
if err != nil {
|
||||
logger.Error("Failed to read new master key file: %s", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
newMasterKey, err = base64.StdEncoding.DecodeString(string(keyData))
|
||||
if err != nil {
|
||||
logger.Error("Failed to decode new master key: %s", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if len(newMasterKey) != 32 {
|
||||
logger.Error("Invalid new master key: must be 32 bytes (256 bits), got %d bytes", len(newMasterKey))
|
||||
os.Exit(1)
|
||||
}
|
||||
logger.Info("Loaded new master key from file: %s", newMasterKeyFile)
|
||||
|
||||
// Query all entities with encryption metadata
|
||||
db := dep.DBClient()
|
||||
entities, err := db.Entity.Query().
|
||||
Where(entity.Not(entity.PropsIsNil())).
|
||||
All(ctx)
|
||||
if err != nil {
|
||||
logger.Error("Failed to query entities: %s", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
logger.Info("Found %d entities to check for encryption", len(entities))
|
||||
|
||||
// Re-encrypt each entity's encryption key
|
||||
encryptedCount := 0
|
||||
for _, ent := range entities {
|
||||
if ent.Props == nil || ent.Props.EncryptMetadata == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
encMeta := ent.Props.EncryptMetadata
|
||||
|
||||
// Decrypt the file key with old master key
|
||||
decryptedFileKey, err := encrypt.DecryptWithMasterKey(oldMasterKey, encMeta.Key)
|
||||
if err != nil {
|
||||
logger.Error("Failed to decrypt key for entity %d: %s", ent.ID, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Re-encrypt the file key with new master key
|
||||
newEncryptedKey, err := encrypt.EncryptWithMasterKey(newMasterKey, decryptedFileKey)
|
||||
if err != nil {
|
||||
logger.Error("Failed to re-encrypt key for entity %d: %s", ent.ID, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Update the entity
|
||||
newProps := *ent.Props
|
||||
newProps.EncryptMetadata = &types.EncryptMetadata{
|
||||
Algorithm: encMeta.Algorithm,
|
||||
Key: newEncryptedKey,
|
||||
KeyPlainText: nil, // Don't store plaintext
|
||||
IV: encMeta.IV,
|
||||
}
|
||||
|
||||
err = db.Entity.UpdateOne(ent).
|
||||
SetProps(&newProps).
|
||||
Exec(ctx)
|
||||
if err != nil {
|
||||
logger.Error("Failed to update entity %d: %s", ent.ID, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
encryptedCount++
|
||||
}
|
||||
|
||||
logger.Info("Re-encrypted %d file keys", encryptedCount)
|
||||
|
||||
// Update the master key in settings
|
||||
keyStore := dep.SettingProvider().MasterEncryptKeyVault(ctx)
|
||||
if keyStore == setting.MasterEncryptKeyVaultTypeSetting {
|
||||
encodedNewKey := base64.StdEncoding.EncodeToString(newMasterKey)
|
||||
err = dep.SettingClient().Set(ctx, map[string]string{
|
||||
"encrypt_master_key": encodedNewKey,
|
||||
})
|
||||
if err != nil {
|
||||
logger.Error("Failed to update master key in settings: %s", err)
|
||||
logger.Error("WARNING: File keys have been re-encrypted but master key update failed!")
|
||||
logger.Error("Please manually update the encrypt_master_key setting.")
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
logger.Info("Current master key is stored in %q", keyStore)
|
||||
if keyStore == setting.MasterEncryptKeyVaultTypeEnv {
|
||||
logger.Info("Please update the new master encryption key in your \"CR_ENCRYPT_MASTER_KEY\" environment variable.")
|
||||
} else if keyStore == setting.MasterEncryptKeyVaultTypeFile {
|
||||
logger.Info("Please update the new master encryption key in your key file: %q", dep.SettingProvider().MasterEncryptKeyFile(ctx))
|
||||
}
|
||||
logger.Info("Last step: Please manually update the new master encryption key in your ENV or key file.")
|
||||
}
|
||||
|
||||
logger.Info("Master key rotation completed successfully")
|
||||
},
|
||||
}
|
||||
69
cmd/migrate.go
Normal file
69
cmd/migrate.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/application/constants"
|
||||
"github.com/cloudreve/Cloudreve/v4/application/dependency"
|
||||
"github.com/cloudreve/Cloudreve/v4/application/migrator"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/util"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
v3ConfPath string
|
||||
forceReset bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(migrateCmd)
|
||||
migrateCmd.PersistentFlags().StringVar(&v3ConfPath, "v3-conf", "", "Path to the v3 config file")
|
||||
migrateCmd.PersistentFlags().BoolVar(&forceReset, "force-reset", false, "Force reset migration state and start from beginning")
|
||||
}
|
||||
|
||||
var migrateCmd = &cobra.Command{
|
||||
Use: "migrate",
|
||||
Short: "Migrate from v3 to v4",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
dep := dependency.NewDependency(
|
||||
dependency.WithConfigPath(confPath),
|
||||
dependency.WithRequiredDbVersion(constants.BackendVersion),
|
||||
dependency.WithProFlag(constants.IsPro == "true"),
|
||||
)
|
||||
logger := dep.Logger()
|
||||
logger.Info("Migrating from v3 to v4...")
|
||||
|
||||
if v3ConfPath == "" {
|
||||
logger.Error("v3 config file is required, please use -v3-conf to specify the path.")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Check if state file exists and warn about resuming
|
||||
stateFilePath := filepath.Join(filepath.Dir(v3ConfPath), "migration_state.json")
|
||||
if util.Exists(stateFilePath) && !forceReset {
|
||||
logger.Info("Found existing migration state file at %s. Migration will resume from the last successful step.", stateFilePath)
|
||||
logger.Info("If you want to start migration from the beginning, please use --force-reset flag.")
|
||||
} else if forceReset && util.Exists(stateFilePath) {
|
||||
logger.Info("Force resetting migration state. Will start from the beginning.")
|
||||
if err := os.Remove(stateFilePath); err != nil {
|
||||
logger.Error("Failed to remove migration state file: %s", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
migrator, err := migrator.NewMigrator(dep, v3ConfPath)
|
||||
if err != nil {
|
||||
logger.Error("Failed to create migrator: %s", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err := migrator.Migrate(); err != nil {
|
||||
logger.Error("Failed to migrate: %s", err)
|
||||
logger.Info("Migration failed but state has been saved. You can retry with the same command to resume from the last successful step.")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
logger.Info("Migration from v3 to v4 completed successfully.")
|
||||
},
|
||||
}
|
||||
44
cmd/root.go
Normal file
44
cmd/root.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/util"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
var (
|
||||
confPath string
|
||||
licenseKey string
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.PersistentFlags().StringVarP(&confPath, "conf", "c", util.DataPath("conf.ini"), "Path to the config file")
|
||||
rootCmd.PersistentFlags().BoolVarP(&util.UseWorkingDir, "use-working-dir", "w", false, "Use working directory, instead of executable directory")
|
||||
}
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "cloudreve",
|
||||
Short: "Cloudreve is a server-side self-hosted cloud storage platform",
|
||||
Long: `Self-hosted file management and sharing system, supports multiple storage providers.
|
||||
Complete documentation is available at https://docs.cloudreve.org/`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
// Do Stuff Here
|
||||
},
|
||||
}
|
||||
|
||||
func Execute() {
|
||||
cmd, _, err := rootCmd.Find(os.Args[1:])
|
||||
// redirect to default server cmd if no cmd is given
|
||||
if err == nil && cmd.Use == rootCmd.Use && cmd.Flags().Parse(os.Args[1:]) != pflag.ErrHelp {
|
||||
args := append([]string{"server"}, os.Args[1:]...)
|
||||
rootCmd.SetArgs(args)
|
||||
}
|
||||
|
||||
if err := rootCmd.Execute(); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
55
cmd/server.go
Normal file
55
cmd/server.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/application"
|
||||
"github.com/cloudreve/Cloudreve/v4/application/constants"
|
||||
"github.com/cloudreve/Cloudreve/v4/application/dependency"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/logging"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(serverCmd)
|
||||
serverCmd.PersistentFlags().StringVarP(&licenseKey, "license-key", "l", "", "License key of your Cloudreve Pro")
|
||||
}
|
||||
|
||||
var serverCmd = &cobra.Command{
|
||||
Use: "server",
|
||||
Short: "Start a Cloudreve server with the given config file",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
dep := dependency.NewDependency(
|
||||
dependency.WithConfigPath(confPath),
|
||||
dependency.WithProFlag(constants.IsProBool),
|
||||
dependency.WithRequiredDbVersion(constants.BackendVersion),
|
||||
)
|
||||
server := application.NewServer(dep)
|
||||
logger := dep.Logger()
|
||||
|
||||
server.PrintBanner()
|
||||
|
||||
// Graceful shutdown after received signal.
|
||||
sigChan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGQUIT)
|
||||
go shutdown(sigChan, logger, server)
|
||||
|
||||
if err := server.Start(); err != nil {
|
||||
logger.Error("Failed to start server: %s", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
<-sigChan
|
||||
}()
|
||||
},
|
||||
}
|
||||
|
||||
func shutdown(sigChan chan os.Signal, logger logging.Logger, server application.Server) {
|
||||
sig := <-sigChan
|
||||
logger.Info("Signal %s received, shutting down server...", sig)
|
||||
server.Close()
|
||||
close(sigChan)
|
||||
}
|
||||
@@ -1,33 +1,47 @@
|
||||
version: "3.8"
|
||||
services:
|
||||
cloudreve:
|
||||
container_name: cloudreve
|
||||
image: cloudreve/cloudreve:latest
|
||||
container_name: cloudreve-backend
|
||||
depends_on:
|
||||
- postgresql
|
||||
- redis
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "5212:5212"
|
||||
- 5212:5212
|
||||
- 6888:6888
|
||||
- 6888:6888/udp
|
||||
environment:
|
||||
- CR_CONF_Database.Type=postgres
|
||||
- CR_CONF_Database.Host=postgresql
|
||||
- CR_CONF_Database.User=cloudreve
|
||||
- CR_CONF_Database.Name=cloudreve
|
||||
- CR_CONF_Database.Port=5432
|
||||
- CR_CONF_Redis.Server=redis:6379
|
||||
volumes:
|
||||
- temp_data:/data
|
||||
- ./cloudreve/uploads:/cloudreve/uploads
|
||||
- ./cloudreve/conf.ini:/cloudreve/conf.ini
|
||||
- ./cloudreve/cloudreve.db:/cloudreve/cloudreve.db
|
||||
- ./cloudreve/avatar:/cloudreve/avatar
|
||||
depends_on:
|
||||
- aria2
|
||||
aria2:
|
||||
container_name: aria2
|
||||
image: p3terx/aria2-pro # third party image, please keep notice what you are doing
|
||||
- backend_data:/cloudreve/data
|
||||
|
||||
postgresql:
|
||||
# Best practice: Pin to major version.
|
||||
# NOTE: For major version jumps:
|
||||
# backup & consult https://www.postgresql.org/docs/current/pgupgrade.html
|
||||
image: postgres:17
|
||||
container_name: postgresql
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- RPC_SECRET=your_aria_rpc_token # aria rpc token, customize your own
|
||||
- RPC_PORT=6800
|
||||
- POSTGRES_USER=cloudreve
|
||||
- POSTGRES_DB=cloudreve
|
||||
- POSTGRES_HOST_AUTH_METHOD=trust
|
||||
volumes:
|
||||
- ./aria2/config:/config
|
||||
- temp_data:/data
|
||||
- database_postgres:/var/lib/postgresql/data
|
||||
|
||||
redis:
|
||||
image: redis:latest
|
||||
container_name: redis
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
|
||||
volumes:
|
||||
temp_data:
|
||||
driver: local
|
||||
driver_opts:
|
||||
type: none
|
||||
device: $PWD/data
|
||||
o: bind
|
||||
backend_data:
|
||||
database_postgres:
|
||||
redis_data:
|
||||
|
||||
3137
ent/client.go
Normal file
3137
ent/client.go
Normal file
File diff suppressed because it is too large
Load Diff
242
ent/davaccount.go
Normal file
242
ent/davaccount.go
Normal file
@@ -0,0 +1,242 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/davaccount"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/user"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/boolset"
|
||||
)
|
||||
|
||||
// DavAccount is the model entity for the DavAccount schema.
|
||||
type DavAccount struct {
|
||||
config `json:"-"`
|
||||
// ID of the ent.
|
||||
ID int `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"`
|
||||
// DeletedAt holds the value of the "deleted_at" field.
|
||||
DeletedAt *time.Time `json:"deleted_at,omitempty"`
|
||||
// Name holds the value of the "name" field.
|
||||
Name string `json:"name,omitempty"`
|
||||
// URI holds the value of the "uri" field.
|
||||
URI string `json:"uri,omitempty"`
|
||||
// Password holds the value of the "password" field.
|
||||
Password string `json:"-"`
|
||||
// Options holds the value of the "options" field.
|
||||
Options *boolset.BooleanSet `json:"options,omitempty"`
|
||||
// Props holds the value of the "props" field.
|
||||
Props *types.DavAccountProps `json:"props,omitempty"`
|
||||
// OwnerID holds the value of the "owner_id" field.
|
||||
OwnerID int `json:"owner_id,omitempty"`
|
||||
// Edges holds the relations/edges for other nodes in the graph.
|
||||
// The values are being populated by the DavAccountQuery when eager-loading is set.
|
||||
Edges DavAccountEdges `json:"edges"`
|
||||
selectValues sql.SelectValues
|
||||
}
|
||||
|
||||
// DavAccountEdges holds the relations/edges for other nodes in the graph.
|
||||
type DavAccountEdges struct {
|
||||
// Owner holds the value of the owner edge.
|
||||
Owner *User `json:"owner,omitempty"`
|
||||
// loadedTypes holds the information for reporting if a
|
||||
// type was loaded (or requested) in eager-loading or not.
|
||||
loadedTypes [1]bool
|
||||
}
|
||||
|
||||
// OwnerOrErr returns the Owner value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e DavAccountEdges) OwnerOrErr() (*User, error) {
|
||||
if e.loadedTypes[0] {
|
||||
if e.Owner == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: user.Label}
|
||||
}
|
||||
return e.Owner, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "owner"}
|
||||
}
|
||||
|
||||
// scanValues returns the types for scanning values from sql.Rows.
|
||||
func (*DavAccount) scanValues(columns []string) ([]any, error) {
|
||||
values := make([]any, len(columns))
|
||||
for i := range columns {
|
||||
switch columns[i] {
|
||||
case davaccount.FieldProps:
|
||||
values[i] = new([]byte)
|
||||
case davaccount.FieldOptions:
|
||||
values[i] = new(boolset.BooleanSet)
|
||||
case davaccount.FieldID, davaccount.FieldOwnerID:
|
||||
values[i] = new(sql.NullInt64)
|
||||
case davaccount.FieldName, davaccount.FieldURI, davaccount.FieldPassword:
|
||||
values[i] = new(sql.NullString)
|
||||
case davaccount.FieldCreatedAt, davaccount.FieldUpdatedAt, davaccount.FieldDeletedAt:
|
||||
values[i] = new(sql.NullTime)
|
||||
default:
|
||||
values[i] = new(sql.UnknownType)
|
||||
}
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// assignValues assigns the values that were returned from sql.Rows (after scanning)
|
||||
// to the DavAccount fields.
|
||||
func (da *DavAccount) 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 davaccount.FieldID:
|
||||
value, ok := values[i].(*sql.NullInt64)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field id", value)
|
||||
}
|
||||
da.ID = int(value.Int64)
|
||||
case davaccount.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 {
|
||||
da.CreatedAt = value.Time
|
||||
}
|
||||
case davaccount.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 {
|
||||
da.UpdatedAt = value.Time
|
||||
}
|
||||
case davaccount.FieldDeletedAt:
|
||||
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field deleted_at", values[i])
|
||||
} else if value.Valid {
|
||||
da.DeletedAt = new(time.Time)
|
||||
*da.DeletedAt = value.Time
|
||||
}
|
||||
case davaccount.FieldName:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field name", values[i])
|
||||
} else if value.Valid {
|
||||
da.Name = value.String
|
||||
}
|
||||
case davaccount.FieldURI:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field uri", values[i])
|
||||
} else if value.Valid {
|
||||
da.URI = value.String
|
||||
}
|
||||
case davaccount.FieldPassword:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field password", values[i])
|
||||
} else if value.Valid {
|
||||
da.Password = value.String
|
||||
}
|
||||
case davaccount.FieldOptions:
|
||||
if value, ok := values[i].(*boolset.BooleanSet); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field options", values[i])
|
||||
} else if value != nil {
|
||||
da.Options = value
|
||||
}
|
||||
case davaccount.FieldProps:
|
||||
if value, ok := values[i].(*[]byte); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field props", values[i])
|
||||
} else if value != nil && len(*value) > 0 {
|
||||
if err := json.Unmarshal(*value, &da.Props); err != nil {
|
||||
return fmt.Errorf("unmarshal field props: %w", err)
|
||||
}
|
||||
}
|
||||
case davaccount.FieldOwnerID:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field owner_id", values[i])
|
||||
} else if value.Valid {
|
||||
da.OwnerID = int(value.Int64)
|
||||
}
|
||||
default:
|
||||
da.selectValues.Set(columns[i], values[i])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value returns the ent.Value that was dynamically selected and assigned to the DavAccount.
|
||||
// This includes values selected through modifiers, order, etc.
|
||||
func (da *DavAccount) Value(name string) (ent.Value, error) {
|
||||
return da.selectValues.Get(name)
|
||||
}
|
||||
|
||||
// QueryOwner queries the "owner" edge of the DavAccount entity.
|
||||
func (da *DavAccount) QueryOwner() *UserQuery {
|
||||
return NewDavAccountClient(da.config).QueryOwner(da)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this DavAccount.
|
||||
// Note that you need to call DavAccount.Unwrap() before calling this method if this DavAccount
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (da *DavAccount) Update() *DavAccountUpdateOne {
|
||||
return NewDavAccountClient(da.config).UpdateOne(da)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the DavAccount 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 (da *DavAccount) Unwrap() *DavAccount {
|
||||
_tx, ok := da.config.driver.(*txDriver)
|
||||
if !ok {
|
||||
panic("ent: DavAccount is not a transactional entity")
|
||||
}
|
||||
da.config.driver = _tx.drv
|
||||
return da
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer.
|
||||
func (da *DavAccount) String() string {
|
||||
var builder strings.Builder
|
||||
builder.WriteString("DavAccount(")
|
||||
builder.WriteString(fmt.Sprintf("id=%v, ", da.ID))
|
||||
builder.WriteString("created_at=")
|
||||
builder.WriteString(da.CreatedAt.Format(time.ANSIC))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("updated_at=")
|
||||
builder.WriteString(da.UpdatedAt.Format(time.ANSIC))
|
||||
builder.WriteString(", ")
|
||||
if v := da.DeletedAt; v != nil {
|
||||
builder.WriteString("deleted_at=")
|
||||
builder.WriteString(v.Format(time.ANSIC))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("name=")
|
||||
builder.WriteString(da.Name)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("uri=")
|
||||
builder.WriteString(da.URI)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("password=<sensitive>")
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("options=")
|
||||
builder.WriteString(fmt.Sprintf("%v", da.Options))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("props=")
|
||||
builder.WriteString(fmt.Sprintf("%v", da.Props))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("owner_id=")
|
||||
builder.WriteString(fmt.Sprintf("%v", da.OwnerID))
|
||||
builder.WriteByte(')')
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
// SetOwner manually set the edge as loaded state.
|
||||
func (e *DavAccount) SetOwner(v *User) {
|
||||
e.Edges.Owner = v
|
||||
e.Edges.loadedTypes[0] = true
|
||||
}
|
||||
|
||||
// DavAccounts is a parsable slice of DavAccount.
|
||||
type DavAccounts []*DavAccount
|
||||
144
ent/davaccount/davaccount.go
Normal file
144
ent/davaccount/davaccount.go
Normal file
@@ -0,0 +1,144 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package davaccount
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
)
|
||||
|
||||
const (
|
||||
// Label holds the string label denoting the davaccount type in the database.
|
||||
Label = "dav_account"
|
||||
// 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"
|
||||
// FieldDeletedAt holds the string denoting the deleted_at field in the database.
|
||||
FieldDeletedAt = "deleted_at"
|
||||
// FieldName holds the string denoting the name field in the database.
|
||||
FieldName = "name"
|
||||
// FieldURI holds the string denoting the uri field in the database.
|
||||
FieldURI = "uri"
|
||||
// FieldPassword holds the string denoting the password field in the database.
|
||||
FieldPassword = "password"
|
||||
// FieldOptions holds the string denoting the options field in the database.
|
||||
FieldOptions = "options"
|
||||
// FieldProps holds the string denoting the props field in the database.
|
||||
FieldProps = "props"
|
||||
// FieldOwnerID holds the string denoting the owner_id field in the database.
|
||||
FieldOwnerID = "owner_id"
|
||||
// EdgeOwner holds the string denoting the owner edge name in mutations.
|
||||
EdgeOwner = "owner"
|
||||
// Table holds the table name of the davaccount in the database.
|
||||
Table = "dav_accounts"
|
||||
// OwnerTable is the table that holds the owner relation/edge.
|
||||
OwnerTable = "dav_accounts"
|
||||
// OwnerInverseTable is the table name for the User entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "user" package.
|
||||
OwnerInverseTable = "users"
|
||||
// OwnerColumn is the table column denoting the owner relation/edge.
|
||||
OwnerColumn = "owner_id"
|
||||
)
|
||||
|
||||
// Columns holds all SQL columns for davaccount fields.
|
||||
var Columns = []string{
|
||||
FieldID,
|
||||
FieldCreatedAt,
|
||||
FieldUpdatedAt,
|
||||
FieldDeletedAt,
|
||||
FieldName,
|
||||
FieldURI,
|
||||
FieldPassword,
|
||||
FieldOptions,
|
||||
FieldProps,
|
||||
FieldOwnerID,
|
||||
}
|
||||
|
||||
// ValidColumn reports if the column name is valid (part of the table columns).
|
||||
func ValidColumn(column string) bool {
|
||||
for i := range Columns {
|
||||
if column == Columns[i] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Note that the variables below are initialized by the runtime
|
||||
// package on the initialization of the application. Therefore,
|
||||
// it should be imported in the main as follows:
|
||||
//
|
||||
// import _ "github.com/cloudreve/Cloudreve/v4/ent/runtime"
|
||||
var (
|
||||
Hooks [1]ent.Hook
|
||||
Interceptors [1]ent.Interceptor
|
||||
// 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
|
||||
)
|
||||
|
||||
// OrderOption defines the ordering options for the DavAccount queries.
|
||||
type OrderOption func(*sql.Selector)
|
||||
|
||||
// ByID orders the results by the id field.
|
||||
func ByID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByCreatedAt orders the results by the created_at field.
|
||||
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByUpdatedAt orders the results by the updated_at field.
|
||||
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByDeletedAt orders the results by the deleted_at field.
|
||||
func ByDeletedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldDeletedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByName orders the results by the name field.
|
||||
func ByName(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldName, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByURI orders the results by the uri field.
|
||||
func ByURI(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldURI, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByPassword orders the results by the password field.
|
||||
func ByPassword(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldPassword, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByOwnerID orders the results by the owner_id field.
|
||||
func ByOwnerID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldOwnerID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByOwnerField orders the results by owner field.
|
||||
func ByOwnerField(field string, opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborTerms(s, newOwnerStep(), sql.OrderByField(field, opts...))
|
||||
}
|
||||
}
|
||||
func newOwnerStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(OwnerInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, OwnerTable, OwnerColumn),
|
||||
)
|
||||
}
|
||||
530
ent/davaccount/where.go
Normal file
530
ent/davaccount/where.go
Normal file
@@ -0,0 +1,530 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package davaccount
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/boolset"
|
||||
)
|
||||
|
||||
// ID filters vertices based on their ID field.
|
||||
func ID(id int) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDEQ applies the EQ predicate on the ID field.
|
||||
func IDEQ(id int) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDNEQ applies the NEQ predicate on the ID field.
|
||||
func IDNEQ(id int) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldNEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDIn applies the In predicate on the ID field.
|
||||
func IDIn(ids ...int) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDNotIn applies the NotIn predicate on the ID field.
|
||||
func IDNotIn(ids ...int) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldNotIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDGT applies the GT predicate on the ID field.
|
||||
func IDGT(id int) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldGT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDGTE applies the GTE predicate on the ID field.
|
||||
func IDGTE(id int) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldGTE(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLT applies the LT predicate on the ID field.
|
||||
func IDLT(id int) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldLT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLTE applies the LTE predicate on the ID field.
|
||||
func IDLTE(id int) predicate.DavAccount {
|
||||
return predicate.DavAccount(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.DavAccount {
|
||||
return predicate.DavAccount(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.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAt applies equality check predicate on the "deleted_at" field. It's identical to DeletedAtEQ.
|
||||
func DeletedAt(v time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldEQ(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// Name applies equality check predicate on the "name" field. It's identical to NameEQ.
|
||||
func Name(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldEQ(FieldName, v))
|
||||
}
|
||||
|
||||
// URI applies equality check predicate on the "uri" field. It's identical to URIEQ.
|
||||
func URI(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldEQ(FieldURI, v))
|
||||
}
|
||||
|
||||
// Password applies equality check predicate on the "password" field. It's identical to PasswordEQ.
|
||||
func Password(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldEQ(FieldPassword, v))
|
||||
}
|
||||
|
||||
// Options applies equality check predicate on the "options" field. It's identical to OptionsEQ.
|
||||
func Options(v *boolset.BooleanSet) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldEQ(FieldOptions, v))
|
||||
}
|
||||
|
||||
// OwnerID applies equality check predicate on the "owner_id" field. It's identical to OwnerIDEQ.
|
||||
func OwnerID(v int) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldEQ(FieldOwnerID, v))
|
||||
}
|
||||
|
||||
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
|
||||
func CreatedAtEQ(v time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
|
||||
func CreatedAtNEQ(v time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldNEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtIn applies the In predicate on the "created_at" field.
|
||||
func CreatedAtIn(vs ...time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldIn(FieldCreatedAt, vs...))
|
||||
}
|
||||
|
||||
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
|
||||
func CreatedAtNotIn(vs ...time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldNotIn(FieldCreatedAt, vs...))
|
||||
}
|
||||
|
||||
// CreatedAtGT applies the GT predicate on the "created_at" field.
|
||||
func CreatedAtGT(v time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldGT(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
|
||||
func CreatedAtGTE(v time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldGTE(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtLT applies the LT predicate on the "created_at" field.
|
||||
func CreatedAtLT(v time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldLT(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
|
||||
func CreatedAtLTE(v time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldLTE(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
|
||||
func UpdatedAtEQ(v time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
|
||||
func UpdatedAtNEQ(v time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldNEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtIn applies the In predicate on the "updated_at" field.
|
||||
func UpdatedAtIn(vs ...time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldIn(FieldUpdatedAt, vs...))
|
||||
}
|
||||
|
||||
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
|
||||
func UpdatedAtNotIn(vs ...time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldNotIn(FieldUpdatedAt, vs...))
|
||||
}
|
||||
|
||||
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
|
||||
func UpdatedAtGT(v time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldGT(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
|
||||
func UpdatedAtGTE(v time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldGTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
|
||||
func UpdatedAtLT(v time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldLT(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
|
||||
func UpdatedAtLTE(v time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldLTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtEQ applies the EQ predicate on the "deleted_at" field.
|
||||
func DeletedAtEQ(v time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldEQ(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtNEQ applies the NEQ predicate on the "deleted_at" field.
|
||||
func DeletedAtNEQ(v time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldNEQ(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtIn applies the In predicate on the "deleted_at" field.
|
||||
func DeletedAtIn(vs ...time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldIn(FieldDeletedAt, vs...))
|
||||
}
|
||||
|
||||
// DeletedAtNotIn applies the NotIn predicate on the "deleted_at" field.
|
||||
func DeletedAtNotIn(vs ...time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldNotIn(FieldDeletedAt, vs...))
|
||||
}
|
||||
|
||||
// DeletedAtGT applies the GT predicate on the "deleted_at" field.
|
||||
func DeletedAtGT(v time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldGT(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtGTE applies the GTE predicate on the "deleted_at" field.
|
||||
func DeletedAtGTE(v time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldGTE(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtLT applies the LT predicate on the "deleted_at" field.
|
||||
func DeletedAtLT(v time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldLT(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtLTE applies the LTE predicate on the "deleted_at" field.
|
||||
func DeletedAtLTE(v time.Time) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldLTE(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtIsNil applies the IsNil predicate on the "deleted_at" field.
|
||||
func DeletedAtIsNil() predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldIsNull(FieldDeletedAt))
|
||||
}
|
||||
|
||||
// DeletedAtNotNil applies the NotNil predicate on the "deleted_at" field.
|
||||
func DeletedAtNotNil() predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldNotNull(FieldDeletedAt))
|
||||
}
|
||||
|
||||
// NameEQ applies the EQ predicate on the "name" field.
|
||||
func NameEQ(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldEQ(FieldName, v))
|
||||
}
|
||||
|
||||
// NameNEQ applies the NEQ predicate on the "name" field.
|
||||
func NameNEQ(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldNEQ(FieldName, v))
|
||||
}
|
||||
|
||||
// NameIn applies the In predicate on the "name" field.
|
||||
func NameIn(vs ...string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldIn(FieldName, vs...))
|
||||
}
|
||||
|
||||
// NameNotIn applies the NotIn predicate on the "name" field.
|
||||
func NameNotIn(vs ...string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldNotIn(FieldName, vs...))
|
||||
}
|
||||
|
||||
// NameGT applies the GT predicate on the "name" field.
|
||||
func NameGT(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldGT(FieldName, v))
|
||||
}
|
||||
|
||||
// NameGTE applies the GTE predicate on the "name" field.
|
||||
func NameGTE(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldGTE(FieldName, v))
|
||||
}
|
||||
|
||||
// NameLT applies the LT predicate on the "name" field.
|
||||
func NameLT(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldLT(FieldName, v))
|
||||
}
|
||||
|
||||
// NameLTE applies the LTE predicate on the "name" field.
|
||||
func NameLTE(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldLTE(FieldName, v))
|
||||
}
|
||||
|
||||
// NameContains applies the Contains predicate on the "name" field.
|
||||
func NameContains(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldContains(FieldName, v))
|
||||
}
|
||||
|
||||
// NameHasPrefix applies the HasPrefix predicate on the "name" field.
|
||||
func NameHasPrefix(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldHasPrefix(FieldName, v))
|
||||
}
|
||||
|
||||
// NameHasSuffix applies the HasSuffix predicate on the "name" field.
|
||||
func NameHasSuffix(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldHasSuffix(FieldName, v))
|
||||
}
|
||||
|
||||
// NameEqualFold applies the EqualFold predicate on the "name" field.
|
||||
func NameEqualFold(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldEqualFold(FieldName, v))
|
||||
}
|
||||
|
||||
// NameContainsFold applies the ContainsFold predicate on the "name" field.
|
||||
func NameContainsFold(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldContainsFold(FieldName, v))
|
||||
}
|
||||
|
||||
// URIEQ applies the EQ predicate on the "uri" field.
|
||||
func URIEQ(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldEQ(FieldURI, v))
|
||||
}
|
||||
|
||||
// URINEQ applies the NEQ predicate on the "uri" field.
|
||||
func URINEQ(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldNEQ(FieldURI, v))
|
||||
}
|
||||
|
||||
// URIIn applies the In predicate on the "uri" field.
|
||||
func URIIn(vs ...string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldIn(FieldURI, vs...))
|
||||
}
|
||||
|
||||
// URINotIn applies the NotIn predicate on the "uri" field.
|
||||
func URINotIn(vs ...string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldNotIn(FieldURI, vs...))
|
||||
}
|
||||
|
||||
// URIGT applies the GT predicate on the "uri" field.
|
||||
func URIGT(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldGT(FieldURI, v))
|
||||
}
|
||||
|
||||
// URIGTE applies the GTE predicate on the "uri" field.
|
||||
func URIGTE(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldGTE(FieldURI, v))
|
||||
}
|
||||
|
||||
// URILT applies the LT predicate on the "uri" field.
|
||||
func URILT(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldLT(FieldURI, v))
|
||||
}
|
||||
|
||||
// URILTE applies the LTE predicate on the "uri" field.
|
||||
func URILTE(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldLTE(FieldURI, v))
|
||||
}
|
||||
|
||||
// URIContains applies the Contains predicate on the "uri" field.
|
||||
func URIContains(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldContains(FieldURI, v))
|
||||
}
|
||||
|
||||
// URIHasPrefix applies the HasPrefix predicate on the "uri" field.
|
||||
func URIHasPrefix(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldHasPrefix(FieldURI, v))
|
||||
}
|
||||
|
||||
// URIHasSuffix applies the HasSuffix predicate on the "uri" field.
|
||||
func URIHasSuffix(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldHasSuffix(FieldURI, v))
|
||||
}
|
||||
|
||||
// URIEqualFold applies the EqualFold predicate on the "uri" field.
|
||||
func URIEqualFold(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldEqualFold(FieldURI, v))
|
||||
}
|
||||
|
||||
// URIContainsFold applies the ContainsFold predicate on the "uri" field.
|
||||
func URIContainsFold(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldContainsFold(FieldURI, v))
|
||||
}
|
||||
|
||||
// PasswordEQ applies the EQ predicate on the "password" field.
|
||||
func PasswordEQ(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldEQ(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordNEQ applies the NEQ predicate on the "password" field.
|
||||
func PasswordNEQ(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldNEQ(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordIn applies the In predicate on the "password" field.
|
||||
func PasswordIn(vs ...string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldIn(FieldPassword, vs...))
|
||||
}
|
||||
|
||||
// PasswordNotIn applies the NotIn predicate on the "password" field.
|
||||
func PasswordNotIn(vs ...string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldNotIn(FieldPassword, vs...))
|
||||
}
|
||||
|
||||
// PasswordGT applies the GT predicate on the "password" field.
|
||||
func PasswordGT(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldGT(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordGTE applies the GTE predicate on the "password" field.
|
||||
func PasswordGTE(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldGTE(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordLT applies the LT predicate on the "password" field.
|
||||
func PasswordLT(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldLT(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordLTE applies the LTE predicate on the "password" field.
|
||||
func PasswordLTE(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldLTE(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordContains applies the Contains predicate on the "password" field.
|
||||
func PasswordContains(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldContains(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordHasPrefix applies the HasPrefix predicate on the "password" field.
|
||||
func PasswordHasPrefix(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldHasPrefix(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordHasSuffix applies the HasSuffix predicate on the "password" field.
|
||||
func PasswordHasSuffix(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldHasSuffix(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordEqualFold applies the EqualFold predicate on the "password" field.
|
||||
func PasswordEqualFold(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldEqualFold(FieldPassword, v))
|
||||
}
|
||||
|
||||
// PasswordContainsFold applies the ContainsFold predicate on the "password" field.
|
||||
func PasswordContainsFold(v string) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldContainsFold(FieldPassword, v))
|
||||
}
|
||||
|
||||
// OptionsEQ applies the EQ predicate on the "options" field.
|
||||
func OptionsEQ(v *boolset.BooleanSet) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldEQ(FieldOptions, v))
|
||||
}
|
||||
|
||||
// OptionsNEQ applies the NEQ predicate on the "options" field.
|
||||
func OptionsNEQ(v *boolset.BooleanSet) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldNEQ(FieldOptions, v))
|
||||
}
|
||||
|
||||
// OptionsIn applies the In predicate on the "options" field.
|
||||
func OptionsIn(vs ...*boolset.BooleanSet) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldIn(FieldOptions, vs...))
|
||||
}
|
||||
|
||||
// OptionsNotIn applies the NotIn predicate on the "options" field.
|
||||
func OptionsNotIn(vs ...*boolset.BooleanSet) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldNotIn(FieldOptions, vs...))
|
||||
}
|
||||
|
||||
// OptionsGT applies the GT predicate on the "options" field.
|
||||
func OptionsGT(v *boolset.BooleanSet) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldGT(FieldOptions, v))
|
||||
}
|
||||
|
||||
// OptionsGTE applies the GTE predicate on the "options" field.
|
||||
func OptionsGTE(v *boolset.BooleanSet) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldGTE(FieldOptions, v))
|
||||
}
|
||||
|
||||
// OptionsLT applies the LT predicate on the "options" field.
|
||||
func OptionsLT(v *boolset.BooleanSet) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldLT(FieldOptions, v))
|
||||
}
|
||||
|
||||
// OptionsLTE applies the LTE predicate on the "options" field.
|
||||
func OptionsLTE(v *boolset.BooleanSet) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldLTE(FieldOptions, v))
|
||||
}
|
||||
|
||||
// PropsIsNil applies the IsNil predicate on the "props" field.
|
||||
func PropsIsNil() predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldIsNull(FieldProps))
|
||||
}
|
||||
|
||||
// PropsNotNil applies the NotNil predicate on the "props" field.
|
||||
func PropsNotNil() predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldNotNull(FieldProps))
|
||||
}
|
||||
|
||||
// OwnerIDEQ applies the EQ predicate on the "owner_id" field.
|
||||
func OwnerIDEQ(v int) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldEQ(FieldOwnerID, v))
|
||||
}
|
||||
|
||||
// OwnerIDNEQ applies the NEQ predicate on the "owner_id" field.
|
||||
func OwnerIDNEQ(v int) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldNEQ(FieldOwnerID, v))
|
||||
}
|
||||
|
||||
// OwnerIDIn applies the In predicate on the "owner_id" field.
|
||||
func OwnerIDIn(vs ...int) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldIn(FieldOwnerID, vs...))
|
||||
}
|
||||
|
||||
// OwnerIDNotIn applies the NotIn predicate on the "owner_id" field.
|
||||
func OwnerIDNotIn(vs ...int) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.FieldNotIn(FieldOwnerID, vs...))
|
||||
}
|
||||
|
||||
// HasOwner applies the HasEdge predicate on the "owner" edge.
|
||||
func HasOwner() predicate.DavAccount {
|
||||
return predicate.DavAccount(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, OwnerTable, OwnerColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasOwnerWith applies the HasEdge predicate on the "owner" edge with a given conditions (other predicates).
|
||||
func HasOwnerWith(preds ...predicate.User) predicate.DavAccount {
|
||||
return predicate.DavAccount(func(s *sql.Selector) {
|
||||
step := newOwnerStep()
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// And groups predicates with the AND operator between them.
|
||||
func And(predicates ...predicate.DavAccount) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.AndPredicates(predicates...))
|
||||
}
|
||||
|
||||
// Or groups predicates with the OR operator between them.
|
||||
func Or(predicates ...predicate.DavAccount) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.OrPredicates(predicates...))
|
||||
}
|
||||
|
||||
// Not applies the not operator on the given predicate.
|
||||
func Not(p predicate.DavAccount) predicate.DavAccount {
|
||||
return predicate.DavAccount(sql.NotPredicates(p))
|
||||
}
|
||||
968
ent/davaccount_create.go
Normal file
968
ent/davaccount_create.go
Normal file
@@ -0,0 +1,968 @@
|
||||
// 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/cloudreve/Cloudreve/v4/ent/davaccount"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/user"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/boolset"
|
||||
)
|
||||
|
||||
// DavAccountCreate is the builder for creating a DavAccount entity.
|
||||
type DavAccountCreate struct {
|
||||
config
|
||||
mutation *DavAccountMutation
|
||||
hooks []Hook
|
||||
conflict []sql.ConflictOption
|
||||
}
|
||||
|
||||
// SetCreatedAt sets the "created_at" field.
|
||||
func (dac *DavAccountCreate) SetCreatedAt(t time.Time) *DavAccountCreate {
|
||||
dac.mutation.SetCreatedAt(t)
|
||||
return dac
|
||||
}
|
||||
|
||||
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
|
||||
func (dac *DavAccountCreate) SetNillableCreatedAt(t *time.Time) *DavAccountCreate {
|
||||
if t != nil {
|
||||
dac.SetCreatedAt(*t)
|
||||
}
|
||||
return dac
|
||||
}
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (dac *DavAccountCreate) SetUpdatedAt(t time.Time) *DavAccountCreate {
|
||||
dac.mutation.SetUpdatedAt(t)
|
||||
return dac
|
||||
}
|
||||
|
||||
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
|
||||
func (dac *DavAccountCreate) SetNillableUpdatedAt(t *time.Time) *DavAccountCreate {
|
||||
if t != nil {
|
||||
dac.SetUpdatedAt(*t)
|
||||
}
|
||||
return dac
|
||||
}
|
||||
|
||||
// SetDeletedAt sets the "deleted_at" field.
|
||||
func (dac *DavAccountCreate) SetDeletedAt(t time.Time) *DavAccountCreate {
|
||||
dac.mutation.SetDeletedAt(t)
|
||||
return dac
|
||||
}
|
||||
|
||||
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
|
||||
func (dac *DavAccountCreate) SetNillableDeletedAt(t *time.Time) *DavAccountCreate {
|
||||
if t != nil {
|
||||
dac.SetDeletedAt(*t)
|
||||
}
|
||||
return dac
|
||||
}
|
||||
|
||||
// SetName sets the "name" field.
|
||||
func (dac *DavAccountCreate) SetName(s string) *DavAccountCreate {
|
||||
dac.mutation.SetName(s)
|
||||
return dac
|
||||
}
|
||||
|
||||
// SetURI sets the "uri" field.
|
||||
func (dac *DavAccountCreate) SetURI(s string) *DavAccountCreate {
|
||||
dac.mutation.SetURI(s)
|
||||
return dac
|
||||
}
|
||||
|
||||
// SetPassword sets the "password" field.
|
||||
func (dac *DavAccountCreate) SetPassword(s string) *DavAccountCreate {
|
||||
dac.mutation.SetPassword(s)
|
||||
return dac
|
||||
}
|
||||
|
||||
// SetOptions sets the "options" field.
|
||||
func (dac *DavAccountCreate) SetOptions(bs *boolset.BooleanSet) *DavAccountCreate {
|
||||
dac.mutation.SetOptions(bs)
|
||||
return dac
|
||||
}
|
||||
|
||||
// SetProps sets the "props" field.
|
||||
func (dac *DavAccountCreate) SetProps(tap *types.DavAccountProps) *DavAccountCreate {
|
||||
dac.mutation.SetProps(tap)
|
||||
return dac
|
||||
}
|
||||
|
||||
// SetOwnerID sets the "owner_id" field.
|
||||
func (dac *DavAccountCreate) SetOwnerID(i int) *DavAccountCreate {
|
||||
dac.mutation.SetOwnerID(i)
|
||||
return dac
|
||||
}
|
||||
|
||||
// SetOwner sets the "owner" edge to the User entity.
|
||||
func (dac *DavAccountCreate) SetOwner(u *User) *DavAccountCreate {
|
||||
return dac.SetOwnerID(u.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the DavAccountMutation object of the builder.
|
||||
func (dac *DavAccountCreate) Mutation() *DavAccountMutation {
|
||||
return dac.mutation
|
||||
}
|
||||
|
||||
// Save creates the DavAccount in the database.
|
||||
func (dac *DavAccountCreate) Save(ctx context.Context) (*DavAccount, error) {
|
||||
if err := dac.defaults(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return withHooks(ctx, dac.sqlSave, dac.mutation, dac.hooks)
|
||||
}
|
||||
|
||||
// SaveX calls Save and panics if Save returns an error.
|
||||
func (dac *DavAccountCreate) SaveX(ctx context.Context) *DavAccount {
|
||||
v, err := dac.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (dac *DavAccountCreate) Exec(ctx context.Context) error {
|
||||
_, err := dac.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (dac *DavAccountCreate) ExecX(ctx context.Context) {
|
||||
if err := dac.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (dac *DavAccountCreate) defaults() error {
|
||||
if _, ok := dac.mutation.CreatedAt(); !ok {
|
||||
if davaccount.DefaultCreatedAt == nil {
|
||||
return fmt.Errorf("ent: uninitialized davaccount.DefaultCreatedAt (forgotten import ent/runtime?)")
|
||||
}
|
||||
v := davaccount.DefaultCreatedAt()
|
||||
dac.mutation.SetCreatedAt(v)
|
||||
}
|
||||
if _, ok := dac.mutation.UpdatedAt(); !ok {
|
||||
if davaccount.DefaultUpdatedAt == nil {
|
||||
return fmt.Errorf("ent: uninitialized davaccount.DefaultUpdatedAt (forgotten import ent/runtime?)")
|
||||
}
|
||||
v := davaccount.DefaultUpdatedAt()
|
||||
dac.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (dac *DavAccountCreate) check() error {
|
||||
if _, ok := dac.mutation.CreatedAt(); !ok {
|
||||
return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "DavAccount.created_at"`)}
|
||||
}
|
||||
if _, ok := dac.mutation.UpdatedAt(); !ok {
|
||||
return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "DavAccount.updated_at"`)}
|
||||
}
|
||||
if _, ok := dac.mutation.Name(); !ok {
|
||||
return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "DavAccount.name"`)}
|
||||
}
|
||||
if _, ok := dac.mutation.URI(); !ok {
|
||||
return &ValidationError{Name: "uri", err: errors.New(`ent: missing required field "DavAccount.uri"`)}
|
||||
}
|
||||
if _, ok := dac.mutation.Password(); !ok {
|
||||
return &ValidationError{Name: "password", err: errors.New(`ent: missing required field "DavAccount.password"`)}
|
||||
}
|
||||
if _, ok := dac.mutation.Options(); !ok {
|
||||
return &ValidationError{Name: "options", err: errors.New(`ent: missing required field "DavAccount.options"`)}
|
||||
}
|
||||
if _, ok := dac.mutation.OwnerID(); !ok {
|
||||
return &ValidationError{Name: "owner_id", err: errors.New(`ent: missing required field "DavAccount.owner_id"`)}
|
||||
}
|
||||
if _, ok := dac.mutation.OwnerID(); !ok {
|
||||
return &ValidationError{Name: "owner", err: errors.New(`ent: missing required edge "DavAccount.owner"`)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dac *DavAccountCreate) sqlSave(ctx context.Context) (*DavAccount, error) {
|
||||
if err := dac.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_node, _spec := dac.createSpec()
|
||||
if err := sqlgraph.CreateNode(ctx, dac.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)
|
||||
dac.mutation.id = &_node.ID
|
||||
dac.mutation.done = true
|
||||
return _node, nil
|
||||
}
|
||||
|
||||
func (dac *DavAccountCreate) createSpec() (*DavAccount, *sqlgraph.CreateSpec) {
|
||||
var (
|
||||
_node = &DavAccount{config: dac.config}
|
||||
_spec = sqlgraph.NewCreateSpec(davaccount.Table, sqlgraph.NewFieldSpec(davaccount.FieldID, field.TypeInt))
|
||||
)
|
||||
|
||||
if id, ok := dac.mutation.ID(); ok {
|
||||
_node.ID = id
|
||||
id64 := int64(id)
|
||||
_spec.ID.Value = id64
|
||||
}
|
||||
|
||||
_spec.OnConflict = dac.conflict
|
||||
if value, ok := dac.mutation.CreatedAt(); ok {
|
||||
_spec.SetField(davaccount.FieldCreatedAt, field.TypeTime, value)
|
||||
_node.CreatedAt = value
|
||||
}
|
||||
if value, ok := dac.mutation.UpdatedAt(); ok {
|
||||
_spec.SetField(davaccount.FieldUpdatedAt, field.TypeTime, value)
|
||||
_node.UpdatedAt = value
|
||||
}
|
||||
if value, ok := dac.mutation.DeletedAt(); ok {
|
||||
_spec.SetField(davaccount.FieldDeletedAt, field.TypeTime, value)
|
||||
_node.DeletedAt = &value
|
||||
}
|
||||
if value, ok := dac.mutation.Name(); ok {
|
||||
_spec.SetField(davaccount.FieldName, field.TypeString, value)
|
||||
_node.Name = value
|
||||
}
|
||||
if value, ok := dac.mutation.URI(); ok {
|
||||
_spec.SetField(davaccount.FieldURI, field.TypeString, value)
|
||||
_node.URI = value
|
||||
}
|
||||
if value, ok := dac.mutation.Password(); ok {
|
||||
_spec.SetField(davaccount.FieldPassword, field.TypeString, value)
|
||||
_node.Password = value
|
||||
}
|
||||
if value, ok := dac.mutation.Options(); ok {
|
||||
_spec.SetField(davaccount.FieldOptions, field.TypeBytes, value)
|
||||
_node.Options = value
|
||||
}
|
||||
if value, ok := dac.mutation.Props(); ok {
|
||||
_spec.SetField(davaccount.FieldProps, field.TypeJSON, value)
|
||||
_node.Props = value
|
||||
}
|
||||
if nodes := dac.mutation.OwnerIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: davaccount.OwnerTable,
|
||||
Columns: []string{davaccount.OwnerColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_node.OwnerID = nodes[0]
|
||||
_spec.Edges = append(_spec.Edges, edge)
|
||||
}
|
||||
return _node, _spec
|
||||
}
|
||||
|
||||
// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
|
||||
// of the `INSERT` statement. For example:
|
||||
//
|
||||
// client.DavAccount.Create().
|
||||
// SetCreatedAt(v).
|
||||
// OnConflict(
|
||||
// // Update the row with the new values
|
||||
// // the was proposed for insertion.
|
||||
// sql.ResolveWithNewValues(),
|
||||
// ).
|
||||
// // Override some of the fields with custom
|
||||
// // update values.
|
||||
// Update(func(u *ent.DavAccountUpsert) {
|
||||
// SetCreatedAt(v+v).
|
||||
// }).
|
||||
// Exec(ctx)
|
||||
func (dac *DavAccountCreate) OnConflict(opts ...sql.ConflictOption) *DavAccountUpsertOne {
|
||||
dac.conflict = opts
|
||||
return &DavAccountUpsertOne{
|
||||
create: dac,
|
||||
}
|
||||
}
|
||||
|
||||
// OnConflictColumns calls `OnConflict` and configures the columns
|
||||
// as conflict target. Using this option is equivalent to using:
|
||||
//
|
||||
// client.DavAccount.Create().
|
||||
// OnConflict(sql.ConflictColumns(columns...)).
|
||||
// Exec(ctx)
|
||||
func (dac *DavAccountCreate) OnConflictColumns(columns ...string) *DavAccountUpsertOne {
|
||||
dac.conflict = append(dac.conflict, sql.ConflictColumns(columns...))
|
||||
return &DavAccountUpsertOne{
|
||||
create: dac,
|
||||
}
|
||||
}
|
||||
|
||||
type (
|
||||
// DavAccountUpsertOne is the builder for "upsert"-ing
|
||||
// one DavAccount node.
|
||||
DavAccountUpsertOne struct {
|
||||
create *DavAccountCreate
|
||||
}
|
||||
|
||||
// DavAccountUpsert is the "OnConflict" setter.
|
||||
DavAccountUpsert struct {
|
||||
*sql.UpdateSet
|
||||
}
|
||||
)
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (u *DavAccountUpsert) SetUpdatedAt(v time.Time) *DavAccountUpsert {
|
||||
u.Set(davaccount.FieldUpdatedAt, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsert) UpdateUpdatedAt() *DavAccountUpsert {
|
||||
u.SetExcluded(davaccount.FieldUpdatedAt)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetDeletedAt sets the "deleted_at" field.
|
||||
func (u *DavAccountUpsert) SetDeletedAt(v time.Time) *DavAccountUpsert {
|
||||
u.Set(davaccount.FieldDeletedAt, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsert) UpdateDeletedAt() *DavAccountUpsert {
|
||||
u.SetExcluded(davaccount.FieldDeletedAt)
|
||||
return u
|
||||
}
|
||||
|
||||
// ClearDeletedAt clears the value of the "deleted_at" field.
|
||||
func (u *DavAccountUpsert) ClearDeletedAt() *DavAccountUpsert {
|
||||
u.SetNull(davaccount.FieldDeletedAt)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetName sets the "name" field.
|
||||
func (u *DavAccountUpsert) SetName(v string) *DavAccountUpsert {
|
||||
u.Set(davaccount.FieldName, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateName sets the "name" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsert) UpdateName() *DavAccountUpsert {
|
||||
u.SetExcluded(davaccount.FieldName)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetURI sets the "uri" field.
|
||||
func (u *DavAccountUpsert) SetURI(v string) *DavAccountUpsert {
|
||||
u.Set(davaccount.FieldURI, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateURI sets the "uri" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsert) UpdateURI() *DavAccountUpsert {
|
||||
u.SetExcluded(davaccount.FieldURI)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetPassword sets the "password" field.
|
||||
func (u *DavAccountUpsert) SetPassword(v string) *DavAccountUpsert {
|
||||
u.Set(davaccount.FieldPassword, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdatePassword sets the "password" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsert) UpdatePassword() *DavAccountUpsert {
|
||||
u.SetExcluded(davaccount.FieldPassword)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetOptions sets the "options" field.
|
||||
func (u *DavAccountUpsert) SetOptions(v *boolset.BooleanSet) *DavAccountUpsert {
|
||||
u.Set(davaccount.FieldOptions, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateOptions sets the "options" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsert) UpdateOptions() *DavAccountUpsert {
|
||||
u.SetExcluded(davaccount.FieldOptions)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetProps sets the "props" field.
|
||||
func (u *DavAccountUpsert) SetProps(v *types.DavAccountProps) *DavAccountUpsert {
|
||||
u.Set(davaccount.FieldProps, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateProps sets the "props" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsert) UpdateProps() *DavAccountUpsert {
|
||||
u.SetExcluded(davaccount.FieldProps)
|
||||
return u
|
||||
}
|
||||
|
||||
// ClearProps clears the value of the "props" field.
|
||||
func (u *DavAccountUpsert) ClearProps() *DavAccountUpsert {
|
||||
u.SetNull(davaccount.FieldProps)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetOwnerID sets the "owner_id" field.
|
||||
func (u *DavAccountUpsert) SetOwnerID(v int) *DavAccountUpsert {
|
||||
u.Set(davaccount.FieldOwnerID, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateOwnerID sets the "owner_id" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsert) UpdateOwnerID() *DavAccountUpsert {
|
||||
u.SetExcluded(davaccount.FieldOwnerID)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateNewValues updates the mutable fields using the new values that were set on create.
|
||||
// Using this option is equivalent to using:
|
||||
//
|
||||
// client.DavAccount.Create().
|
||||
// OnConflict(
|
||||
// sql.ResolveWithNewValues(),
|
||||
// ).
|
||||
// Exec(ctx)
|
||||
func (u *DavAccountUpsertOne) UpdateNewValues() *DavAccountUpsertOne {
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues())
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) {
|
||||
if _, exists := u.create.mutation.CreatedAt(); exists {
|
||||
s.SetIgnore(davaccount.FieldCreatedAt)
|
||||
}
|
||||
}))
|
||||
return u
|
||||
}
|
||||
|
||||
// Ignore sets each column to itself in case of conflict.
|
||||
// Using this option is equivalent to using:
|
||||
//
|
||||
// client.DavAccount.Create().
|
||||
// OnConflict(sql.ResolveWithIgnore()).
|
||||
// Exec(ctx)
|
||||
func (u *DavAccountUpsertOne) Ignore() *DavAccountUpsertOne {
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore())
|
||||
return u
|
||||
}
|
||||
|
||||
// DoNothing configures the conflict_action to `DO NOTHING`.
|
||||
// Supported only by SQLite and PostgreSQL.
|
||||
func (u *DavAccountUpsertOne) DoNothing() *DavAccountUpsertOne {
|
||||
u.create.conflict = append(u.create.conflict, sql.DoNothing())
|
||||
return u
|
||||
}
|
||||
|
||||
// Update allows overriding fields `UPDATE` values. See the DavAccountCreate.OnConflict
|
||||
// documentation for more info.
|
||||
func (u *DavAccountUpsertOne) Update(set func(*DavAccountUpsert)) *DavAccountUpsertOne {
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
|
||||
set(&DavAccountUpsert{UpdateSet: update})
|
||||
}))
|
||||
return u
|
||||
}
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (u *DavAccountUpsertOne) SetUpdatedAt(v time.Time) *DavAccountUpsertOne {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.SetUpdatedAt(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsertOne) UpdateUpdatedAt() *DavAccountUpsertOne {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.UpdateUpdatedAt()
|
||||
})
|
||||
}
|
||||
|
||||
// SetDeletedAt sets the "deleted_at" field.
|
||||
func (u *DavAccountUpsertOne) SetDeletedAt(v time.Time) *DavAccountUpsertOne {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.SetDeletedAt(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsertOne) UpdateDeletedAt() *DavAccountUpsertOne {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.UpdateDeletedAt()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearDeletedAt clears the value of the "deleted_at" field.
|
||||
func (u *DavAccountUpsertOne) ClearDeletedAt() *DavAccountUpsertOne {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.ClearDeletedAt()
|
||||
})
|
||||
}
|
||||
|
||||
// SetName sets the "name" field.
|
||||
func (u *DavAccountUpsertOne) SetName(v string) *DavAccountUpsertOne {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.SetName(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateName sets the "name" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsertOne) UpdateName() *DavAccountUpsertOne {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.UpdateName()
|
||||
})
|
||||
}
|
||||
|
||||
// SetURI sets the "uri" field.
|
||||
func (u *DavAccountUpsertOne) SetURI(v string) *DavAccountUpsertOne {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.SetURI(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateURI sets the "uri" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsertOne) UpdateURI() *DavAccountUpsertOne {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.UpdateURI()
|
||||
})
|
||||
}
|
||||
|
||||
// SetPassword sets the "password" field.
|
||||
func (u *DavAccountUpsertOne) SetPassword(v string) *DavAccountUpsertOne {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.SetPassword(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdatePassword sets the "password" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsertOne) UpdatePassword() *DavAccountUpsertOne {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.UpdatePassword()
|
||||
})
|
||||
}
|
||||
|
||||
// SetOptions sets the "options" field.
|
||||
func (u *DavAccountUpsertOne) SetOptions(v *boolset.BooleanSet) *DavAccountUpsertOne {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.SetOptions(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateOptions sets the "options" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsertOne) UpdateOptions() *DavAccountUpsertOne {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.UpdateOptions()
|
||||
})
|
||||
}
|
||||
|
||||
// SetProps sets the "props" field.
|
||||
func (u *DavAccountUpsertOne) SetProps(v *types.DavAccountProps) *DavAccountUpsertOne {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.SetProps(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateProps sets the "props" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsertOne) UpdateProps() *DavAccountUpsertOne {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.UpdateProps()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearProps clears the value of the "props" field.
|
||||
func (u *DavAccountUpsertOne) ClearProps() *DavAccountUpsertOne {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.ClearProps()
|
||||
})
|
||||
}
|
||||
|
||||
// SetOwnerID sets the "owner_id" field.
|
||||
func (u *DavAccountUpsertOne) SetOwnerID(v int) *DavAccountUpsertOne {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.SetOwnerID(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateOwnerID sets the "owner_id" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsertOne) UpdateOwnerID() *DavAccountUpsertOne {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.UpdateOwnerID()
|
||||
})
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (u *DavAccountUpsertOne) Exec(ctx context.Context) error {
|
||||
if len(u.create.conflict) == 0 {
|
||||
return errors.New("ent: missing options for DavAccountCreate.OnConflict")
|
||||
}
|
||||
return u.create.Exec(ctx)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (u *DavAccountUpsertOne) ExecX(ctx context.Context) {
|
||||
if err := u.create.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Exec executes the UPSERT query and returns the inserted/updated ID.
|
||||
func (u *DavAccountUpsertOne) ID(ctx context.Context) (id int, err error) {
|
||||
node, err := u.create.Save(ctx)
|
||||
if err != nil {
|
||||
return id, err
|
||||
}
|
||||
return node.ID, nil
|
||||
}
|
||||
|
||||
// IDX is like ID, but panics if an error occurs.
|
||||
func (u *DavAccountUpsertOne) IDX(ctx context.Context) int {
|
||||
id, err := u.ID(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
func (m *DavAccountCreate) SetRawID(t int) *DavAccountCreate {
|
||||
m.mutation.SetRawID(t)
|
||||
return m
|
||||
}
|
||||
|
||||
// DavAccountCreateBulk is the builder for creating many DavAccount entities in bulk.
|
||||
type DavAccountCreateBulk struct {
|
||||
config
|
||||
err error
|
||||
builders []*DavAccountCreate
|
||||
conflict []sql.ConflictOption
|
||||
}
|
||||
|
||||
// Save creates the DavAccount entities in the database.
|
||||
func (dacb *DavAccountCreateBulk) Save(ctx context.Context) ([]*DavAccount, error) {
|
||||
if dacb.err != nil {
|
||||
return nil, dacb.err
|
||||
}
|
||||
specs := make([]*sqlgraph.CreateSpec, len(dacb.builders))
|
||||
nodes := make([]*DavAccount, len(dacb.builders))
|
||||
mutators := make([]Mutator, len(dacb.builders))
|
||||
for i := range dacb.builders {
|
||||
func(i int, root context.Context) {
|
||||
builder := dacb.builders[i]
|
||||
builder.defaults()
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*DavAccountMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
if err := builder.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
builder.mutation = mutation
|
||||
var err error
|
||||
nodes[i], specs[i] = builder.createSpec()
|
||||
if i < len(mutators)-1 {
|
||||
_, err = mutators[i+1].Mutate(root, dacb.builders[i+1].mutation)
|
||||
} else {
|
||||
spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
|
||||
spec.OnConflict = dacb.conflict
|
||||
// Invoke the actual operation on the latest mutation in the chain.
|
||||
if err = sqlgraph.BatchCreate(ctx, dacb.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, dacb.builders[0].mutation); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (dacb *DavAccountCreateBulk) SaveX(ctx context.Context) []*DavAccount {
|
||||
v, err := dacb.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (dacb *DavAccountCreateBulk) Exec(ctx context.Context) error {
|
||||
_, err := dacb.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (dacb *DavAccountCreateBulk) ExecX(ctx context.Context) {
|
||||
if err := dacb.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
|
||||
// of the `INSERT` statement. For example:
|
||||
//
|
||||
// client.DavAccount.CreateBulk(builders...).
|
||||
// OnConflict(
|
||||
// // Update the row with the new values
|
||||
// // the was proposed for insertion.
|
||||
// sql.ResolveWithNewValues(),
|
||||
// ).
|
||||
// // Override some of the fields with custom
|
||||
// // update values.
|
||||
// Update(func(u *ent.DavAccountUpsert) {
|
||||
// SetCreatedAt(v+v).
|
||||
// }).
|
||||
// Exec(ctx)
|
||||
func (dacb *DavAccountCreateBulk) OnConflict(opts ...sql.ConflictOption) *DavAccountUpsertBulk {
|
||||
dacb.conflict = opts
|
||||
return &DavAccountUpsertBulk{
|
||||
create: dacb,
|
||||
}
|
||||
}
|
||||
|
||||
// OnConflictColumns calls `OnConflict` and configures the columns
|
||||
// as conflict target. Using this option is equivalent to using:
|
||||
//
|
||||
// client.DavAccount.Create().
|
||||
// OnConflict(sql.ConflictColumns(columns...)).
|
||||
// Exec(ctx)
|
||||
func (dacb *DavAccountCreateBulk) OnConflictColumns(columns ...string) *DavAccountUpsertBulk {
|
||||
dacb.conflict = append(dacb.conflict, sql.ConflictColumns(columns...))
|
||||
return &DavAccountUpsertBulk{
|
||||
create: dacb,
|
||||
}
|
||||
}
|
||||
|
||||
// DavAccountUpsertBulk is the builder for "upsert"-ing
|
||||
// a bulk of DavAccount nodes.
|
||||
type DavAccountUpsertBulk struct {
|
||||
create *DavAccountCreateBulk
|
||||
}
|
||||
|
||||
// UpdateNewValues updates the mutable fields using the new values that
|
||||
// were set on create. Using this option is equivalent to using:
|
||||
//
|
||||
// client.DavAccount.Create().
|
||||
// OnConflict(
|
||||
// sql.ResolveWithNewValues(),
|
||||
// ).
|
||||
// Exec(ctx)
|
||||
func (u *DavAccountUpsertBulk) UpdateNewValues() *DavAccountUpsertBulk {
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues())
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) {
|
||||
for _, b := range u.create.builders {
|
||||
if _, exists := b.mutation.CreatedAt(); exists {
|
||||
s.SetIgnore(davaccount.FieldCreatedAt)
|
||||
}
|
||||
}
|
||||
}))
|
||||
return u
|
||||
}
|
||||
|
||||
// Ignore sets each column to itself in case of conflict.
|
||||
// Using this option is equivalent to using:
|
||||
//
|
||||
// client.DavAccount.Create().
|
||||
// OnConflict(sql.ResolveWithIgnore()).
|
||||
// Exec(ctx)
|
||||
func (u *DavAccountUpsertBulk) Ignore() *DavAccountUpsertBulk {
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore())
|
||||
return u
|
||||
}
|
||||
|
||||
// DoNothing configures the conflict_action to `DO NOTHING`.
|
||||
// Supported only by SQLite and PostgreSQL.
|
||||
func (u *DavAccountUpsertBulk) DoNothing() *DavAccountUpsertBulk {
|
||||
u.create.conflict = append(u.create.conflict, sql.DoNothing())
|
||||
return u
|
||||
}
|
||||
|
||||
// Update allows overriding fields `UPDATE` values. See the DavAccountCreateBulk.OnConflict
|
||||
// documentation for more info.
|
||||
func (u *DavAccountUpsertBulk) Update(set func(*DavAccountUpsert)) *DavAccountUpsertBulk {
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
|
||||
set(&DavAccountUpsert{UpdateSet: update})
|
||||
}))
|
||||
return u
|
||||
}
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (u *DavAccountUpsertBulk) SetUpdatedAt(v time.Time) *DavAccountUpsertBulk {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.SetUpdatedAt(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsertBulk) UpdateUpdatedAt() *DavAccountUpsertBulk {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.UpdateUpdatedAt()
|
||||
})
|
||||
}
|
||||
|
||||
// SetDeletedAt sets the "deleted_at" field.
|
||||
func (u *DavAccountUpsertBulk) SetDeletedAt(v time.Time) *DavAccountUpsertBulk {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.SetDeletedAt(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsertBulk) UpdateDeletedAt() *DavAccountUpsertBulk {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.UpdateDeletedAt()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearDeletedAt clears the value of the "deleted_at" field.
|
||||
func (u *DavAccountUpsertBulk) ClearDeletedAt() *DavAccountUpsertBulk {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.ClearDeletedAt()
|
||||
})
|
||||
}
|
||||
|
||||
// SetName sets the "name" field.
|
||||
func (u *DavAccountUpsertBulk) SetName(v string) *DavAccountUpsertBulk {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.SetName(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateName sets the "name" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsertBulk) UpdateName() *DavAccountUpsertBulk {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.UpdateName()
|
||||
})
|
||||
}
|
||||
|
||||
// SetURI sets the "uri" field.
|
||||
func (u *DavAccountUpsertBulk) SetURI(v string) *DavAccountUpsertBulk {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.SetURI(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateURI sets the "uri" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsertBulk) UpdateURI() *DavAccountUpsertBulk {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.UpdateURI()
|
||||
})
|
||||
}
|
||||
|
||||
// SetPassword sets the "password" field.
|
||||
func (u *DavAccountUpsertBulk) SetPassword(v string) *DavAccountUpsertBulk {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.SetPassword(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdatePassword sets the "password" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsertBulk) UpdatePassword() *DavAccountUpsertBulk {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.UpdatePassword()
|
||||
})
|
||||
}
|
||||
|
||||
// SetOptions sets the "options" field.
|
||||
func (u *DavAccountUpsertBulk) SetOptions(v *boolset.BooleanSet) *DavAccountUpsertBulk {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.SetOptions(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateOptions sets the "options" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsertBulk) UpdateOptions() *DavAccountUpsertBulk {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.UpdateOptions()
|
||||
})
|
||||
}
|
||||
|
||||
// SetProps sets the "props" field.
|
||||
func (u *DavAccountUpsertBulk) SetProps(v *types.DavAccountProps) *DavAccountUpsertBulk {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.SetProps(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateProps sets the "props" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsertBulk) UpdateProps() *DavAccountUpsertBulk {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.UpdateProps()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearProps clears the value of the "props" field.
|
||||
func (u *DavAccountUpsertBulk) ClearProps() *DavAccountUpsertBulk {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.ClearProps()
|
||||
})
|
||||
}
|
||||
|
||||
// SetOwnerID sets the "owner_id" field.
|
||||
func (u *DavAccountUpsertBulk) SetOwnerID(v int) *DavAccountUpsertBulk {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.SetOwnerID(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateOwnerID sets the "owner_id" field to the value that was provided on create.
|
||||
func (u *DavAccountUpsertBulk) UpdateOwnerID() *DavAccountUpsertBulk {
|
||||
return u.Update(func(s *DavAccountUpsert) {
|
||||
s.UpdateOwnerID()
|
||||
})
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (u *DavAccountUpsertBulk) Exec(ctx context.Context) error {
|
||||
if u.create.err != nil {
|
||||
return u.create.err
|
||||
}
|
||||
for i, b := range u.create.builders {
|
||||
if len(b.conflict) != 0 {
|
||||
return fmt.Errorf("ent: OnConflict was set for builder %d. Set it on the DavAccountCreateBulk instead", i)
|
||||
}
|
||||
}
|
||||
if len(u.create.conflict) == 0 {
|
||||
return errors.New("ent: missing options for DavAccountCreateBulk.OnConflict")
|
||||
}
|
||||
return u.create.Exec(ctx)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (u *DavAccountUpsertBulk) ExecX(ctx context.Context) {
|
||||
if err := u.create.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
88
ent/davaccount_delete.go
Normal file
88
ent/davaccount_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/cloudreve/Cloudreve/v4/ent/davaccount"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||
)
|
||||
|
||||
// DavAccountDelete is the builder for deleting a DavAccount entity.
|
||||
type DavAccountDelete struct {
|
||||
config
|
||||
hooks []Hook
|
||||
mutation *DavAccountMutation
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the DavAccountDelete builder.
|
||||
func (dad *DavAccountDelete) Where(ps ...predicate.DavAccount) *DavAccountDelete {
|
||||
dad.mutation.Where(ps...)
|
||||
return dad
|
||||
}
|
||||
|
||||
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||
func (dad *DavAccountDelete) Exec(ctx context.Context) (int, error) {
|
||||
return withHooks(ctx, dad.sqlExec, dad.mutation, dad.hooks)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (dad *DavAccountDelete) ExecX(ctx context.Context) int {
|
||||
n, err := dad.Exec(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (dad *DavAccountDelete) sqlExec(ctx context.Context) (int, error) {
|
||||
_spec := sqlgraph.NewDeleteSpec(davaccount.Table, sqlgraph.NewFieldSpec(davaccount.FieldID, field.TypeInt))
|
||||
if ps := dad.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
affected, err := sqlgraph.DeleteNodes(ctx, dad.driver, _spec)
|
||||
if err != nil && sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
dad.mutation.done = true
|
||||
return affected, err
|
||||
}
|
||||
|
||||
// DavAccountDeleteOne is the builder for deleting a single DavAccount entity.
|
||||
type DavAccountDeleteOne struct {
|
||||
dad *DavAccountDelete
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the DavAccountDelete builder.
|
||||
func (dado *DavAccountDeleteOne) Where(ps ...predicate.DavAccount) *DavAccountDeleteOne {
|
||||
dado.dad.mutation.Where(ps...)
|
||||
return dado
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (dado *DavAccountDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := dado.dad.Exec(ctx)
|
||||
switch {
|
||||
case err != nil:
|
||||
return err
|
||||
case n == 0:
|
||||
return &NotFoundError{davaccount.Label}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (dado *DavAccountDeleteOne) ExecX(ctx context.Context) {
|
||||
if err := dado.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
605
ent/davaccount_query.go
Normal file
605
ent/davaccount_query.go
Normal file
@@ -0,0 +1,605 @@
|
||||
// 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/cloudreve/Cloudreve/v4/ent/davaccount"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/user"
|
||||
)
|
||||
|
||||
// DavAccountQuery is the builder for querying DavAccount entities.
|
||||
type DavAccountQuery struct {
|
||||
config
|
||||
ctx *QueryContext
|
||||
order []davaccount.OrderOption
|
||||
inters []Interceptor
|
||||
predicates []predicate.DavAccount
|
||||
withOwner *UserQuery
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the DavAccountQuery builder.
|
||||
func (daq *DavAccountQuery) Where(ps ...predicate.DavAccount) *DavAccountQuery {
|
||||
daq.predicates = append(daq.predicates, ps...)
|
||||
return daq
|
||||
}
|
||||
|
||||
// Limit the number of records to be returned by this query.
|
||||
func (daq *DavAccountQuery) Limit(limit int) *DavAccountQuery {
|
||||
daq.ctx.Limit = &limit
|
||||
return daq
|
||||
}
|
||||
|
||||
// Offset to start from.
|
||||
func (daq *DavAccountQuery) Offset(offset int) *DavAccountQuery {
|
||||
daq.ctx.Offset = &offset
|
||||
return daq
|
||||
}
|
||||
|
||||
// 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 (daq *DavAccountQuery) Unique(unique bool) *DavAccountQuery {
|
||||
daq.ctx.Unique = &unique
|
||||
return daq
|
||||
}
|
||||
|
||||
// Order specifies how the records should be ordered.
|
||||
func (daq *DavAccountQuery) Order(o ...davaccount.OrderOption) *DavAccountQuery {
|
||||
daq.order = append(daq.order, o...)
|
||||
return daq
|
||||
}
|
||||
|
||||
// QueryOwner chains the current query on the "owner" edge.
|
||||
func (daq *DavAccountQuery) QueryOwner() *UserQuery {
|
||||
query := (&UserClient{config: daq.config}).Query()
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := daq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector := daq.sqlQuery(ctx)
|
||||
if err := selector.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(davaccount.Table, davaccount.FieldID, selector),
|
||||
sqlgraph.To(user.Table, user.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, davaccount.OwnerTable, davaccount.OwnerColumn),
|
||||
)
|
||||
fromU = sqlgraph.SetNeighbors(daq.driver.Dialect(), step)
|
||||
return fromU, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// First returns the first DavAccount entity from the query.
|
||||
// Returns a *NotFoundError when no DavAccount was found.
|
||||
func (daq *DavAccountQuery) First(ctx context.Context) (*DavAccount, error) {
|
||||
nodes, err := daq.Limit(1).All(setContextOp(ctx, daq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nil, &NotFoundError{davaccount.Label}
|
||||
}
|
||||
return nodes[0], nil
|
||||
}
|
||||
|
||||
// FirstX is like First, but panics if an error occurs.
|
||||
func (daq *DavAccountQuery) FirstX(ctx context.Context) *DavAccount {
|
||||
node, err := daq.First(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// FirstID returns the first DavAccount ID from the query.
|
||||
// Returns a *NotFoundError when no DavAccount ID was found.
|
||||
func (daq *DavAccountQuery) FirstID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = daq.Limit(1).IDs(setContextOp(ctx, daq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
err = &NotFoundError{davaccount.Label}
|
||||
return
|
||||
}
|
||||
return ids[0], nil
|
||||
}
|
||||
|
||||
// FirstIDX is like FirstID, but panics if an error occurs.
|
||||
func (daq *DavAccountQuery) FirstIDX(ctx context.Context) int {
|
||||
id, err := daq.FirstID(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// Only returns a single DavAccount entity found by the query, ensuring it only returns one.
|
||||
// Returns a *NotSingularError when more than one DavAccount entity is found.
|
||||
// Returns a *NotFoundError when no DavAccount entities are found.
|
||||
func (daq *DavAccountQuery) Only(ctx context.Context) (*DavAccount, error) {
|
||||
nodes, err := daq.Limit(2).All(setContextOp(ctx, daq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch len(nodes) {
|
||||
case 1:
|
||||
return nodes[0], nil
|
||||
case 0:
|
||||
return nil, &NotFoundError{davaccount.Label}
|
||||
default:
|
||||
return nil, &NotSingularError{davaccount.Label}
|
||||
}
|
||||
}
|
||||
|
||||
// OnlyX is like Only, but panics if an error occurs.
|
||||
func (daq *DavAccountQuery) OnlyX(ctx context.Context) *DavAccount {
|
||||
node, err := daq.Only(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// OnlyID is like Only, but returns the only DavAccount ID in the query.
|
||||
// Returns a *NotSingularError when more than one DavAccount ID is found.
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (daq *DavAccountQuery) OnlyID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = daq.Limit(2).IDs(setContextOp(ctx, daq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
case 1:
|
||||
id = ids[0]
|
||||
case 0:
|
||||
err = &NotFoundError{davaccount.Label}
|
||||
default:
|
||||
err = &NotSingularError{davaccount.Label}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// OnlyIDX is like OnlyID, but panics if an error occurs.
|
||||
func (daq *DavAccountQuery) OnlyIDX(ctx context.Context) int {
|
||||
id, err := daq.OnlyID(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// All executes the query and returns a list of DavAccounts.
|
||||
func (daq *DavAccountQuery) All(ctx context.Context) ([]*DavAccount, error) {
|
||||
ctx = setContextOp(ctx, daq.ctx, "All")
|
||||
if err := daq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
qr := querierAll[[]*DavAccount, *DavAccountQuery]()
|
||||
return withInterceptors[[]*DavAccount](ctx, daq, qr, daq.inters)
|
||||
}
|
||||
|
||||
// AllX is like All, but panics if an error occurs.
|
||||
func (daq *DavAccountQuery) AllX(ctx context.Context) []*DavAccount {
|
||||
nodes, err := daq.All(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
// IDs executes the query and returns a list of DavAccount IDs.
|
||||
func (daq *DavAccountQuery) IDs(ctx context.Context) (ids []int, err error) {
|
||||
if daq.ctx.Unique == nil && daq.path != nil {
|
||||
daq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, daq.ctx, "IDs")
|
||||
if err = daq.Select(davaccount.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
// IDsX is like IDs, but panics if an error occurs.
|
||||
func (daq *DavAccountQuery) IDsX(ctx context.Context) []int {
|
||||
ids, err := daq.IDs(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (daq *DavAccountQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, daq.ctx, "Count")
|
||||
if err := daq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return withInterceptors[int](ctx, daq, querierCount[*DavAccountQuery](), daq.inters)
|
||||
}
|
||||
|
||||
// CountX is like Count, but panics if an error occurs.
|
||||
func (daq *DavAccountQuery) CountX(ctx context.Context) int {
|
||||
count, err := daq.Count(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (daq *DavAccountQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, daq.ctx, "Exist")
|
||||
switch _, err := daq.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 (daq *DavAccountQuery) ExistX(ctx context.Context) bool {
|
||||
exist, err := daq.Exist(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return exist
|
||||
}
|
||||
|
||||
// Clone returns a duplicate of the DavAccountQuery builder, including all associated steps. It can be
|
||||
// used to prepare common query builders and use them differently after the clone is made.
|
||||
func (daq *DavAccountQuery) Clone() *DavAccountQuery {
|
||||
if daq == nil {
|
||||
return nil
|
||||
}
|
||||
return &DavAccountQuery{
|
||||
config: daq.config,
|
||||
ctx: daq.ctx.Clone(),
|
||||
order: append([]davaccount.OrderOption{}, daq.order...),
|
||||
inters: append([]Interceptor{}, daq.inters...),
|
||||
predicates: append([]predicate.DavAccount{}, daq.predicates...),
|
||||
withOwner: daq.withOwner.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: daq.sql.Clone(),
|
||||
path: daq.path,
|
||||
}
|
||||
}
|
||||
|
||||
// WithOwner tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "owner" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (daq *DavAccountQuery) WithOwner(opts ...func(*UserQuery)) *DavAccountQuery {
|
||||
query := (&UserClient{config: daq.config}).Query()
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
daq.withOwner = query
|
||||
return daq
|
||||
}
|
||||
|
||||
// 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.DavAccount.Query().
|
||||
// GroupBy(davaccount.FieldCreatedAt).
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (daq *DavAccountQuery) GroupBy(field string, fields ...string) *DavAccountGroupBy {
|
||||
daq.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &DavAccountGroupBy{build: daq}
|
||||
grbuild.flds = &daq.ctx.Fields
|
||||
grbuild.label = davaccount.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 {
|
||||
// CreatedAt time.Time `json:"created_at,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.DavAccount.Query().
|
||||
// Select(davaccount.FieldCreatedAt).
|
||||
// Scan(ctx, &v)
|
||||
func (daq *DavAccountQuery) Select(fields ...string) *DavAccountSelect {
|
||||
daq.ctx.Fields = append(daq.ctx.Fields, fields...)
|
||||
sbuild := &DavAccountSelect{DavAccountQuery: daq}
|
||||
sbuild.label = davaccount.Label
|
||||
sbuild.flds, sbuild.scan = &daq.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
// Aggregate returns a DavAccountSelect configured with the given aggregations.
|
||||
func (daq *DavAccountQuery) Aggregate(fns ...AggregateFunc) *DavAccountSelect {
|
||||
return daq.Select().Aggregate(fns...)
|
||||
}
|
||||
|
||||
func (daq *DavAccountQuery) prepareQuery(ctx context.Context) error {
|
||||
for _, inter := range daq.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, daq); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range daq.ctx.Fields {
|
||||
if !davaccount.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
}
|
||||
if daq.path != nil {
|
||||
prev, err := daq.path(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
daq.sql = prev
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (daq *DavAccountQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*DavAccount, error) {
|
||||
var (
|
||||
nodes = []*DavAccount{}
|
||||
_spec = daq.querySpec()
|
||||
loadedTypes = [1]bool{
|
||||
daq.withOwner != nil,
|
||||
}
|
||||
)
|
||||
_spec.ScanValues = func(columns []string) ([]any, error) {
|
||||
return (*DavAccount).scanValues(nil, columns)
|
||||
}
|
||||
_spec.Assign = func(columns []string, values []any) error {
|
||||
node := &DavAccount{config: daq.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, daq.driver, _spec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nodes, nil
|
||||
}
|
||||
if query := daq.withOwner; query != nil {
|
||||
if err := daq.loadOwner(ctx, query, nodes, nil,
|
||||
func(n *DavAccount, e *User) { n.Edges.Owner = e }); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
func (daq *DavAccountQuery) loadOwner(ctx context.Context, query *UserQuery, nodes []*DavAccount, init func(*DavAccount), assign func(*DavAccount, *User)) error {
|
||||
ids := make([]int, 0, len(nodes))
|
||||
nodeids := make(map[int][]*DavAccount)
|
||||
for i := range nodes {
|
||||
fk := nodes[i].OwnerID
|
||||
if _, ok := nodeids[fk]; !ok {
|
||||
ids = append(ids, fk)
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
query.Where(user.IDIn(ids...))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, n := range neighbors {
|
||||
nodes, ok := nodeids[n.ID]
|
||||
if !ok {
|
||||
return fmt.Errorf(`unexpected foreign-key "owner_id" returned %v`, n.ID)
|
||||
}
|
||||
for i := range nodes {
|
||||
assign(nodes[i], n)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (daq *DavAccountQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := daq.querySpec()
|
||||
_spec.Node.Columns = daq.ctx.Fields
|
||||
if len(daq.ctx.Fields) > 0 {
|
||||
_spec.Unique = daq.ctx.Unique != nil && *daq.ctx.Unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, daq.driver, _spec)
|
||||
}
|
||||
|
||||
func (daq *DavAccountQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
_spec := sqlgraph.NewQuerySpec(davaccount.Table, davaccount.Columns, sqlgraph.NewFieldSpec(davaccount.FieldID, field.TypeInt))
|
||||
_spec.From = daq.sql
|
||||
if unique := daq.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
} else if daq.path != nil {
|
||||
_spec.Unique = true
|
||||
}
|
||||
if fields := daq.ctx.Fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, davaccount.FieldID)
|
||||
for i := range fields {
|
||||
if fields[i] != davaccount.FieldID {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
|
||||
}
|
||||
}
|
||||
if daq.withOwner != nil {
|
||||
_spec.Node.AddColumnOnce(davaccount.FieldOwnerID)
|
||||
}
|
||||
}
|
||||
if ps := daq.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := daq.ctx.Limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := daq.ctx.Offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := daq.order; len(ps) > 0 {
|
||||
_spec.Order = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
return _spec
|
||||
}
|
||||
|
||||
func (daq *DavAccountQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(daq.driver.Dialect())
|
||||
t1 := builder.Table(davaccount.Table)
|
||||
columns := daq.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = davaccount.Columns
|
||||
}
|
||||
selector := builder.Select(t1.Columns(columns...)...).From(t1)
|
||||
if daq.sql != nil {
|
||||
selector = daq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if daq.ctx.Unique != nil && *daq.ctx.Unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, p := range daq.predicates {
|
||||
p(selector)
|
||||
}
|
||||
for _, p := range daq.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := daq.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 := daq.ctx.Limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
}
|
||||
|
||||
// DavAccountGroupBy is the group-by builder for DavAccount entities.
|
||||
type DavAccountGroupBy struct {
|
||||
selector
|
||||
build *DavAccountQuery
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the group-by query.
|
||||
func (dagb *DavAccountGroupBy) Aggregate(fns ...AggregateFunc) *DavAccountGroupBy {
|
||||
dagb.fns = append(dagb.fns, fns...)
|
||||
return dagb
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (dagb *DavAccountGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, dagb.build.ctx, "GroupBy")
|
||||
if err := dagb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return scanWithInterceptors[*DavAccountQuery, *DavAccountGroupBy](ctx, dagb.build, dagb, dagb.build.inters, v)
|
||||
}
|
||||
|
||||
func (dagb *DavAccountGroupBy) sqlScan(ctx context.Context, root *DavAccountQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx).Select()
|
||||
aggregation := make([]string, 0, len(dagb.fns))
|
||||
for _, fn := range dagb.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
if len(selector.SelectedColumns()) == 0 {
|
||||
columns := make([]string, 0, len(*dagb.flds)+len(dagb.fns))
|
||||
for _, f := range *dagb.flds {
|
||||
columns = append(columns, selector.C(f))
|
||||
}
|
||||
columns = append(columns, aggregation...)
|
||||
selector.Select(columns...)
|
||||
}
|
||||
selector.GroupBy(selector.Columns(*dagb.flds...)...)
|
||||
if err := selector.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := dagb.build.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
// DavAccountSelect is the builder for selecting fields of DavAccount entities.
|
||||
type DavAccountSelect struct {
|
||||
*DavAccountQuery
|
||||
selector
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the selector query.
|
||||
func (das *DavAccountSelect) Aggregate(fns ...AggregateFunc) *DavAccountSelect {
|
||||
das.fns = append(das.fns, fns...)
|
||||
return das
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (das *DavAccountSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, das.ctx, "Select")
|
||||
if err := das.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return scanWithInterceptors[*DavAccountQuery, *DavAccountSelect](ctx, das.DavAccountQuery, das, das.inters, v)
|
||||
}
|
||||
|
||||
func (das *DavAccountSelect) sqlScan(ctx context.Context, root *DavAccountQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx)
|
||||
aggregation := make([]string, 0, len(das.fns))
|
||||
for _, fn := range das.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
switch n := len(*das.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 := das.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
565
ent/davaccount_update.go
Normal file
565
ent/davaccount_update.go
Normal file
@@ -0,0 +1,565 @@
|
||||
// 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/cloudreve/Cloudreve/v4/ent/davaccount"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/user"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
"github.com/cloudreve/Cloudreve/v4/pkg/boolset"
|
||||
)
|
||||
|
||||
// DavAccountUpdate is the builder for updating DavAccount entities.
|
||||
type DavAccountUpdate struct {
|
||||
config
|
||||
hooks []Hook
|
||||
mutation *DavAccountMutation
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the DavAccountUpdate builder.
|
||||
func (dau *DavAccountUpdate) Where(ps ...predicate.DavAccount) *DavAccountUpdate {
|
||||
dau.mutation.Where(ps...)
|
||||
return dau
|
||||
}
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (dau *DavAccountUpdate) SetUpdatedAt(t time.Time) *DavAccountUpdate {
|
||||
dau.mutation.SetUpdatedAt(t)
|
||||
return dau
|
||||
}
|
||||
|
||||
// SetDeletedAt sets the "deleted_at" field.
|
||||
func (dau *DavAccountUpdate) SetDeletedAt(t time.Time) *DavAccountUpdate {
|
||||
dau.mutation.SetDeletedAt(t)
|
||||
return dau
|
||||
}
|
||||
|
||||
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
|
||||
func (dau *DavAccountUpdate) SetNillableDeletedAt(t *time.Time) *DavAccountUpdate {
|
||||
if t != nil {
|
||||
dau.SetDeletedAt(*t)
|
||||
}
|
||||
return dau
|
||||
}
|
||||
|
||||
// ClearDeletedAt clears the value of the "deleted_at" field.
|
||||
func (dau *DavAccountUpdate) ClearDeletedAt() *DavAccountUpdate {
|
||||
dau.mutation.ClearDeletedAt()
|
||||
return dau
|
||||
}
|
||||
|
||||
// SetName sets the "name" field.
|
||||
func (dau *DavAccountUpdate) SetName(s string) *DavAccountUpdate {
|
||||
dau.mutation.SetName(s)
|
||||
return dau
|
||||
}
|
||||
|
||||
// SetNillableName sets the "name" field if the given value is not nil.
|
||||
func (dau *DavAccountUpdate) SetNillableName(s *string) *DavAccountUpdate {
|
||||
if s != nil {
|
||||
dau.SetName(*s)
|
||||
}
|
||||
return dau
|
||||
}
|
||||
|
||||
// SetURI sets the "uri" field.
|
||||
func (dau *DavAccountUpdate) SetURI(s string) *DavAccountUpdate {
|
||||
dau.mutation.SetURI(s)
|
||||
return dau
|
||||
}
|
||||
|
||||
// SetNillableURI sets the "uri" field if the given value is not nil.
|
||||
func (dau *DavAccountUpdate) SetNillableURI(s *string) *DavAccountUpdate {
|
||||
if s != nil {
|
||||
dau.SetURI(*s)
|
||||
}
|
||||
return dau
|
||||
}
|
||||
|
||||
// SetPassword sets the "password" field.
|
||||
func (dau *DavAccountUpdate) SetPassword(s string) *DavAccountUpdate {
|
||||
dau.mutation.SetPassword(s)
|
||||
return dau
|
||||
}
|
||||
|
||||
// SetNillablePassword sets the "password" field if the given value is not nil.
|
||||
func (dau *DavAccountUpdate) SetNillablePassword(s *string) *DavAccountUpdate {
|
||||
if s != nil {
|
||||
dau.SetPassword(*s)
|
||||
}
|
||||
return dau
|
||||
}
|
||||
|
||||
// SetOptions sets the "options" field.
|
||||
func (dau *DavAccountUpdate) SetOptions(bs *boolset.BooleanSet) *DavAccountUpdate {
|
||||
dau.mutation.SetOptions(bs)
|
||||
return dau
|
||||
}
|
||||
|
||||
// SetProps sets the "props" field.
|
||||
func (dau *DavAccountUpdate) SetProps(tap *types.DavAccountProps) *DavAccountUpdate {
|
||||
dau.mutation.SetProps(tap)
|
||||
return dau
|
||||
}
|
||||
|
||||
// ClearProps clears the value of the "props" field.
|
||||
func (dau *DavAccountUpdate) ClearProps() *DavAccountUpdate {
|
||||
dau.mutation.ClearProps()
|
||||
return dau
|
||||
}
|
||||
|
||||
// SetOwnerID sets the "owner_id" field.
|
||||
func (dau *DavAccountUpdate) SetOwnerID(i int) *DavAccountUpdate {
|
||||
dau.mutation.SetOwnerID(i)
|
||||
return dau
|
||||
}
|
||||
|
||||
// SetNillableOwnerID sets the "owner_id" field if the given value is not nil.
|
||||
func (dau *DavAccountUpdate) SetNillableOwnerID(i *int) *DavAccountUpdate {
|
||||
if i != nil {
|
||||
dau.SetOwnerID(*i)
|
||||
}
|
||||
return dau
|
||||
}
|
||||
|
||||
// SetOwner sets the "owner" edge to the User entity.
|
||||
func (dau *DavAccountUpdate) SetOwner(u *User) *DavAccountUpdate {
|
||||
return dau.SetOwnerID(u.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the DavAccountMutation object of the builder.
|
||||
func (dau *DavAccountUpdate) Mutation() *DavAccountMutation {
|
||||
return dau.mutation
|
||||
}
|
||||
|
||||
// ClearOwner clears the "owner" edge to the User entity.
|
||||
func (dau *DavAccountUpdate) ClearOwner() *DavAccountUpdate {
|
||||
dau.mutation.ClearOwner()
|
||||
return dau
|
||||
}
|
||||
|
||||
// Save executes the query and returns the number of nodes affected by the update operation.
|
||||
func (dau *DavAccountUpdate) Save(ctx context.Context) (int, error) {
|
||||
if err := dau.defaults(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return withHooks(ctx, dau.sqlSave, dau.mutation, dau.hooks)
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (dau *DavAccountUpdate) SaveX(ctx context.Context) int {
|
||||
affected, err := dau.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return affected
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (dau *DavAccountUpdate) Exec(ctx context.Context) error {
|
||||
_, err := dau.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (dau *DavAccountUpdate) ExecX(ctx context.Context) {
|
||||
if err := dau.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (dau *DavAccountUpdate) defaults() error {
|
||||
if _, ok := dau.mutation.UpdatedAt(); !ok {
|
||||
if davaccount.UpdateDefaultUpdatedAt == nil {
|
||||
return fmt.Errorf("ent: uninitialized davaccount.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)")
|
||||
}
|
||||
v := davaccount.UpdateDefaultUpdatedAt()
|
||||
dau.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (dau *DavAccountUpdate) check() error {
|
||||
if _, ok := dau.mutation.OwnerID(); dau.mutation.OwnerCleared() && !ok {
|
||||
return errors.New(`ent: clearing a required unique edge "DavAccount.owner"`)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dau *DavAccountUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
if err := dau.check(); err != nil {
|
||||
return n, err
|
||||
}
|
||||
_spec := sqlgraph.NewUpdateSpec(davaccount.Table, davaccount.Columns, sqlgraph.NewFieldSpec(davaccount.FieldID, field.TypeInt))
|
||||
if ps := dau.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if value, ok := dau.mutation.UpdatedAt(); ok {
|
||||
_spec.SetField(davaccount.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if value, ok := dau.mutation.DeletedAt(); ok {
|
||||
_spec.SetField(davaccount.FieldDeletedAt, field.TypeTime, value)
|
||||
}
|
||||
if dau.mutation.DeletedAtCleared() {
|
||||
_spec.ClearField(davaccount.FieldDeletedAt, field.TypeTime)
|
||||
}
|
||||
if value, ok := dau.mutation.Name(); ok {
|
||||
_spec.SetField(davaccount.FieldName, field.TypeString, value)
|
||||
}
|
||||
if value, ok := dau.mutation.URI(); ok {
|
||||
_spec.SetField(davaccount.FieldURI, field.TypeString, value)
|
||||
}
|
||||
if value, ok := dau.mutation.Password(); ok {
|
||||
_spec.SetField(davaccount.FieldPassword, field.TypeString, value)
|
||||
}
|
||||
if value, ok := dau.mutation.Options(); ok {
|
||||
_spec.SetField(davaccount.FieldOptions, field.TypeBytes, value)
|
||||
}
|
||||
if value, ok := dau.mutation.Props(); ok {
|
||||
_spec.SetField(davaccount.FieldProps, field.TypeJSON, value)
|
||||
}
|
||||
if dau.mutation.PropsCleared() {
|
||||
_spec.ClearField(davaccount.FieldProps, field.TypeJSON)
|
||||
}
|
||||
if dau.mutation.OwnerCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: davaccount.OwnerTable,
|
||||
Columns: []string{davaccount.OwnerColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := dau.mutation.OwnerIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: davaccount.OwnerTable,
|
||||
Columns: []string{davaccount.OwnerColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if n, err = sqlgraph.UpdateNodes(ctx, dau.driver, _spec); err != nil {
|
||||
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||
err = &NotFoundError{davaccount.Label}
|
||||
} else if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
dau.mutation.done = true
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// DavAccountUpdateOne is the builder for updating a single DavAccount entity.
|
||||
type DavAccountUpdateOne struct {
|
||||
config
|
||||
fields []string
|
||||
hooks []Hook
|
||||
mutation *DavAccountMutation
|
||||
}
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (dauo *DavAccountUpdateOne) SetUpdatedAt(t time.Time) *DavAccountUpdateOne {
|
||||
dauo.mutation.SetUpdatedAt(t)
|
||||
return dauo
|
||||
}
|
||||
|
||||
// SetDeletedAt sets the "deleted_at" field.
|
||||
func (dauo *DavAccountUpdateOne) SetDeletedAt(t time.Time) *DavAccountUpdateOne {
|
||||
dauo.mutation.SetDeletedAt(t)
|
||||
return dauo
|
||||
}
|
||||
|
||||
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
|
||||
func (dauo *DavAccountUpdateOne) SetNillableDeletedAt(t *time.Time) *DavAccountUpdateOne {
|
||||
if t != nil {
|
||||
dauo.SetDeletedAt(*t)
|
||||
}
|
||||
return dauo
|
||||
}
|
||||
|
||||
// ClearDeletedAt clears the value of the "deleted_at" field.
|
||||
func (dauo *DavAccountUpdateOne) ClearDeletedAt() *DavAccountUpdateOne {
|
||||
dauo.mutation.ClearDeletedAt()
|
||||
return dauo
|
||||
}
|
||||
|
||||
// SetName sets the "name" field.
|
||||
func (dauo *DavAccountUpdateOne) SetName(s string) *DavAccountUpdateOne {
|
||||
dauo.mutation.SetName(s)
|
||||
return dauo
|
||||
}
|
||||
|
||||
// SetNillableName sets the "name" field if the given value is not nil.
|
||||
func (dauo *DavAccountUpdateOne) SetNillableName(s *string) *DavAccountUpdateOne {
|
||||
if s != nil {
|
||||
dauo.SetName(*s)
|
||||
}
|
||||
return dauo
|
||||
}
|
||||
|
||||
// SetURI sets the "uri" field.
|
||||
func (dauo *DavAccountUpdateOne) SetURI(s string) *DavAccountUpdateOne {
|
||||
dauo.mutation.SetURI(s)
|
||||
return dauo
|
||||
}
|
||||
|
||||
// SetNillableURI sets the "uri" field if the given value is not nil.
|
||||
func (dauo *DavAccountUpdateOne) SetNillableURI(s *string) *DavAccountUpdateOne {
|
||||
if s != nil {
|
||||
dauo.SetURI(*s)
|
||||
}
|
||||
return dauo
|
||||
}
|
||||
|
||||
// SetPassword sets the "password" field.
|
||||
func (dauo *DavAccountUpdateOne) SetPassword(s string) *DavAccountUpdateOne {
|
||||
dauo.mutation.SetPassword(s)
|
||||
return dauo
|
||||
}
|
||||
|
||||
// SetNillablePassword sets the "password" field if the given value is not nil.
|
||||
func (dauo *DavAccountUpdateOne) SetNillablePassword(s *string) *DavAccountUpdateOne {
|
||||
if s != nil {
|
||||
dauo.SetPassword(*s)
|
||||
}
|
||||
return dauo
|
||||
}
|
||||
|
||||
// SetOptions sets the "options" field.
|
||||
func (dauo *DavAccountUpdateOne) SetOptions(bs *boolset.BooleanSet) *DavAccountUpdateOne {
|
||||
dauo.mutation.SetOptions(bs)
|
||||
return dauo
|
||||
}
|
||||
|
||||
// SetProps sets the "props" field.
|
||||
func (dauo *DavAccountUpdateOne) SetProps(tap *types.DavAccountProps) *DavAccountUpdateOne {
|
||||
dauo.mutation.SetProps(tap)
|
||||
return dauo
|
||||
}
|
||||
|
||||
// ClearProps clears the value of the "props" field.
|
||||
func (dauo *DavAccountUpdateOne) ClearProps() *DavAccountUpdateOne {
|
||||
dauo.mutation.ClearProps()
|
||||
return dauo
|
||||
}
|
||||
|
||||
// SetOwnerID sets the "owner_id" field.
|
||||
func (dauo *DavAccountUpdateOne) SetOwnerID(i int) *DavAccountUpdateOne {
|
||||
dauo.mutation.SetOwnerID(i)
|
||||
return dauo
|
||||
}
|
||||
|
||||
// SetNillableOwnerID sets the "owner_id" field if the given value is not nil.
|
||||
func (dauo *DavAccountUpdateOne) SetNillableOwnerID(i *int) *DavAccountUpdateOne {
|
||||
if i != nil {
|
||||
dauo.SetOwnerID(*i)
|
||||
}
|
||||
return dauo
|
||||
}
|
||||
|
||||
// SetOwner sets the "owner" edge to the User entity.
|
||||
func (dauo *DavAccountUpdateOne) SetOwner(u *User) *DavAccountUpdateOne {
|
||||
return dauo.SetOwnerID(u.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the DavAccountMutation object of the builder.
|
||||
func (dauo *DavAccountUpdateOne) Mutation() *DavAccountMutation {
|
||||
return dauo.mutation
|
||||
}
|
||||
|
||||
// ClearOwner clears the "owner" edge to the User entity.
|
||||
func (dauo *DavAccountUpdateOne) ClearOwner() *DavAccountUpdateOne {
|
||||
dauo.mutation.ClearOwner()
|
||||
return dauo
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the DavAccountUpdate builder.
|
||||
func (dauo *DavAccountUpdateOne) Where(ps ...predicate.DavAccount) *DavAccountUpdateOne {
|
||||
dauo.mutation.Where(ps...)
|
||||
return dauo
|
||||
}
|
||||
|
||||
// Select allows selecting one or more fields (columns) of the returned entity.
|
||||
// The default is selecting all fields defined in the entity schema.
|
||||
func (dauo *DavAccountUpdateOne) Select(field string, fields ...string) *DavAccountUpdateOne {
|
||||
dauo.fields = append([]string{field}, fields...)
|
||||
return dauo
|
||||
}
|
||||
|
||||
// Save executes the query and returns the updated DavAccount entity.
|
||||
func (dauo *DavAccountUpdateOne) Save(ctx context.Context) (*DavAccount, error) {
|
||||
if err := dauo.defaults(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return withHooks(ctx, dauo.sqlSave, dauo.mutation, dauo.hooks)
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (dauo *DavAccountUpdateOne) SaveX(ctx context.Context) *DavAccount {
|
||||
node, err := dauo.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// Exec executes the query on the entity.
|
||||
func (dauo *DavAccountUpdateOne) Exec(ctx context.Context) error {
|
||||
_, err := dauo.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (dauo *DavAccountUpdateOne) ExecX(ctx context.Context) {
|
||||
if err := dauo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (dauo *DavAccountUpdateOne) defaults() error {
|
||||
if _, ok := dauo.mutation.UpdatedAt(); !ok {
|
||||
if davaccount.UpdateDefaultUpdatedAt == nil {
|
||||
return fmt.Errorf("ent: uninitialized davaccount.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)")
|
||||
}
|
||||
v := davaccount.UpdateDefaultUpdatedAt()
|
||||
dauo.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (dauo *DavAccountUpdateOne) check() error {
|
||||
if _, ok := dauo.mutation.OwnerID(); dauo.mutation.OwnerCleared() && !ok {
|
||||
return errors.New(`ent: clearing a required unique edge "DavAccount.owner"`)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dauo *DavAccountUpdateOne) sqlSave(ctx context.Context) (_node *DavAccount, err error) {
|
||||
if err := dauo.check(); err != nil {
|
||||
return _node, err
|
||||
}
|
||||
_spec := sqlgraph.NewUpdateSpec(davaccount.Table, davaccount.Columns, sqlgraph.NewFieldSpec(davaccount.FieldID, field.TypeInt))
|
||||
id, ok := dauo.mutation.ID()
|
||||
if !ok {
|
||||
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "DavAccount.id" for update`)}
|
||||
}
|
||||
_spec.Node.ID.Value = id
|
||||
if fields := dauo.fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, davaccount.FieldID)
|
||||
for _, f := range fields {
|
||||
if !davaccount.ValidColumn(f) {
|
||||
return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
if f != davaccount.FieldID {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
if ps := dauo.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if value, ok := dauo.mutation.UpdatedAt(); ok {
|
||||
_spec.SetField(davaccount.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if value, ok := dauo.mutation.DeletedAt(); ok {
|
||||
_spec.SetField(davaccount.FieldDeletedAt, field.TypeTime, value)
|
||||
}
|
||||
if dauo.mutation.DeletedAtCleared() {
|
||||
_spec.ClearField(davaccount.FieldDeletedAt, field.TypeTime)
|
||||
}
|
||||
if value, ok := dauo.mutation.Name(); ok {
|
||||
_spec.SetField(davaccount.FieldName, field.TypeString, value)
|
||||
}
|
||||
if value, ok := dauo.mutation.URI(); ok {
|
||||
_spec.SetField(davaccount.FieldURI, field.TypeString, value)
|
||||
}
|
||||
if value, ok := dauo.mutation.Password(); ok {
|
||||
_spec.SetField(davaccount.FieldPassword, field.TypeString, value)
|
||||
}
|
||||
if value, ok := dauo.mutation.Options(); ok {
|
||||
_spec.SetField(davaccount.FieldOptions, field.TypeBytes, value)
|
||||
}
|
||||
if value, ok := dauo.mutation.Props(); ok {
|
||||
_spec.SetField(davaccount.FieldProps, field.TypeJSON, value)
|
||||
}
|
||||
if dauo.mutation.PropsCleared() {
|
||||
_spec.ClearField(davaccount.FieldProps, field.TypeJSON)
|
||||
}
|
||||
if dauo.mutation.OwnerCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: davaccount.OwnerTable,
|
||||
Columns: []string{davaccount.OwnerColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := dauo.mutation.OwnerIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: davaccount.OwnerTable,
|
||||
Columns: []string{davaccount.OwnerColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(user.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
_node = &DavAccount{config: dauo.config}
|
||||
_spec.Assign = _node.assignValues
|
||||
_spec.ScanValues = _node.scanValues
|
||||
if err = sqlgraph.UpdateNode(ctx, dauo.driver, _spec); err != nil {
|
||||
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||
err = &NotFoundError{davaccount.Label}
|
||||
} else if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
dauo.mutation.done = true
|
||||
return _node, nil
|
||||
}
|
||||
212
ent/directlink.go
Normal file
212
ent/directlink.go
Normal file
@@ -0,0 +1,212 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/directlink"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/file"
|
||||
)
|
||||
|
||||
// DirectLink is the model entity for the DirectLink schema.
|
||||
type DirectLink struct {
|
||||
config `json:"-"`
|
||||
// ID of the ent.
|
||||
ID int `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"`
|
||||
// DeletedAt holds the value of the "deleted_at" field.
|
||||
DeletedAt *time.Time `json:"deleted_at,omitempty"`
|
||||
// Name holds the value of the "name" field.
|
||||
Name string `json:"name,omitempty"`
|
||||
// Downloads holds the value of the "downloads" field.
|
||||
Downloads int `json:"downloads,omitempty"`
|
||||
// FileID holds the value of the "file_id" field.
|
||||
FileID int `json:"file_id,omitempty"`
|
||||
// Speed holds the value of the "speed" field.
|
||||
Speed int `json:"speed,omitempty"`
|
||||
// Edges holds the relations/edges for other nodes in the graph.
|
||||
// The values are being populated by the DirectLinkQuery when eager-loading is set.
|
||||
Edges DirectLinkEdges `json:"edges"`
|
||||
selectValues sql.SelectValues
|
||||
}
|
||||
|
||||
// DirectLinkEdges holds the relations/edges for other nodes in the graph.
|
||||
type DirectLinkEdges struct {
|
||||
// File holds the value of the file edge.
|
||||
File *File `json:"file,omitempty"`
|
||||
// loadedTypes holds the information for reporting if a
|
||||
// type was loaded (or requested) in eager-loading or not.
|
||||
loadedTypes [1]bool
|
||||
}
|
||||
|
||||
// FileOrErr returns the File value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e DirectLinkEdges) FileOrErr() (*File, error) {
|
||||
if e.loadedTypes[0] {
|
||||
if e.File == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: file.Label}
|
||||
}
|
||||
return e.File, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "file"}
|
||||
}
|
||||
|
||||
// scanValues returns the types for scanning values from sql.Rows.
|
||||
func (*DirectLink) scanValues(columns []string) ([]any, error) {
|
||||
values := make([]any, len(columns))
|
||||
for i := range columns {
|
||||
switch columns[i] {
|
||||
case directlink.FieldID, directlink.FieldDownloads, directlink.FieldFileID, directlink.FieldSpeed:
|
||||
values[i] = new(sql.NullInt64)
|
||||
case directlink.FieldName:
|
||||
values[i] = new(sql.NullString)
|
||||
case directlink.FieldCreatedAt, directlink.FieldUpdatedAt, directlink.FieldDeletedAt:
|
||||
values[i] = new(sql.NullTime)
|
||||
default:
|
||||
values[i] = new(sql.UnknownType)
|
||||
}
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// assignValues assigns the values that were returned from sql.Rows (after scanning)
|
||||
// to the DirectLink fields.
|
||||
func (dl *DirectLink) 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 directlink.FieldID:
|
||||
value, ok := values[i].(*sql.NullInt64)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field id", value)
|
||||
}
|
||||
dl.ID = int(value.Int64)
|
||||
case directlink.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 {
|
||||
dl.CreatedAt = value.Time
|
||||
}
|
||||
case directlink.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 {
|
||||
dl.UpdatedAt = value.Time
|
||||
}
|
||||
case directlink.FieldDeletedAt:
|
||||
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field deleted_at", values[i])
|
||||
} else if value.Valid {
|
||||
dl.DeletedAt = new(time.Time)
|
||||
*dl.DeletedAt = value.Time
|
||||
}
|
||||
case directlink.FieldName:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field name", values[i])
|
||||
} else if value.Valid {
|
||||
dl.Name = value.String
|
||||
}
|
||||
case directlink.FieldDownloads:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field downloads", values[i])
|
||||
} else if value.Valid {
|
||||
dl.Downloads = int(value.Int64)
|
||||
}
|
||||
case directlink.FieldFileID:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field file_id", values[i])
|
||||
} else if value.Valid {
|
||||
dl.FileID = int(value.Int64)
|
||||
}
|
||||
case directlink.FieldSpeed:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field speed", values[i])
|
||||
} else if value.Valid {
|
||||
dl.Speed = int(value.Int64)
|
||||
}
|
||||
default:
|
||||
dl.selectValues.Set(columns[i], values[i])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value returns the ent.Value that was dynamically selected and assigned to the DirectLink.
|
||||
// This includes values selected through modifiers, order, etc.
|
||||
func (dl *DirectLink) Value(name string) (ent.Value, error) {
|
||||
return dl.selectValues.Get(name)
|
||||
}
|
||||
|
||||
// QueryFile queries the "file" edge of the DirectLink entity.
|
||||
func (dl *DirectLink) QueryFile() *FileQuery {
|
||||
return NewDirectLinkClient(dl.config).QueryFile(dl)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this DirectLink.
|
||||
// Note that you need to call DirectLink.Unwrap() before calling this method if this DirectLink
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (dl *DirectLink) Update() *DirectLinkUpdateOne {
|
||||
return NewDirectLinkClient(dl.config).UpdateOne(dl)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the DirectLink 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 (dl *DirectLink) Unwrap() *DirectLink {
|
||||
_tx, ok := dl.config.driver.(*txDriver)
|
||||
if !ok {
|
||||
panic("ent: DirectLink is not a transactional entity")
|
||||
}
|
||||
dl.config.driver = _tx.drv
|
||||
return dl
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer.
|
||||
func (dl *DirectLink) String() string {
|
||||
var builder strings.Builder
|
||||
builder.WriteString("DirectLink(")
|
||||
builder.WriteString(fmt.Sprintf("id=%v, ", dl.ID))
|
||||
builder.WriteString("created_at=")
|
||||
builder.WriteString(dl.CreatedAt.Format(time.ANSIC))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("updated_at=")
|
||||
builder.WriteString(dl.UpdatedAt.Format(time.ANSIC))
|
||||
builder.WriteString(", ")
|
||||
if v := dl.DeletedAt; v != nil {
|
||||
builder.WriteString("deleted_at=")
|
||||
builder.WriteString(v.Format(time.ANSIC))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("name=")
|
||||
builder.WriteString(dl.Name)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("downloads=")
|
||||
builder.WriteString(fmt.Sprintf("%v", dl.Downloads))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("file_id=")
|
||||
builder.WriteString(fmt.Sprintf("%v", dl.FileID))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("speed=")
|
||||
builder.WriteString(fmt.Sprintf("%v", dl.Speed))
|
||||
builder.WriteByte(')')
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
// SetFile manually set the edge as loaded state.
|
||||
func (e *DirectLink) SetFile(v *File) {
|
||||
e.Edges.File = v
|
||||
e.Edges.loadedTypes[0] = true
|
||||
}
|
||||
|
||||
// DirectLinks is a parsable slice of DirectLink.
|
||||
type DirectLinks []*DirectLink
|
||||
138
ent/directlink/directlink.go
Normal file
138
ent/directlink/directlink.go
Normal file
@@ -0,0 +1,138 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package directlink
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
)
|
||||
|
||||
const (
|
||||
// Label holds the string label denoting the directlink type in the database.
|
||||
Label = "direct_link"
|
||||
// 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"
|
||||
// FieldDeletedAt holds the string denoting the deleted_at field in the database.
|
||||
FieldDeletedAt = "deleted_at"
|
||||
// FieldName holds the string denoting the name field in the database.
|
||||
FieldName = "name"
|
||||
// FieldDownloads holds the string denoting the downloads field in the database.
|
||||
FieldDownloads = "downloads"
|
||||
// FieldFileID holds the string denoting the file_id field in the database.
|
||||
FieldFileID = "file_id"
|
||||
// FieldSpeed holds the string denoting the speed field in the database.
|
||||
FieldSpeed = "speed"
|
||||
// EdgeFile holds the string denoting the file edge name in mutations.
|
||||
EdgeFile = "file"
|
||||
// Table holds the table name of the directlink in the database.
|
||||
Table = "direct_links"
|
||||
// FileTable is the table that holds the file relation/edge.
|
||||
FileTable = "direct_links"
|
||||
// FileInverseTable is the table name for the File entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "file" package.
|
||||
FileInverseTable = "files"
|
||||
// FileColumn is the table column denoting the file relation/edge.
|
||||
FileColumn = "file_id"
|
||||
)
|
||||
|
||||
// Columns holds all SQL columns for directlink fields.
|
||||
var Columns = []string{
|
||||
FieldID,
|
||||
FieldCreatedAt,
|
||||
FieldUpdatedAt,
|
||||
FieldDeletedAt,
|
||||
FieldName,
|
||||
FieldDownloads,
|
||||
FieldFileID,
|
||||
FieldSpeed,
|
||||
}
|
||||
|
||||
// ValidColumn reports if the column name is valid (part of the table columns).
|
||||
func ValidColumn(column string) bool {
|
||||
for i := range Columns {
|
||||
if column == Columns[i] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Note that the variables below are initialized by the runtime
|
||||
// package on the initialization of the application. Therefore,
|
||||
// it should be imported in the main as follows:
|
||||
//
|
||||
// import _ "github.com/cloudreve/Cloudreve/v4/ent/runtime"
|
||||
var (
|
||||
Hooks [1]ent.Hook
|
||||
Interceptors [1]ent.Interceptor
|
||||
// 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
|
||||
)
|
||||
|
||||
// OrderOption defines the ordering options for the DirectLink queries.
|
||||
type OrderOption func(*sql.Selector)
|
||||
|
||||
// ByID orders the results by the id field.
|
||||
func ByID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByCreatedAt orders the results by the created_at field.
|
||||
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByUpdatedAt orders the results by the updated_at field.
|
||||
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByDeletedAt orders the results by the deleted_at field.
|
||||
func ByDeletedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldDeletedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByName orders the results by the name field.
|
||||
func ByName(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldName, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByDownloads orders the results by the downloads field.
|
||||
func ByDownloads(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldDownloads, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByFileID orders the results by the file_id field.
|
||||
func ByFileID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldFileID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// BySpeed orders the results by the speed field.
|
||||
func BySpeed(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldSpeed, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByFileField orders the results by file field.
|
||||
func ByFileField(field string, opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborTerms(s, newFileStep(), sql.OrderByField(field, opts...))
|
||||
}
|
||||
}
|
||||
func newFileStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(FileInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, FileTable, FileColumn),
|
||||
)
|
||||
}
|
||||
424
ent/directlink/where.go
Normal file
424
ent/directlink/where.go
Normal file
@@ -0,0 +1,424 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package directlink
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||
)
|
||||
|
||||
// ID filters vertices based on their ID field.
|
||||
func ID(id int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDEQ applies the EQ predicate on the ID field.
|
||||
func IDEQ(id int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDNEQ applies the NEQ predicate on the ID field.
|
||||
func IDNEQ(id int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldNEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDIn applies the In predicate on the ID field.
|
||||
func IDIn(ids ...int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDNotIn applies the NotIn predicate on the ID field.
|
||||
func IDNotIn(ids ...int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldNotIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDGT applies the GT predicate on the ID field.
|
||||
func IDGT(id int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldGT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDGTE applies the GTE predicate on the ID field.
|
||||
func IDGTE(id int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldGTE(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLT applies the LT predicate on the ID field.
|
||||
func IDLT(id int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldLT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLTE applies the LTE predicate on the ID field.
|
||||
func IDLTE(id int) predicate.DirectLink {
|
||||
return predicate.DirectLink(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.DirectLink {
|
||||
return predicate.DirectLink(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.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAt applies equality check predicate on the "deleted_at" field. It's identical to DeletedAtEQ.
|
||||
func DeletedAt(v time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldEQ(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// Name applies equality check predicate on the "name" field. It's identical to NameEQ.
|
||||
func Name(v string) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldEQ(FieldName, v))
|
||||
}
|
||||
|
||||
// Downloads applies equality check predicate on the "downloads" field. It's identical to DownloadsEQ.
|
||||
func Downloads(v int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldEQ(FieldDownloads, v))
|
||||
}
|
||||
|
||||
// FileID applies equality check predicate on the "file_id" field. It's identical to FileIDEQ.
|
||||
func FileID(v int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldEQ(FieldFileID, v))
|
||||
}
|
||||
|
||||
// Speed applies equality check predicate on the "speed" field. It's identical to SpeedEQ.
|
||||
func Speed(v int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldEQ(FieldSpeed, v))
|
||||
}
|
||||
|
||||
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
|
||||
func CreatedAtEQ(v time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
|
||||
func CreatedAtNEQ(v time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldNEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtIn applies the In predicate on the "created_at" field.
|
||||
func CreatedAtIn(vs ...time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldIn(FieldCreatedAt, vs...))
|
||||
}
|
||||
|
||||
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
|
||||
func CreatedAtNotIn(vs ...time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldNotIn(FieldCreatedAt, vs...))
|
||||
}
|
||||
|
||||
// CreatedAtGT applies the GT predicate on the "created_at" field.
|
||||
func CreatedAtGT(v time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldGT(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
|
||||
func CreatedAtGTE(v time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldGTE(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtLT applies the LT predicate on the "created_at" field.
|
||||
func CreatedAtLT(v time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldLT(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
|
||||
func CreatedAtLTE(v time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldLTE(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
|
||||
func UpdatedAtEQ(v time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
|
||||
func UpdatedAtNEQ(v time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldNEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtIn applies the In predicate on the "updated_at" field.
|
||||
func UpdatedAtIn(vs ...time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldIn(FieldUpdatedAt, vs...))
|
||||
}
|
||||
|
||||
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
|
||||
func UpdatedAtNotIn(vs ...time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldNotIn(FieldUpdatedAt, vs...))
|
||||
}
|
||||
|
||||
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
|
||||
func UpdatedAtGT(v time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldGT(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
|
||||
func UpdatedAtGTE(v time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldGTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
|
||||
func UpdatedAtLT(v time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldLT(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
|
||||
func UpdatedAtLTE(v time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldLTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtEQ applies the EQ predicate on the "deleted_at" field.
|
||||
func DeletedAtEQ(v time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldEQ(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtNEQ applies the NEQ predicate on the "deleted_at" field.
|
||||
func DeletedAtNEQ(v time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldNEQ(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtIn applies the In predicate on the "deleted_at" field.
|
||||
func DeletedAtIn(vs ...time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldIn(FieldDeletedAt, vs...))
|
||||
}
|
||||
|
||||
// DeletedAtNotIn applies the NotIn predicate on the "deleted_at" field.
|
||||
func DeletedAtNotIn(vs ...time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldNotIn(FieldDeletedAt, vs...))
|
||||
}
|
||||
|
||||
// DeletedAtGT applies the GT predicate on the "deleted_at" field.
|
||||
func DeletedAtGT(v time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldGT(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtGTE applies the GTE predicate on the "deleted_at" field.
|
||||
func DeletedAtGTE(v time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldGTE(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtLT applies the LT predicate on the "deleted_at" field.
|
||||
func DeletedAtLT(v time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldLT(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtLTE applies the LTE predicate on the "deleted_at" field.
|
||||
func DeletedAtLTE(v time.Time) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldLTE(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtIsNil applies the IsNil predicate on the "deleted_at" field.
|
||||
func DeletedAtIsNil() predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldIsNull(FieldDeletedAt))
|
||||
}
|
||||
|
||||
// DeletedAtNotNil applies the NotNil predicate on the "deleted_at" field.
|
||||
func DeletedAtNotNil() predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldNotNull(FieldDeletedAt))
|
||||
}
|
||||
|
||||
// NameEQ applies the EQ predicate on the "name" field.
|
||||
func NameEQ(v string) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldEQ(FieldName, v))
|
||||
}
|
||||
|
||||
// NameNEQ applies the NEQ predicate on the "name" field.
|
||||
func NameNEQ(v string) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldNEQ(FieldName, v))
|
||||
}
|
||||
|
||||
// NameIn applies the In predicate on the "name" field.
|
||||
func NameIn(vs ...string) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldIn(FieldName, vs...))
|
||||
}
|
||||
|
||||
// NameNotIn applies the NotIn predicate on the "name" field.
|
||||
func NameNotIn(vs ...string) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldNotIn(FieldName, vs...))
|
||||
}
|
||||
|
||||
// NameGT applies the GT predicate on the "name" field.
|
||||
func NameGT(v string) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldGT(FieldName, v))
|
||||
}
|
||||
|
||||
// NameGTE applies the GTE predicate on the "name" field.
|
||||
func NameGTE(v string) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldGTE(FieldName, v))
|
||||
}
|
||||
|
||||
// NameLT applies the LT predicate on the "name" field.
|
||||
func NameLT(v string) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldLT(FieldName, v))
|
||||
}
|
||||
|
||||
// NameLTE applies the LTE predicate on the "name" field.
|
||||
func NameLTE(v string) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldLTE(FieldName, v))
|
||||
}
|
||||
|
||||
// NameContains applies the Contains predicate on the "name" field.
|
||||
func NameContains(v string) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldContains(FieldName, v))
|
||||
}
|
||||
|
||||
// NameHasPrefix applies the HasPrefix predicate on the "name" field.
|
||||
func NameHasPrefix(v string) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldHasPrefix(FieldName, v))
|
||||
}
|
||||
|
||||
// NameHasSuffix applies the HasSuffix predicate on the "name" field.
|
||||
func NameHasSuffix(v string) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldHasSuffix(FieldName, v))
|
||||
}
|
||||
|
||||
// NameEqualFold applies the EqualFold predicate on the "name" field.
|
||||
func NameEqualFold(v string) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldEqualFold(FieldName, v))
|
||||
}
|
||||
|
||||
// NameContainsFold applies the ContainsFold predicate on the "name" field.
|
||||
func NameContainsFold(v string) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldContainsFold(FieldName, v))
|
||||
}
|
||||
|
||||
// DownloadsEQ applies the EQ predicate on the "downloads" field.
|
||||
func DownloadsEQ(v int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldEQ(FieldDownloads, v))
|
||||
}
|
||||
|
||||
// DownloadsNEQ applies the NEQ predicate on the "downloads" field.
|
||||
func DownloadsNEQ(v int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldNEQ(FieldDownloads, v))
|
||||
}
|
||||
|
||||
// DownloadsIn applies the In predicate on the "downloads" field.
|
||||
func DownloadsIn(vs ...int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldIn(FieldDownloads, vs...))
|
||||
}
|
||||
|
||||
// DownloadsNotIn applies the NotIn predicate on the "downloads" field.
|
||||
func DownloadsNotIn(vs ...int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldNotIn(FieldDownloads, vs...))
|
||||
}
|
||||
|
||||
// DownloadsGT applies the GT predicate on the "downloads" field.
|
||||
func DownloadsGT(v int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldGT(FieldDownloads, v))
|
||||
}
|
||||
|
||||
// DownloadsGTE applies the GTE predicate on the "downloads" field.
|
||||
func DownloadsGTE(v int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldGTE(FieldDownloads, v))
|
||||
}
|
||||
|
||||
// DownloadsLT applies the LT predicate on the "downloads" field.
|
||||
func DownloadsLT(v int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldLT(FieldDownloads, v))
|
||||
}
|
||||
|
||||
// DownloadsLTE applies the LTE predicate on the "downloads" field.
|
||||
func DownloadsLTE(v int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldLTE(FieldDownloads, v))
|
||||
}
|
||||
|
||||
// FileIDEQ applies the EQ predicate on the "file_id" field.
|
||||
func FileIDEQ(v int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldEQ(FieldFileID, v))
|
||||
}
|
||||
|
||||
// FileIDNEQ applies the NEQ predicate on the "file_id" field.
|
||||
func FileIDNEQ(v int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldNEQ(FieldFileID, v))
|
||||
}
|
||||
|
||||
// FileIDIn applies the In predicate on the "file_id" field.
|
||||
func FileIDIn(vs ...int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldIn(FieldFileID, vs...))
|
||||
}
|
||||
|
||||
// FileIDNotIn applies the NotIn predicate on the "file_id" field.
|
||||
func FileIDNotIn(vs ...int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldNotIn(FieldFileID, vs...))
|
||||
}
|
||||
|
||||
// SpeedEQ applies the EQ predicate on the "speed" field.
|
||||
func SpeedEQ(v int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldEQ(FieldSpeed, v))
|
||||
}
|
||||
|
||||
// SpeedNEQ applies the NEQ predicate on the "speed" field.
|
||||
func SpeedNEQ(v int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldNEQ(FieldSpeed, v))
|
||||
}
|
||||
|
||||
// SpeedIn applies the In predicate on the "speed" field.
|
||||
func SpeedIn(vs ...int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldIn(FieldSpeed, vs...))
|
||||
}
|
||||
|
||||
// SpeedNotIn applies the NotIn predicate on the "speed" field.
|
||||
func SpeedNotIn(vs ...int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldNotIn(FieldSpeed, vs...))
|
||||
}
|
||||
|
||||
// SpeedGT applies the GT predicate on the "speed" field.
|
||||
func SpeedGT(v int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldGT(FieldSpeed, v))
|
||||
}
|
||||
|
||||
// SpeedGTE applies the GTE predicate on the "speed" field.
|
||||
func SpeedGTE(v int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldGTE(FieldSpeed, v))
|
||||
}
|
||||
|
||||
// SpeedLT applies the LT predicate on the "speed" field.
|
||||
func SpeedLT(v int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldLT(FieldSpeed, v))
|
||||
}
|
||||
|
||||
// SpeedLTE applies the LTE predicate on the "speed" field.
|
||||
func SpeedLTE(v int) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.FieldLTE(FieldSpeed, v))
|
||||
}
|
||||
|
||||
// HasFile applies the HasEdge predicate on the "file" edge.
|
||||
func HasFile() predicate.DirectLink {
|
||||
return predicate.DirectLink(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, FileTable, FileColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasFileWith applies the HasEdge predicate on the "file" edge with a given conditions (other predicates).
|
||||
func HasFileWith(preds ...predicate.File) predicate.DirectLink {
|
||||
return predicate.DirectLink(func(s *sql.Selector) {
|
||||
step := newFileStep()
|
||||
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.DirectLink) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.AndPredicates(predicates...))
|
||||
}
|
||||
|
||||
// Or groups predicates with the OR operator between them.
|
||||
func Or(predicates ...predicate.DirectLink) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.OrPredicates(predicates...))
|
||||
}
|
||||
|
||||
// Not applies the not operator on the given predicate.
|
||||
func Not(p predicate.DirectLink) predicate.DirectLink {
|
||||
return predicate.DirectLink(sql.NotPredicates(p))
|
||||
}
|
||||
883
ent/directlink_create.go
Normal file
883
ent/directlink_create.go
Normal file
@@ -0,0 +1,883 @@
|
||||
// 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/cloudreve/Cloudreve/v4/ent/directlink"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/file"
|
||||
)
|
||||
|
||||
// DirectLinkCreate is the builder for creating a DirectLink entity.
|
||||
type DirectLinkCreate struct {
|
||||
config
|
||||
mutation *DirectLinkMutation
|
||||
hooks []Hook
|
||||
conflict []sql.ConflictOption
|
||||
}
|
||||
|
||||
// SetCreatedAt sets the "created_at" field.
|
||||
func (dlc *DirectLinkCreate) SetCreatedAt(t time.Time) *DirectLinkCreate {
|
||||
dlc.mutation.SetCreatedAt(t)
|
||||
return dlc
|
||||
}
|
||||
|
||||
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
|
||||
func (dlc *DirectLinkCreate) SetNillableCreatedAt(t *time.Time) *DirectLinkCreate {
|
||||
if t != nil {
|
||||
dlc.SetCreatedAt(*t)
|
||||
}
|
||||
return dlc
|
||||
}
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (dlc *DirectLinkCreate) SetUpdatedAt(t time.Time) *DirectLinkCreate {
|
||||
dlc.mutation.SetUpdatedAt(t)
|
||||
return dlc
|
||||
}
|
||||
|
||||
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
|
||||
func (dlc *DirectLinkCreate) SetNillableUpdatedAt(t *time.Time) *DirectLinkCreate {
|
||||
if t != nil {
|
||||
dlc.SetUpdatedAt(*t)
|
||||
}
|
||||
return dlc
|
||||
}
|
||||
|
||||
// SetDeletedAt sets the "deleted_at" field.
|
||||
func (dlc *DirectLinkCreate) SetDeletedAt(t time.Time) *DirectLinkCreate {
|
||||
dlc.mutation.SetDeletedAt(t)
|
||||
return dlc
|
||||
}
|
||||
|
||||
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
|
||||
func (dlc *DirectLinkCreate) SetNillableDeletedAt(t *time.Time) *DirectLinkCreate {
|
||||
if t != nil {
|
||||
dlc.SetDeletedAt(*t)
|
||||
}
|
||||
return dlc
|
||||
}
|
||||
|
||||
// SetName sets the "name" field.
|
||||
func (dlc *DirectLinkCreate) SetName(s string) *DirectLinkCreate {
|
||||
dlc.mutation.SetName(s)
|
||||
return dlc
|
||||
}
|
||||
|
||||
// SetDownloads sets the "downloads" field.
|
||||
func (dlc *DirectLinkCreate) SetDownloads(i int) *DirectLinkCreate {
|
||||
dlc.mutation.SetDownloads(i)
|
||||
return dlc
|
||||
}
|
||||
|
||||
// SetFileID sets the "file_id" field.
|
||||
func (dlc *DirectLinkCreate) SetFileID(i int) *DirectLinkCreate {
|
||||
dlc.mutation.SetFileID(i)
|
||||
return dlc
|
||||
}
|
||||
|
||||
// SetSpeed sets the "speed" field.
|
||||
func (dlc *DirectLinkCreate) SetSpeed(i int) *DirectLinkCreate {
|
||||
dlc.mutation.SetSpeed(i)
|
||||
return dlc
|
||||
}
|
||||
|
||||
// SetFile sets the "file" edge to the File entity.
|
||||
func (dlc *DirectLinkCreate) SetFile(f *File) *DirectLinkCreate {
|
||||
return dlc.SetFileID(f.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the DirectLinkMutation object of the builder.
|
||||
func (dlc *DirectLinkCreate) Mutation() *DirectLinkMutation {
|
||||
return dlc.mutation
|
||||
}
|
||||
|
||||
// Save creates the DirectLink in the database.
|
||||
func (dlc *DirectLinkCreate) Save(ctx context.Context) (*DirectLink, error) {
|
||||
if err := dlc.defaults(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return withHooks(ctx, dlc.sqlSave, dlc.mutation, dlc.hooks)
|
||||
}
|
||||
|
||||
// SaveX calls Save and panics if Save returns an error.
|
||||
func (dlc *DirectLinkCreate) SaveX(ctx context.Context) *DirectLink {
|
||||
v, err := dlc.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (dlc *DirectLinkCreate) Exec(ctx context.Context) error {
|
||||
_, err := dlc.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (dlc *DirectLinkCreate) ExecX(ctx context.Context) {
|
||||
if err := dlc.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (dlc *DirectLinkCreate) defaults() error {
|
||||
if _, ok := dlc.mutation.CreatedAt(); !ok {
|
||||
if directlink.DefaultCreatedAt == nil {
|
||||
return fmt.Errorf("ent: uninitialized directlink.DefaultCreatedAt (forgotten import ent/runtime?)")
|
||||
}
|
||||
v := directlink.DefaultCreatedAt()
|
||||
dlc.mutation.SetCreatedAt(v)
|
||||
}
|
||||
if _, ok := dlc.mutation.UpdatedAt(); !ok {
|
||||
if directlink.DefaultUpdatedAt == nil {
|
||||
return fmt.Errorf("ent: uninitialized directlink.DefaultUpdatedAt (forgotten import ent/runtime?)")
|
||||
}
|
||||
v := directlink.DefaultUpdatedAt()
|
||||
dlc.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (dlc *DirectLinkCreate) check() error {
|
||||
if _, ok := dlc.mutation.CreatedAt(); !ok {
|
||||
return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "DirectLink.created_at"`)}
|
||||
}
|
||||
if _, ok := dlc.mutation.UpdatedAt(); !ok {
|
||||
return &ValidationError{Name: "updated_at", err: errors.New(`ent: missing required field "DirectLink.updated_at"`)}
|
||||
}
|
||||
if _, ok := dlc.mutation.Name(); !ok {
|
||||
return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "DirectLink.name"`)}
|
||||
}
|
||||
if _, ok := dlc.mutation.Downloads(); !ok {
|
||||
return &ValidationError{Name: "downloads", err: errors.New(`ent: missing required field "DirectLink.downloads"`)}
|
||||
}
|
||||
if _, ok := dlc.mutation.FileID(); !ok {
|
||||
return &ValidationError{Name: "file_id", err: errors.New(`ent: missing required field "DirectLink.file_id"`)}
|
||||
}
|
||||
if _, ok := dlc.mutation.Speed(); !ok {
|
||||
return &ValidationError{Name: "speed", err: errors.New(`ent: missing required field "DirectLink.speed"`)}
|
||||
}
|
||||
if _, ok := dlc.mutation.FileID(); !ok {
|
||||
return &ValidationError{Name: "file", err: errors.New(`ent: missing required edge "DirectLink.file"`)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dlc *DirectLinkCreate) sqlSave(ctx context.Context) (*DirectLink, error) {
|
||||
if err := dlc.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_node, _spec := dlc.createSpec()
|
||||
if err := sqlgraph.CreateNode(ctx, dlc.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)
|
||||
dlc.mutation.id = &_node.ID
|
||||
dlc.mutation.done = true
|
||||
return _node, nil
|
||||
}
|
||||
|
||||
func (dlc *DirectLinkCreate) createSpec() (*DirectLink, *sqlgraph.CreateSpec) {
|
||||
var (
|
||||
_node = &DirectLink{config: dlc.config}
|
||||
_spec = sqlgraph.NewCreateSpec(directlink.Table, sqlgraph.NewFieldSpec(directlink.FieldID, field.TypeInt))
|
||||
)
|
||||
|
||||
if id, ok := dlc.mutation.ID(); ok {
|
||||
_node.ID = id
|
||||
id64 := int64(id)
|
||||
_spec.ID.Value = id64
|
||||
}
|
||||
|
||||
_spec.OnConflict = dlc.conflict
|
||||
if value, ok := dlc.mutation.CreatedAt(); ok {
|
||||
_spec.SetField(directlink.FieldCreatedAt, field.TypeTime, value)
|
||||
_node.CreatedAt = value
|
||||
}
|
||||
if value, ok := dlc.mutation.UpdatedAt(); ok {
|
||||
_spec.SetField(directlink.FieldUpdatedAt, field.TypeTime, value)
|
||||
_node.UpdatedAt = value
|
||||
}
|
||||
if value, ok := dlc.mutation.DeletedAt(); ok {
|
||||
_spec.SetField(directlink.FieldDeletedAt, field.TypeTime, value)
|
||||
_node.DeletedAt = &value
|
||||
}
|
||||
if value, ok := dlc.mutation.Name(); ok {
|
||||
_spec.SetField(directlink.FieldName, field.TypeString, value)
|
||||
_node.Name = value
|
||||
}
|
||||
if value, ok := dlc.mutation.Downloads(); ok {
|
||||
_spec.SetField(directlink.FieldDownloads, field.TypeInt, value)
|
||||
_node.Downloads = value
|
||||
}
|
||||
if value, ok := dlc.mutation.Speed(); ok {
|
||||
_spec.SetField(directlink.FieldSpeed, field.TypeInt, value)
|
||||
_node.Speed = value
|
||||
}
|
||||
if nodes := dlc.mutation.FileIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: directlink.FileTable,
|
||||
Columns: []string{directlink.FileColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(file.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_node.FileID = nodes[0]
|
||||
_spec.Edges = append(_spec.Edges, edge)
|
||||
}
|
||||
return _node, _spec
|
||||
}
|
||||
|
||||
// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
|
||||
// of the `INSERT` statement. For example:
|
||||
//
|
||||
// client.DirectLink.Create().
|
||||
// SetCreatedAt(v).
|
||||
// OnConflict(
|
||||
// // Update the row with the new values
|
||||
// // the was proposed for insertion.
|
||||
// sql.ResolveWithNewValues(),
|
||||
// ).
|
||||
// // Override some of the fields with custom
|
||||
// // update values.
|
||||
// Update(func(u *ent.DirectLinkUpsert) {
|
||||
// SetCreatedAt(v+v).
|
||||
// }).
|
||||
// Exec(ctx)
|
||||
func (dlc *DirectLinkCreate) OnConflict(opts ...sql.ConflictOption) *DirectLinkUpsertOne {
|
||||
dlc.conflict = opts
|
||||
return &DirectLinkUpsertOne{
|
||||
create: dlc,
|
||||
}
|
||||
}
|
||||
|
||||
// OnConflictColumns calls `OnConflict` and configures the columns
|
||||
// as conflict target. Using this option is equivalent to using:
|
||||
//
|
||||
// client.DirectLink.Create().
|
||||
// OnConflict(sql.ConflictColumns(columns...)).
|
||||
// Exec(ctx)
|
||||
func (dlc *DirectLinkCreate) OnConflictColumns(columns ...string) *DirectLinkUpsertOne {
|
||||
dlc.conflict = append(dlc.conflict, sql.ConflictColumns(columns...))
|
||||
return &DirectLinkUpsertOne{
|
||||
create: dlc,
|
||||
}
|
||||
}
|
||||
|
||||
type (
|
||||
// DirectLinkUpsertOne is the builder for "upsert"-ing
|
||||
// one DirectLink node.
|
||||
DirectLinkUpsertOne struct {
|
||||
create *DirectLinkCreate
|
||||
}
|
||||
|
||||
// DirectLinkUpsert is the "OnConflict" setter.
|
||||
DirectLinkUpsert struct {
|
||||
*sql.UpdateSet
|
||||
}
|
||||
)
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (u *DirectLinkUpsert) SetUpdatedAt(v time.Time) *DirectLinkUpsert {
|
||||
u.Set(directlink.FieldUpdatedAt, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
|
||||
func (u *DirectLinkUpsert) UpdateUpdatedAt() *DirectLinkUpsert {
|
||||
u.SetExcluded(directlink.FieldUpdatedAt)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetDeletedAt sets the "deleted_at" field.
|
||||
func (u *DirectLinkUpsert) SetDeletedAt(v time.Time) *DirectLinkUpsert {
|
||||
u.Set(directlink.FieldDeletedAt, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
|
||||
func (u *DirectLinkUpsert) UpdateDeletedAt() *DirectLinkUpsert {
|
||||
u.SetExcluded(directlink.FieldDeletedAt)
|
||||
return u
|
||||
}
|
||||
|
||||
// ClearDeletedAt clears the value of the "deleted_at" field.
|
||||
func (u *DirectLinkUpsert) ClearDeletedAt() *DirectLinkUpsert {
|
||||
u.SetNull(directlink.FieldDeletedAt)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetName sets the "name" field.
|
||||
func (u *DirectLinkUpsert) SetName(v string) *DirectLinkUpsert {
|
||||
u.Set(directlink.FieldName, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateName sets the "name" field to the value that was provided on create.
|
||||
func (u *DirectLinkUpsert) UpdateName() *DirectLinkUpsert {
|
||||
u.SetExcluded(directlink.FieldName)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetDownloads sets the "downloads" field.
|
||||
func (u *DirectLinkUpsert) SetDownloads(v int) *DirectLinkUpsert {
|
||||
u.Set(directlink.FieldDownloads, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateDownloads sets the "downloads" field to the value that was provided on create.
|
||||
func (u *DirectLinkUpsert) UpdateDownloads() *DirectLinkUpsert {
|
||||
u.SetExcluded(directlink.FieldDownloads)
|
||||
return u
|
||||
}
|
||||
|
||||
// AddDownloads adds v to the "downloads" field.
|
||||
func (u *DirectLinkUpsert) AddDownloads(v int) *DirectLinkUpsert {
|
||||
u.Add(directlink.FieldDownloads, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetFileID sets the "file_id" field.
|
||||
func (u *DirectLinkUpsert) SetFileID(v int) *DirectLinkUpsert {
|
||||
u.Set(directlink.FieldFileID, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateFileID sets the "file_id" field to the value that was provided on create.
|
||||
func (u *DirectLinkUpsert) UpdateFileID() *DirectLinkUpsert {
|
||||
u.SetExcluded(directlink.FieldFileID)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetSpeed sets the "speed" field.
|
||||
func (u *DirectLinkUpsert) SetSpeed(v int) *DirectLinkUpsert {
|
||||
u.Set(directlink.FieldSpeed, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateSpeed sets the "speed" field to the value that was provided on create.
|
||||
func (u *DirectLinkUpsert) UpdateSpeed() *DirectLinkUpsert {
|
||||
u.SetExcluded(directlink.FieldSpeed)
|
||||
return u
|
||||
}
|
||||
|
||||
// AddSpeed adds v to the "speed" field.
|
||||
func (u *DirectLinkUpsert) AddSpeed(v int) *DirectLinkUpsert {
|
||||
u.Add(directlink.FieldSpeed, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateNewValues updates the mutable fields using the new values that were set on create.
|
||||
// Using this option is equivalent to using:
|
||||
//
|
||||
// client.DirectLink.Create().
|
||||
// OnConflict(
|
||||
// sql.ResolveWithNewValues(),
|
||||
// ).
|
||||
// Exec(ctx)
|
||||
func (u *DirectLinkUpsertOne) UpdateNewValues() *DirectLinkUpsertOne {
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues())
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) {
|
||||
if _, exists := u.create.mutation.CreatedAt(); exists {
|
||||
s.SetIgnore(directlink.FieldCreatedAt)
|
||||
}
|
||||
}))
|
||||
return u
|
||||
}
|
||||
|
||||
// Ignore sets each column to itself in case of conflict.
|
||||
// Using this option is equivalent to using:
|
||||
//
|
||||
// client.DirectLink.Create().
|
||||
// OnConflict(sql.ResolveWithIgnore()).
|
||||
// Exec(ctx)
|
||||
func (u *DirectLinkUpsertOne) Ignore() *DirectLinkUpsertOne {
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore())
|
||||
return u
|
||||
}
|
||||
|
||||
// DoNothing configures the conflict_action to `DO NOTHING`.
|
||||
// Supported only by SQLite and PostgreSQL.
|
||||
func (u *DirectLinkUpsertOne) DoNothing() *DirectLinkUpsertOne {
|
||||
u.create.conflict = append(u.create.conflict, sql.DoNothing())
|
||||
return u
|
||||
}
|
||||
|
||||
// Update allows overriding fields `UPDATE` values. See the DirectLinkCreate.OnConflict
|
||||
// documentation for more info.
|
||||
func (u *DirectLinkUpsertOne) Update(set func(*DirectLinkUpsert)) *DirectLinkUpsertOne {
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
|
||||
set(&DirectLinkUpsert{UpdateSet: update})
|
||||
}))
|
||||
return u
|
||||
}
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (u *DirectLinkUpsertOne) SetUpdatedAt(v time.Time) *DirectLinkUpsertOne {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.SetUpdatedAt(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
|
||||
func (u *DirectLinkUpsertOne) UpdateUpdatedAt() *DirectLinkUpsertOne {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.UpdateUpdatedAt()
|
||||
})
|
||||
}
|
||||
|
||||
// SetDeletedAt sets the "deleted_at" field.
|
||||
func (u *DirectLinkUpsertOne) SetDeletedAt(v time.Time) *DirectLinkUpsertOne {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.SetDeletedAt(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
|
||||
func (u *DirectLinkUpsertOne) UpdateDeletedAt() *DirectLinkUpsertOne {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.UpdateDeletedAt()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearDeletedAt clears the value of the "deleted_at" field.
|
||||
func (u *DirectLinkUpsertOne) ClearDeletedAt() *DirectLinkUpsertOne {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.ClearDeletedAt()
|
||||
})
|
||||
}
|
||||
|
||||
// SetName sets the "name" field.
|
||||
func (u *DirectLinkUpsertOne) SetName(v string) *DirectLinkUpsertOne {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.SetName(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateName sets the "name" field to the value that was provided on create.
|
||||
func (u *DirectLinkUpsertOne) UpdateName() *DirectLinkUpsertOne {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.UpdateName()
|
||||
})
|
||||
}
|
||||
|
||||
// SetDownloads sets the "downloads" field.
|
||||
func (u *DirectLinkUpsertOne) SetDownloads(v int) *DirectLinkUpsertOne {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.SetDownloads(v)
|
||||
})
|
||||
}
|
||||
|
||||
// AddDownloads adds v to the "downloads" field.
|
||||
func (u *DirectLinkUpsertOne) AddDownloads(v int) *DirectLinkUpsertOne {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.AddDownloads(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateDownloads sets the "downloads" field to the value that was provided on create.
|
||||
func (u *DirectLinkUpsertOne) UpdateDownloads() *DirectLinkUpsertOne {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.UpdateDownloads()
|
||||
})
|
||||
}
|
||||
|
||||
// SetFileID sets the "file_id" field.
|
||||
func (u *DirectLinkUpsertOne) SetFileID(v int) *DirectLinkUpsertOne {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.SetFileID(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateFileID sets the "file_id" field to the value that was provided on create.
|
||||
func (u *DirectLinkUpsertOne) UpdateFileID() *DirectLinkUpsertOne {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.UpdateFileID()
|
||||
})
|
||||
}
|
||||
|
||||
// SetSpeed sets the "speed" field.
|
||||
func (u *DirectLinkUpsertOne) SetSpeed(v int) *DirectLinkUpsertOne {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.SetSpeed(v)
|
||||
})
|
||||
}
|
||||
|
||||
// AddSpeed adds v to the "speed" field.
|
||||
func (u *DirectLinkUpsertOne) AddSpeed(v int) *DirectLinkUpsertOne {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.AddSpeed(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateSpeed sets the "speed" field to the value that was provided on create.
|
||||
func (u *DirectLinkUpsertOne) UpdateSpeed() *DirectLinkUpsertOne {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.UpdateSpeed()
|
||||
})
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (u *DirectLinkUpsertOne) Exec(ctx context.Context) error {
|
||||
if len(u.create.conflict) == 0 {
|
||||
return errors.New("ent: missing options for DirectLinkCreate.OnConflict")
|
||||
}
|
||||
return u.create.Exec(ctx)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (u *DirectLinkUpsertOne) ExecX(ctx context.Context) {
|
||||
if err := u.create.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Exec executes the UPSERT query and returns the inserted/updated ID.
|
||||
func (u *DirectLinkUpsertOne) ID(ctx context.Context) (id int, err error) {
|
||||
node, err := u.create.Save(ctx)
|
||||
if err != nil {
|
||||
return id, err
|
||||
}
|
||||
return node.ID, nil
|
||||
}
|
||||
|
||||
// IDX is like ID, but panics if an error occurs.
|
||||
func (u *DirectLinkUpsertOne) IDX(ctx context.Context) int {
|
||||
id, err := u.ID(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
func (m *DirectLinkCreate) SetRawID(t int) *DirectLinkCreate {
|
||||
m.mutation.SetRawID(t)
|
||||
return m
|
||||
}
|
||||
|
||||
// DirectLinkCreateBulk is the builder for creating many DirectLink entities in bulk.
|
||||
type DirectLinkCreateBulk struct {
|
||||
config
|
||||
err error
|
||||
builders []*DirectLinkCreate
|
||||
conflict []sql.ConflictOption
|
||||
}
|
||||
|
||||
// Save creates the DirectLink entities in the database.
|
||||
func (dlcb *DirectLinkCreateBulk) Save(ctx context.Context) ([]*DirectLink, error) {
|
||||
if dlcb.err != nil {
|
||||
return nil, dlcb.err
|
||||
}
|
||||
specs := make([]*sqlgraph.CreateSpec, len(dlcb.builders))
|
||||
nodes := make([]*DirectLink, len(dlcb.builders))
|
||||
mutators := make([]Mutator, len(dlcb.builders))
|
||||
for i := range dlcb.builders {
|
||||
func(i int, root context.Context) {
|
||||
builder := dlcb.builders[i]
|
||||
builder.defaults()
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*DirectLinkMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
if err := builder.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
builder.mutation = mutation
|
||||
var err error
|
||||
nodes[i], specs[i] = builder.createSpec()
|
||||
if i < len(mutators)-1 {
|
||||
_, err = mutators[i+1].Mutate(root, dlcb.builders[i+1].mutation)
|
||||
} else {
|
||||
spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
|
||||
spec.OnConflict = dlcb.conflict
|
||||
// Invoke the actual operation on the latest mutation in the chain.
|
||||
if err = sqlgraph.BatchCreate(ctx, dlcb.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, dlcb.builders[0].mutation); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (dlcb *DirectLinkCreateBulk) SaveX(ctx context.Context) []*DirectLink {
|
||||
v, err := dlcb.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (dlcb *DirectLinkCreateBulk) Exec(ctx context.Context) error {
|
||||
_, err := dlcb.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (dlcb *DirectLinkCreateBulk) ExecX(ctx context.Context) {
|
||||
if err := dlcb.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
|
||||
// of the `INSERT` statement. For example:
|
||||
//
|
||||
// client.DirectLink.CreateBulk(builders...).
|
||||
// OnConflict(
|
||||
// // Update the row with the new values
|
||||
// // the was proposed for insertion.
|
||||
// sql.ResolveWithNewValues(),
|
||||
// ).
|
||||
// // Override some of the fields with custom
|
||||
// // update values.
|
||||
// Update(func(u *ent.DirectLinkUpsert) {
|
||||
// SetCreatedAt(v+v).
|
||||
// }).
|
||||
// Exec(ctx)
|
||||
func (dlcb *DirectLinkCreateBulk) OnConflict(opts ...sql.ConflictOption) *DirectLinkUpsertBulk {
|
||||
dlcb.conflict = opts
|
||||
return &DirectLinkUpsertBulk{
|
||||
create: dlcb,
|
||||
}
|
||||
}
|
||||
|
||||
// OnConflictColumns calls `OnConflict` and configures the columns
|
||||
// as conflict target. Using this option is equivalent to using:
|
||||
//
|
||||
// client.DirectLink.Create().
|
||||
// OnConflict(sql.ConflictColumns(columns...)).
|
||||
// Exec(ctx)
|
||||
func (dlcb *DirectLinkCreateBulk) OnConflictColumns(columns ...string) *DirectLinkUpsertBulk {
|
||||
dlcb.conflict = append(dlcb.conflict, sql.ConflictColumns(columns...))
|
||||
return &DirectLinkUpsertBulk{
|
||||
create: dlcb,
|
||||
}
|
||||
}
|
||||
|
||||
// DirectLinkUpsertBulk is the builder for "upsert"-ing
|
||||
// a bulk of DirectLink nodes.
|
||||
type DirectLinkUpsertBulk struct {
|
||||
create *DirectLinkCreateBulk
|
||||
}
|
||||
|
||||
// UpdateNewValues updates the mutable fields using the new values that
|
||||
// were set on create. Using this option is equivalent to using:
|
||||
//
|
||||
// client.DirectLink.Create().
|
||||
// OnConflict(
|
||||
// sql.ResolveWithNewValues(),
|
||||
// ).
|
||||
// Exec(ctx)
|
||||
func (u *DirectLinkUpsertBulk) UpdateNewValues() *DirectLinkUpsertBulk {
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWithNewValues())
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(s *sql.UpdateSet) {
|
||||
for _, b := range u.create.builders {
|
||||
if _, exists := b.mutation.CreatedAt(); exists {
|
||||
s.SetIgnore(directlink.FieldCreatedAt)
|
||||
}
|
||||
}
|
||||
}))
|
||||
return u
|
||||
}
|
||||
|
||||
// Ignore sets each column to itself in case of conflict.
|
||||
// Using this option is equivalent to using:
|
||||
//
|
||||
// client.DirectLink.Create().
|
||||
// OnConflict(sql.ResolveWithIgnore()).
|
||||
// Exec(ctx)
|
||||
func (u *DirectLinkUpsertBulk) Ignore() *DirectLinkUpsertBulk {
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWithIgnore())
|
||||
return u
|
||||
}
|
||||
|
||||
// DoNothing configures the conflict_action to `DO NOTHING`.
|
||||
// Supported only by SQLite and PostgreSQL.
|
||||
func (u *DirectLinkUpsertBulk) DoNothing() *DirectLinkUpsertBulk {
|
||||
u.create.conflict = append(u.create.conflict, sql.DoNothing())
|
||||
return u
|
||||
}
|
||||
|
||||
// Update allows overriding fields `UPDATE` values. See the DirectLinkCreateBulk.OnConflict
|
||||
// documentation for more info.
|
||||
func (u *DirectLinkUpsertBulk) Update(set func(*DirectLinkUpsert)) *DirectLinkUpsertBulk {
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
|
||||
set(&DirectLinkUpsert{UpdateSet: update})
|
||||
}))
|
||||
return u
|
||||
}
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (u *DirectLinkUpsertBulk) SetUpdatedAt(v time.Time) *DirectLinkUpsertBulk {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.SetUpdatedAt(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateUpdatedAt sets the "updated_at" field to the value that was provided on create.
|
||||
func (u *DirectLinkUpsertBulk) UpdateUpdatedAt() *DirectLinkUpsertBulk {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.UpdateUpdatedAt()
|
||||
})
|
||||
}
|
||||
|
||||
// SetDeletedAt sets the "deleted_at" field.
|
||||
func (u *DirectLinkUpsertBulk) SetDeletedAt(v time.Time) *DirectLinkUpsertBulk {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.SetDeletedAt(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateDeletedAt sets the "deleted_at" field to the value that was provided on create.
|
||||
func (u *DirectLinkUpsertBulk) UpdateDeletedAt() *DirectLinkUpsertBulk {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.UpdateDeletedAt()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearDeletedAt clears the value of the "deleted_at" field.
|
||||
func (u *DirectLinkUpsertBulk) ClearDeletedAt() *DirectLinkUpsertBulk {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.ClearDeletedAt()
|
||||
})
|
||||
}
|
||||
|
||||
// SetName sets the "name" field.
|
||||
func (u *DirectLinkUpsertBulk) SetName(v string) *DirectLinkUpsertBulk {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.SetName(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateName sets the "name" field to the value that was provided on create.
|
||||
func (u *DirectLinkUpsertBulk) UpdateName() *DirectLinkUpsertBulk {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.UpdateName()
|
||||
})
|
||||
}
|
||||
|
||||
// SetDownloads sets the "downloads" field.
|
||||
func (u *DirectLinkUpsertBulk) SetDownloads(v int) *DirectLinkUpsertBulk {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.SetDownloads(v)
|
||||
})
|
||||
}
|
||||
|
||||
// AddDownloads adds v to the "downloads" field.
|
||||
func (u *DirectLinkUpsertBulk) AddDownloads(v int) *DirectLinkUpsertBulk {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.AddDownloads(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateDownloads sets the "downloads" field to the value that was provided on create.
|
||||
func (u *DirectLinkUpsertBulk) UpdateDownloads() *DirectLinkUpsertBulk {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.UpdateDownloads()
|
||||
})
|
||||
}
|
||||
|
||||
// SetFileID sets the "file_id" field.
|
||||
func (u *DirectLinkUpsertBulk) SetFileID(v int) *DirectLinkUpsertBulk {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.SetFileID(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateFileID sets the "file_id" field to the value that was provided on create.
|
||||
func (u *DirectLinkUpsertBulk) UpdateFileID() *DirectLinkUpsertBulk {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.UpdateFileID()
|
||||
})
|
||||
}
|
||||
|
||||
// SetSpeed sets the "speed" field.
|
||||
func (u *DirectLinkUpsertBulk) SetSpeed(v int) *DirectLinkUpsertBulk {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.SetSpeed(v)
|
||||
})
|
||||
}
|
||||
|
||||
// AddSpeed adds v to the "speed" field.
|
||||
func (u *DirectLinkUpsertBulk) AddSpeed(v int) *DirectLinkUpsertBulk {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.AddSpeed(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateSpeed sets the "speed" field to the value that was provided on create.
|
||||
func (u *DirectLinkUpsertBulk) UpdateSpeed() *DirectLinkUpsertBulk {
|
||||
return u.Update(func(s *DirectLinkUpsert) {
|
||||
s.UpdateSpeed()
|
||||
})
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (u *DirectLinkUpsertBulk) Exec(ctx context.Context) error {
|
||||
if u.create.err != nil {
|
||||
return u.create.err
|
||||
}
|
||||
for i, b := range u.create.builders {
|
||||
if len(b.conflict) != 0 {
|
||||
return fmt.Errorf("ent: OnConflict was set for builder %d. Set it on the DirectLinkCreateBulk instead", i)
|
||||
}
|
||||
}
|
||||
if len(u.create.conflict) == 0 {
|
||||
return errors.New("ent: missing options for DirectLinkCreateBulk.OnConflict")
|
||||
}
|
||||
return u.create.Exec(ctx)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (u *DirectLinkUpsertBulk) ExecX(ctx context.Context) {
|
||||
if err := u.create.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
88
ent/directlink_delete.go
Normal file
88
ent/directlink_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/cloudreve/Cloudreve/v4/ent/directlink"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||
)
|
||||
|
||||
// DirectLinkDelete is the builder for deleting a DirectLink entity.
|
||||
type DirectLinkDelete struct {
|
||||
config
|
||||
hooks []Hook
|
||||
mutation *DirectLinkMutation
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the DirectLinkDelete builder.
|
||||
func (dld *DirectLinkDelete) Where(ps ...predicate.DirectLink) *DirectLinkDelete {
|
||||
dld.mutation.Where(ps...)
|
||||
return dld
|
||||
}
|
||||
|
||||
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||
func (dld *DirectLinkDelete) Exec(ctx context.Context) (int, error) {
|
||||
return withHooks(ctx, dld.sqlExec, dld.mutation, dld.hooks)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (dld *DirectLinkDelete) ExecX(ctx context.Context) int {
|
||||
n, err := dld.Exec(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (dld *DirectLinkDelete) sqlExec(ctx context.Context) (int, error) {
|
||||
_spec := sqlgraph.NewDeleteSpec(directlink.Table, sqlgraph.NewFieldSpec(directlink.FieldID, field.TypeInt))
|
||||
if ps := dld.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
affected, err := sqlgraph.DeleteNodes(ctx, dld.driver, _spec)
|
||||
if err != nil && sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
dld.mutation.done = true
|
||||
return affected, err
|
||||
}
|
||||
|
||||
// DirectLinkDeleteOne is the builder for deleting a single DirectLink entity.
|
||||
type DirectLinkDeleteOne struct {
|
||||
dld *DirectLinkDelete
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the DirectLinkDelete builder.
|
||||
func (dldo *DirectLinkDeleteOne) Where(ps ...predicate.DirectLink) *DirectLinkDeleteOne {
|
||||
dldo.dld.mutation.Where(ps...)
|
||||
return dldo
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (dldo *DirectLinkDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := dldo.dld.Exec(ctx)
|
||||
switch {
|
||||
case err != nil:
|
||||
return err
|
||||
case n == 0:
|
||||
return &NotFoundError{directlink.Label}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (dldo *DirectLinkDeleteOne) ExecX(ctx context.Context) {
|
||||
if err := dldo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
605
ent/directlink_query.go
Normal file
605
ent/directlink_query.go
Normal file
@@ -0,0 +1,605 @@
|
||||
// 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/cloudreve/Cloudreve/v4/ent/directlink"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/file"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||
)
|
||||
|
||||
// DirectLinkQuery is the builder for querying DirectLink entities.
|
||||
type DirectLinkQuery struct {
|
||||
config
|
||||
ctx *QueryContext
|
||||
order []directlink.OrderOption
|
||||
inters []Interceptor
|
||||
predicates []predicate.DirectLink
|
||||
withFile *FileQuery
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the DirectLinkQuery builder.
|
||||
func (dlq *DirectLinkQuery) Where(ps ...predicate.DirectLink) *DirectLinkQuery {
|
||||
dlq.predicates = append(dlq.predicates, ps...)
|
||||
return dlq
|
||||
}
|
||||
|
||||
// Limit the number of records to be returned by this query.
|
||||
func (dlq *DirectLinkQuery) Limit(limit int) *DirectLinkQuery {
|
||||
dlq.ctx.Limit = &limit
|
||||
return dlq
|
||||
}
|
||||
|
||||
// Offset to start from.
|
||||
func (dlq *DirectLinkQuery) Offset(offset int) *DirectLinkQuery {
|
||||
dlq.ctx.Offset = &offset
|
||||
return dlq
|
||||
}
|
||||
|
||||
// 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 (dlq *DirectLinkQuery) Unique(unique bool) *DirectLinkQuery {
|
||||
dlq.ctx.Unique = &unique
|
||||
return dlq
|
||||
}
|
||||
|
||||
// Order specifies how the records should be ordered.
|
||||
func (dlq *DirectLinkQuery) Order(o ...directlink.OrderOption) *DirectLinkQuery {
|
||||
dlq.order = append(dlq.order, o...)
|
||||
return dlq
|
||||
}
|
||||
|
||||
// QueryFile chains the current query on the "file" edge.
|
||||
func (dlq *DirectLinkQuery) QueryFile() *FileQuery {
|
||||
query := (&FileClient{config: dlq.config}).Query()
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := dlq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector := dlq.sqlQuery(ctx)
|
||||
if err := selector.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(directlink.Table, directlink.FieldID, selector),
|
||||
sqlgraph.To(file.Table, file.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, directlink.FileTable, directlink.FileColumn),
|
||||
)
|
||||
fromU = sqlgraph.SetNeighbors(dlq.driver.Dialect(), step)
|
||||
return fromU, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// First returns the first DirectLink entity from the query.
|
||||
// Returns a *NotFoundError when no DirectLink was found.
|
||||
func (dlq *DirectLinkQuery) First(ctx context.Context) (*DirectLink, error) {
|
||||
nodes, err := dlq.Limit(1).All(setContextOp(ctx, dlq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nil, &NotFoundError{directlink.Label}
|
||||
}
|
||||
return nodes[0], nil
|
||||
}
|
||||
|
||||
// FirstX is like First, but panics if an error occurs.
|
||||
func (dlq *DirectLinkQuery) FirstX(ctx context.Context) *DirectLink {
|
||||
node, err := dlq.First(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// FirstID returns the first DirectLink ID from the query.
|
||||
// Returns a *NotFoundError when no DirectLink ID was found.
|
||||
func (dlq *DirectLinkQuery) FirstID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = dlq.Limit(1).IDs(setContextOp(ctx, dlq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
err = &NotFoundError{directlink.Label}
|
||||
return
|
||||
}
|
||||
return ids[0], nil
|
||||
}
|
||||
|
||||
// FirstIDX is like FirstID, but panics if an error occurs.
|
||||
func (dlq *DirectLinkQuery) FirstIDX(ctx context.Context) int {
|
||||
id, err := dlq.FirstID(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// Only returns a single DirectLink entity found by the query, ensuring it only returns one.
|
||||
// Returns a *NotSingularError when more than one DirectLink entity is found.
|
||||
// Returns a *NotFoundError when no DirectLink entities are found.
|
||||
func (dlq *DirectLinkQuery) Only(ctx context.Context) (*DirectLink, error) {
|
||||
nodes, err := dlq.Limit(2).All(setContextOp(ctx, dlq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch len(nodes) {
|
||||
case 1:
|
||||
return nodes[0], nil
|
||||
case 0:
|
||||
return nil, &NotFoundError{directlink.Label}
|
||||
default:
|
||||
return nil, &NotSingularError{directlink.Label}
|
||||
}
|
||||
}
|
||||
|
||||
// OnlyX is like Only, but panics if an error occurs.
|
||||
func (dlq *DirectLinkQuery) OnlyX(ctx context.Context) *DirectLink {
|
||||
node, err := dlq.Only(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// OnlyID is like Only, but returns the only DirectLink ID in the query.
|
||||
// Returns a *NotSingularError when more than one DirectLink ID is found.
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (dlq *DirectLinkQuery) OnlyID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = dlq.Limit(2).IDs(setContextOp(ctx, dlq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
case 1:
|
||||
id = ids[0]
|
||||
case 0:
|
||||
err = &NotFoundError{directlink.Label}
|
||||
default:
|
||||
err = &NotSingularError{directlink.Label}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// OnlyIDX is like OnlyID, but panics if an error occurs.
|
||||
func (dlq *DirectLinkQuery) OnlyIDX(ctx context.Context) int {
|
||||
id, err := dlq.OnlyID(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// All executes the query and returns a list of DirectLinks.
|
||||
func (dlq *DirectLinkQuery) All(ctx context.Context) ([]*DirectLink, error) {
|
||||
ctx = setContextOp(ctx, dlq.ctx, "All")
|
||||
if err := dlq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
qr := querierAll[[]*DirectLink, *DirectLinkQuery]()
|
||||
return withInterceptors[[]*DirectLink](ctx, dlq, qr, dlq.inters)
|
||||
}
|
||||
|
||||
// AllX is like All, but panics if an error occurs.
|
||||
func (dlq *DirectLinkQuery) AllX(ctx context.Context) []*DirectLink {
|
||||
nodes, err := dlq.All(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
// IDs executes the query and returns a list of DirectLink IDs.
|
||||
func (dlq *DirectLinkQuery) IDs(ctx context.Context) (ids []int, err error) {
|
||||
if dlq.ctx.Unique == nil && dlq.path != nil {
|
||||
dlq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, dlq.ctx, "IDs")
|
||||
if err = dlq.Select(directlink.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
// IDsX is like IDs, but panics if an error occurs.
|
||||
func (dlq *DirectLinkQuery) IDsX(ctx context.Context) []int {
|
||||
ids, err := dlq.IDs(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (dlq *DirectLinkQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, dlq.ctx, "Count")
|
||||
if err := dlq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return withInterceptors[int](ctx, dlq, querierCount[*DirectLinkQuery](), dlq.inters)
|
||||
}
|
||||
|
||||
// CountX is like Count, but panics if an error occurs.
|
||||
func (dlq *DirectLinkQuery) CountX(ctx context.Context) int {
|
||||
count, err := dlq.Count(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (dlq *DirectLinkQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, dlq.ctx, "Exist")
|
||||
switch _, err := dlq.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 (dlq *DirectLinkQuery) ExistX(ctx context.Context) bool {
|
||||
exist, err := dlq.Exist(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return exist
|
||||
}
|
||||
|
||||
// Clone returns a duplicate of the DirectLinkQuery builder, including all associated steps. It can be
|
||||
// used to prepare common query builders and use them differently after the clone is made.
|
||||
func (dlq *DirectLinkQuery) Clone() *DirectLinkQuery {
|
||||
if dlq == nil {
|
||||
return nil
|
||||
}
|
||||
return &DirectLinkQuery{
|
||||
config: dlq.config,
|
||||
ctx: dlq.ctx.Clone(),
|
||||
order: append([]directlink.OrderOption{}, dlq.order...),
|
||||
inters: append([]Interceptor{}, dlq.inters...),
|
||||
predicates: append([]predicate.DirectLink{}, dlq.predicates...),
|
||||
withFile: dlq.withFile.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: dlq.sql.Clone(),
|
||||
path: dlq.path,
|
||||
}
|
||||
}
|
||||
|
||||
// WithFile tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "file" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (dlq *DirectLinkQuery) WithFile(opts ...func(*FileQuery)) *DirectLinkQuery {
|
||||
query := (&FileClient{config: dlq.config}).Query()
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
dlq.withFile = query
|
||||
return dlq
|
||||
}
|
||||
|
||||
// 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.DirectLink.Query().
|
||||
// GroupBy(directlink.FieldCreatedAt).
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (dlq *DirectLinkQuery) GroupBy(field string, fields ...string) *DirectLinkGroupBy {
|
||||
dlq.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &DirectLinkGroupBy{build: dlq}
|
||||
grbuild.flds = &dlq.ctx.Fields
|
||||
grbuild.label = directlink.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 {
|
||||
// CreatedAt time.Time `json:"created_at,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.DirectLink.Query().
|
||||
// Select(directlink.FieldCreatedAt).
|
||||
// Scan(ctx, &v)
|
||||
func (dlq *DirectLinkQuery) Select(fields ...string) *DirectLinkSelect {
|
||||
dlq.ctx.Fields = append(dlq.ctx.Fields, fields...)
|
||||
sbuild := &DirectLinkSelect{DirectLinkQuery: dlq}
|
||||
sbuild.label = directlink.Label
|
||||
sbuild.flds, sbuild.scan = &dlq.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
// Aggregate returns a DirectLinkSelect configured with the given aggregations.
|
||||
func (dlq *DirectLinkQuery) Aggregate(fns ...AggregateFunc) *DirectLinkSelect {
|
||||
return dlq.Select().Aggregate(fns...)
|
||||
}
|
||||
|
||||
func (dlq *DirectLinkQuery) prepareQuery(ctx context.Context) error {
|
||||
for _, inter := range dlq.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, dlq); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range dlq.ctx.Fields {
|
||||
if !directlink.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
}
|
||||
if dlq.path != nil {
|
||||
prev, err := dlq.path(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dlq.sql = prev
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dlq *DirectLinkQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*DirectLink, error) {
|
||||
var (
|
||||
nodes = []*DirectLink{}
|
||||
_spec = dlq.querySpec()
|
||||
loadedTypes = [1]bool{
|
||||
dlq.withFile != nil,
|
||||
}
|
||||
)
|
||||
_spec.ScanValues = func(columns []string) ([]any, error) {
|
||||
return (*DirectLink).scanValues(nil, columns)
|
||||
}
|
||||
_spec.Assign = func(columns []string, values []any) error {
|
||||
node := &DirectLink{config: dlq.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, dlq.driver, _spec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nodes, nil
|
||||
}
|
||||
if query := dlq.withFile; query != nil {
|
||||
if err := dlq.loadFile(ctx, query, nodes, nil,
|
||||
func(n *DirectLink, e *File) { n.Edges.File = e }); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
func (dlq *DirectLinkQuery) loadFile(ctx context.Context, query *FileQuery, nodes []*DirectLink, init func(*DirectLink), assign func(*DirectLink, *File)) error {
|
||||
ids := make([]int, 0, len(nodes))
|
||||
nodeids := make(map[int][]*DirectLink)
|
||||
for i := range nodes {
|
||||
fk := nodes[i].FileID
|
||||
if _, ok := nodeids[fk]; !ok {
|
||||
ids = append(ids, fk)
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
query.Where(file.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 "file_id" returned %v`, n.ID)
|
||||
}
|
||||
for i := range nodes {
|
||||
assign(nodes[i], n)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dlq *DirectLinkQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := dlq.querySpec()
|
||||
_spec.Node.Columns = dlq.ctx.Fields
|
||||
if len(dlq.ctx.Fields) > 0 {
|
||||
_spec.Unique = dlq.ctx.Unique != nil && *dlq.ctx.Unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, dlq.driver, _spec)
|
||||
}
|
||||
|
||||
func (dlq *DirectLinkQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
_spec := sqlgraph.NewQuerySpec(directlink.Table, directlink.Columns, sqlgraph.NewFieldSpec(directlink.FieldID, field.TypeInt))
|
||||
_spec.From = dlq.sql
|
||||
if unique := dlq.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
} else if dlq.path != nil {
|
||||
_spec.Unique = true
|
||||
}
|
||||
if fields := dlq.ctx.Fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, directlink.FieldID)
|
||||
for i := range fields {
|
||||
if fields[i] != directlink.FieldID {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
|
||||
}
|
||||
}
|
||||
if dlq.withFile != nil {
|
||||
_spec.Node.AddColumnOnce(directlink.FieldFileID)
|
||||
}
|
||||
}
|
||||
if ps := dlq.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := dlq.ctx.Limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := dlq.ctx.Offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := dlq.order; len(ps) > 0 {
|
||||
_spec.Order = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
return _spec
|
||||
}
|
||||
|
||||
func (dlq *DirectLinkQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(dlq.driver.Dialect())
|
||||
t1 := builder.Table(directlink.Table)
|
||||
columns := dlq.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = directlink.Columns
|
||||
}
|
||||
selector := builder.Select(t1.Columns(columns...)...).From(t1)
|
||||
if dlq.sql != nil {
|
||||
selector = dlq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if dlq.ctx.Unique != nil && *dlq.ctx.Unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, p := range dlq.predicates {
|
||||
p(selector)
|
||||
}
|
||||
for _, p := range dlq.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := dlq.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 := dlq.ctx.Limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
}
|
||||
|
||||
// DirectLinkGroupBy is the group-by builder for DirectLink entities.
|
||||
type DirectLinkGroupBy struct {
|
||||
selector
|
||||
build *DirectLinkQuery
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the group-by query.
|
||||
func (dlgb *DirectLinkGroupBy) Aggregate(fns ...AggregateFunc) *DirectLinkGroupBy {
|
||||
dlgb.fns = append(dlgb.fns, fns...)
|
||||
return dlgb
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (dlgb *DirectLinkGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, dlgb.build.ctx, "GroupBy")
|
||||
if err := dlgb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return scanWithInterceptors[*DirectLinkQuery, *DirectLinkGroupBy](ctx, dlgb.build, dlgb, dlgb.build.inters, v)
|
||||
}
|
||||
|
||||
func (dlgb *DirectLinkGroupBy) sqlScan(ctx context.Context, root *DirectLinkQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx).Select()
|
||||
aggregation := make([]string, 0, len(dlgb.fns))
|
||||
for _, fn := range dlgb.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
if len(selector.SelectedColumns()) == 0 {
|
||||
columns := make([]string, 0, len(*dlgb.flds)+len(dlgb.fns))
|
||||
for _, f := range *dlgb.flds {
|
||||
columns = append(columns, selector.C(f))
|
||||
}
|
||||
columns = append(columns, aggregation...)
|
||||
selector.Select(columns...)
|
||||
}
|
||||
selector.GroupBy(selector.Columns(*dlgb.flds...)...)
|
||||
if err := selector.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := dlgb.build.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
// DirectLinkSelect is the builder for selecting fields of DirectLink entities.
|
||||
type DirectLinkSelect struct {
|
||||
*DirectLinkQuery
|
||||
selector
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the selector query.
|
||||
func (dls *DirectLinkSelect) Aggregate(fns ...AggregateFunc) *DirectLinkSelect {
|
||||
dls.fns = append(dls.fns, fns...)
|
||||
return dls
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (dls *DirectLinkSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, dls.ctx, "Select")
|
||||
if err := dls.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return scanWithInterceptors[*DirectLinkQuery, *DirectLinkSelect](ctx, dls.DirectLinkQuery, dls, dls.inters, v)
|
||||
}
|
||||
|
||||
func (dls *DirectLinkSelect) sqlScan(ctx context.Context, root *DirectLinkQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx)
|
||||
aggregation := make([]string, 0, len(dls.fns))
|
||||
for _, fn := range dls.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
switch n := len(*dls.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 := dls.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
549
ent/directlink_update.go
Normal file
549
ent/directlink_update.go
Normal file
@@ -0,0 +1,549 @@
|
||||
// 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/cloudreve/Cloudreve/v4/ent/directlink"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/file"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||
)
|
||||
|
||||
// DirectLinkUpdate is the builder for updating DirectLink entities.
|
||||
type DirectLinkUpdate struct {
|
||||
config
|
||||
hooks []Hook
|
||||
mutation *DirectLinkMutation
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the DirectLinkUpdate builder.
|
||||
func (dlu *DirectLinkUpdate) Where(ps ...predicate.DirectLink) *DirectLinkUpdate {
|
||||
dlu.mutation.Where(ps...)
|
||||
return dlu
|
||||
}
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (dlu *DirectLinkUpdate) SetUpdatedAt(t time.Time) *DirectLinkUpdate {
|
||||
dlu.mutation.SetUpdatedAt(t)
|
||||
return dlu
|
||||
}
|
||||
|
||||
// SetDeletedAt sets the "deleted_at" field.
|
||||
func (dlu *DirectLinkUpdate) SetDeletedAt(t time.Time) *DirectLinkUpdate {
|
||||
dlu.mutation.SetDeletedAt(t)
|
||||
return dlu
|
||||
}
|
||||
|
||||
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
|
||||
func (dlu *DirectLinkUpdate) SetNillableDeletedAt(t *time.Time) *DirectLinkUpdate {
|
||||
if t != nil {
|
||||
dlu.SetDeletedAt(*t)
|
||||
}
|
||||
return dlu
|
||||
}
|
||||
|
||||
// ClearDeletedAt clears the value of the "deleted_at" field.
|
||||
func (dlu *DirectLinkUpdate) ClearDeletedAt() *DirectLinkUpdate {
|
||||
dlu.mutation.ClearDeletedAt()
|
||||
return dlu
|
||||
}
|
||||
|
||||
// SetName sets the "name" field.
|
||||
func (dlu *DirectLinkUpdate) SetName(s string) *DirectLinkUpdate {
|
||||
dlu.mutation.SetName(s)
|
||||
return dlu
|
||||
}
|
||||
|
||||
// SetNillableName sets the "name" field if the given value is not nil.
|
||||
func (dlu *DirectLinkUpdate) SetNillableName(s *string) *DirectLinkUpdate {
|
||||
if s != nil {
|
||||
dlu.SetName(*s)
|
||||
}
|
||||
return dlu
|
||||
}
|
||||
|
||||
// SetDownloads sets the "downloads" field.
|
||||
func (dlu *DirectLinkUpdate) SetDownloads(i int) *DirectLinkUpdate {
|
||||
dlu.mutation.ResetDownloads()
|
||||
dlu.mutation.SetDownloads(i)
|
||||
return dlu
|
||||
}
|
||||
|
||||
// SetNillableDownloads sets the "downloads" field if the given value is not nil.
|
||||
func (dlu *DirectLinkUpdate) SetNillableDownloads(i *int) *DirectLinkUpdate {
|
||||
if i != nil {
|
||||
dlu.SetDownloads(*i)
|
||||
}
|
||||
return dlu
|
||||
}
|
||||
|
||||
// AddDownloads adds i to the "downloads" field.
|
||||
func (dlu *DirectLinkUpdate) AddDownloads(i int) *DirectLinkUpdate {
|
||||
dlu.mutation.AddDownloads(i)
|
||||
return dlu
|
||||
}
|
||||
|
||||
// SetFileID sets the "file_id" field.
|
||||
func (dlu *DirectLinkUpdate) SetFileID(i int) *DirectLinkUpdate {
|
||||
dlu.mutation.SetFileID(i)
|
||||
return dlu
|
||||
}
|
||||
|
||||
// SetNillableFileID sets the "file_id" field if the given value is not nil.
|
||||
func (dlu *DirectLinkUpdate) SetNillableFileID(i *int) *DirectLinkUpdate {
|
||||
if i != nil {
|
||||
dlu.SetFileID(*i)
|
||||
}
|
||||
return dlu
|
||||
}
|
||||
|
||||
// SetSpeed sets the "speed" field.
|
||||
func (dlu *DirectLinkUpdate) SetSpeed(i int) *DirectLinkUpdate {
|
||||
dlu.mutation.ResetSpeed()
|
||||
dlu.mutation.SetSpeed(i)
|
||||
return dlu
|
||||
}
|
||||
|
||||
// SetNillableSpeed sets the "speed" field if the given value is not nil.
|
||||
func (dlu *DirectLinkUpdate) SetNillableSpeed(i *int) *DirectLinkUpdate {
|
||||
if i != nil {
|
||||
dlu.SetSpeed(*i)
|
||||
}
|
||||
return dlu
|
||||
}
|
||||
|
||||
// AddSpeed adds i to the "speed" field.
|
||||
func (dlu *DirectLinkUpdate) AddSpeed(i int) *DirectLinkUpdate {
|
||||
dlu.mutation.AddSpeed(i)
|
||||
return dlu
|
||||
}
|
||||
|
||||
// SetFile sets the "file" edge to the File entity.
|
||||
func (dlu *DirectLinkUpdate) SetFile(f *File) *DirectLinkUpdate {
|
||||
return dlu.SetFileID(f.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the DirectLinkMutation object of the builder.
|
||||
func (dlu *DirectLinkUpdate) Mutation() *DirectLinkMutation {
|
||||
return dlu.mutation
|
||||
}
|
||||
|
||||
// ClearFile clears the "file" edge to the File entity.
|
||||
func (dlu *DirectLinkUpdate) ClearFile() *DirectLinkUpdate {
|
||||
dlu.mutation.ClearFile()
|
||||
return dlu
|
||||
}
|
||||
|
||||
// Save executes the query and returns the number of nodes affected by the update operation.
|
||||
func (dlu *DirectLinkUpdate) Save(ctx context.Context) (int, error) {
|
||||
if err := dlu.defaults(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return withHooks(ctx, dlu.sqlSave, dlu.mutation, dlu.hooks)
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (dlu *DirectLinkUpdate) SaveX(ctx context.Context) int {
|
||||
affected, err := dlu.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return affected
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (dlu *DirectLinkUpdate) Exec(ctx context.Context) error {
|
||||
_, err := dlu.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (dlu *DirectLinkUpdate) ExecX(ctx context.Context) {
|
||||
if err := dlu.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (dlu *DirectLinkUpdate) defaults() error {
|
||||
if _, ok := dlu.mutation.UpdatedAt(); !ok {
|
||||
if directlink.UpdateDefaultUpdatedAt == nil {
|
||||
return fmt.Errorf("ent: uninitialized directlink.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)")
|
||||
}
|
||||
v := directlink.UpdateDefaultUpdatedAt()
|
||||
dlu.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (dlu *DirectLinkUpdate) check() error {
|
||||
if _, ok := dlu.mutation.FileID(); dlu.mutation.FileCleared() && !ok {
|
||||
return errors.New(`ent: clearing a required unique edge "DirectLink.file"`)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dlu *DirectLinkUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
||||
if err := dlu.check(); err != nil {
|
||||
return n, err
|
||||
}
|
||||
_spec := sqlgraph.NewUpdateSpec(directlink.Table, directlink.Columns, sqlgraph.NewFieldSpec(directlink.FieldID, field.TypeInt))
|
||||
if ps := dlu.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if value, ok := dlu.mutation.UpdatedAt(); ok {
|
||||
_spec.SetField(directlink.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if value, ok := dlu.mutation.DeletedAt(); ok {
|
||||
_spec.SetField(directlink.FieldDeletedAt, field.TypeTime, value)
|
||||
}
|
||||
if dlu.mutation.DeletedAtCleared() {
|
||||
_spec.ClearField(directlink.FieldDeletedAt, field.TypeTime)
|
||||
}
|
||||
if value, ok := dlu.mutation.Name(); ok {
|
||||
_spec.SetField(directlink.FieldName, field.TypeString, value)
|
||||
}
|
||||
if value, ok := dlu.mutation.Downloads(); ok {
|
||||
_spec.SetField(directlink.FieldDownloads, field.TypeInt, value)
|
||||
}
|
||||
if value, ok := dlu.mutation.AddedDownloads(); ok {
|
||||
_spec.AddField(directlink.FieldDownloads, field.TypeInt, value)
|
||||
}
|
||||
if value, ok := dlu.mutation.Speed(); ok {
|
||||
_spec.SetField(directlink.FieldSpeed, field.TypeInt, value)
|
||||
}
|
||||
if value, ok := dlu.mutation.AddedSpeed(); ok {
|
||||
_spec.AddField(directlink.FieldSpeed, field.TypeInt, value)
|
||||
}
|
||||
if dlu.mutation.FileCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: directlink.FileTable,
|
||||
Columns: []string{directlink.FileColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(file.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := dlu.mutation.FileIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: directlink.FileTable,
|
||||
Columns: []string{directlink.FileColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(file.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if n, err = sqlgraph.UpdateNodes(ctx, dlu.driver, _spec); err != nil {
|
||||
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||
err = &NotFoundError{directlink.Label}
|
||||
} else if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
dlu.mutation.done = true
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// DirectLinkUpdateOne is the builder for updating a single DirectLink entity.
|
||||
type DirectLinkUpdateOne struct {
|
||||
config
|
||||
fields []string
|
||||
hooks []Hook
|
||||
mutation *DirectLinkMutation
|
||||
}
|
||||
|
||||
// SetUpdatedAt sets the "updated_at" field.
|
||||
func (dluo *DirectLinkUpdateOne) SetUpdatedAt(t time.Time) *DirectLinkUpdateOne {
|
||||
dluo.mutation.SetUpdatedAt(t)
|
||||
return dluo
|
||||
}
|
||||
|
||||
// SetDeletedAt sets the "deleted_at" field.
|
||||
func (dluo *DirectLinkUpdateOne) SetDeletedAt(t time.Time) *DirectLinkUpdateOne {
|
||||
dluo.mutation.SetDeletedAt(t)
|
||||
return dluo
|
||||
}
|
||||
|
||||
// SetNillableDeletedAt sets the "deleted_at" field if the given value is not nil.
|
||||
func (dluo *DirectLinkUpdateOne) SetNillableDeletedAt(t *time.Time) *DirectLinkUpdateOne {
|
||||
if t != nil {
|
||||
dluo.SetDeletedAt(*t)
|
||||
}
|
||||
return dluo
|
||||
}
|
||||
|
||||
// ClearDeletedAt clears the value of the "deleted_at" field.
|
||||
func (dluo *DirectLinkUpdateOne) ClearDeletedAt() *DirectLinkUpdateOne {
|
||||
dluo.mutation.ClearDeletedAt()
|
||||
return dluo
|
||||
}
|
||||
|
||||
// SetName sets the "name" field.
|
||||
func (dluo *DirectLinkUpdateOne) SetName(s string) *DirectLinkUpdateOne {
|
||||
dluo.mutation.SetName(s)
|
||||
return dluo
|
||||
}
|
||||
|
||||
// SetNillableName sets the "name" field if the given value is not nil.
|
||||
func (dluo *DirectLinkUpdateOne) SetNillableName(s *string) *DirectLinkUpdateOne {
|
||||
if s != nil {
|
||||
dluo.SetName(*s)
|
||||
}
|
||||
return dluo
|
||||
}
|
||||
|
||||
// SetDownloads sets the "downloads" field.
|
||||
func (dluo *DirectLinkUpdateOne) SetDownloads(i int) *DirectLinkUpdateOne {
|
||||
dluo.mutation.ResetDownloads()
|
||||
dluo.mutation.SetDownloads(i)
|
||||
return dluo
|
||||
}
|
||||
|
||||
// SetNillableDownloads sets the "downloads" field if the given value is not nil.
|
||||
func (dluo *DirectLinkUpdateOne) SetNillableDownloads(i *int) *DirectLinkUpdateOne {
|
||||
if i != nil {
|
||||
dluo.SetDownloads(*i)
|
||||
}
|
||||
return dluo
|
||||
}
|
||||
|
||||
// AddDownloads adds i to the "downloads" field.
|
||||
func (dluo *DirectLinkUpdateOne) AddDownloads(i int) *DirectLinkUpdateOne {
|
||||
dluo.mutation.AddDownloads(i)
|
||||
return dluo
|
||||
}
|
||||
|
||||
// SetFileID sets the "file_id" field.
|
||||
func (dluo *DirectLinkUpdateOne) SetFileID(i int) *DirectLinkUpdateOne {
|
||||
dluo.mutation.SetFileID(i)
|
||||
return dluo
|
||||
}
|
||||
|
||||
// SetNillableFileID sets the "file_id" field if the given value is not nil.
|
||||
func (dluo *DirectLinkUpdateOne) SetNillableFileID(i *int) *DirectLinkUpdateOne {
|
||||
if i != nil {
|
||||
dluo.SetFileID(*i)
|
||||
}
|
||||
return dluo
|
||||
}
|
||||
|
||||
// SetSpeed sets the "speed" field.
|
||||
func (dluo *DirectLinkUpdateOne) SetSpeed(i int) *DirectLinkUpdateOne {
|
||||
dluo.mutation.ResetSpeed()
|
||||
dluo.mutation.SetSpeed(i)
|
||||
return dluo
|
||||
}
|
||||
|
||||
// SetNillableSpeed sets the "speed" field if the given value is not nil.
|
||||
func (dluo *DirectLinkUpdateOne) SetNillableSpeed(i *int) *DirectLinkUpdateOne {
|
||||
if i != nil {
|
||||
dluo.SetSpeed(*i)
|
||||
}
|
||||
return dluo
|
||||
}
|
||||
|
||||
// AddSpeed adds i to the "speed" field.
|
||||
func (dluo *DirectLinkUpdateOne) AddSpeed(i int) *DirectLinkUpdateOne {
|
||||
dluo.mutation.AddSpeed(i)
|
||||
return dluo
|
||||
}
|
||||
|
||||
// SetFile sets the "file" edge to the File entity.
|
||||
func (dluo *DirectLinkUpdateOne) SetFile(f *File) *DirectLinkUpdateOne {
|
||||
return dluo.SetFileID(f.ID)
|
||||
}
|
||||
|
||||
// Mutation returns the DirectLinkMutation object of the builder.
|
||||
func (dluo *DirectLinkUpdateOne) Mutation() *DirectLinkMutation {
|
||||
return dluo.mutation
|
||||
}
|
||||
|
||||
// ClearFile clears the "file" edge to the File entity.
|
||||
func (dluo *DirectLinkUpdateOne) ClearFile() *DirectLinkUpdateOne {
|
||||
dluo.mutation.ClearFile()
|
||||
return dluo
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the DirectLinkUpdate builder.
|
||||
func (dluo *DirectLinkUpdateOne) Where(ps ...predicate.DirectLink) *DirectLinkUpdateOne {
|
||||
dluo.mutation.Where(ps...)
|
||||
return dluo
|
||||
}
|
||||
|
||||
// Select allows selecting one or more fields (columns) of the returned entity.
|
||||
// The default is selecting all fields defined in the entity schema.
|
||||
func (dluo *DirectLinkUpdateOne) Select(field string, fields ...string) *DirectLinkUpdateOne {
|
||||
dluo.fields = append([]string{field}, fields...)
|
||||
return dluo
|
||||
}
|
||||
|
||||
// Save executes the query and returns the updated DirectLink entity.
|
||||
func (dluo *DirectLinkUpdateOne) Save(ctx context.Context) (*DirectLink, error) {
|
||||
if err := dluo.defaults(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return withHooks(ctx, dluo.sqlSave, dluo.mutation, dluo.hooks)
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (dluo *DirectLinkUpdateOne) SaveX(ctx context.Context) *DirectLink {
|
||||
node, err := dluo.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// Exec executes the query on the entity.
|
||||
func (dluo *DirectLinkUpdateOne) Exec(ctx context.Context) error {
|
||||
_, err := dluo.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (dluo *DirectLinkUpdateOne) ExecX(ctx context.Context) {
|
||||
if err := dluo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (dluo *DirectLinkUpdateOne) defaults() error {
|
||||
if _, ok := dluo.mutation.UpdatedAt(); !ok {
|
||||
if directlink.UpdateDefaultUpdatedAt == nil {
|
||||
return fmt.Errorf("ent: uninitialized directlink.UpdateDefaultUpdatedAt (forgotten import ent/runtime?)")
|
||||
}
|
||||
v := directlink.UpdateDefaultUpdatedAt()
|
||||
dluo.mutation.SetUpdatedAt(v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (dluo *DirectLinkUpdateOne) check() error {
|
||||
if _, ok := dluo.mutation.FileID(); dluo.mutation.FileCleared() && !ok {
|
||||
return errors.New(`ent: clearing a required unique edge "DirectLink.file"`)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dluo *DirectLinkUpdateOne) sqlSave(ctx context.Context) (_node *DirectLink, err error) {
|
||||
if err := dluo.check(); err != nil {
|
||||
return _node, err
|
||||
}
|
||||
_spec := sqlgraph.NewUpdateSpec(directlink.Table, directlink.Columns, sqlgraph.NewFieldSpec(directlink.FieldID, field.TypeInt))
|
||||
id, ok := dluo.mutation.ID()
|
||||
if !ok {
|
||||
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "DirectLink.id" for update`)}
|
||||
}
|
||||
_spec.Node.ID.Value = id
|
||||
if fields := dluo.fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, directlink.FieldID)
|
||||
for _, f := range fields {
|
||||
if !directlink.ValidColumn(f) {
|
||||
return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
if f != directlink.FieldID {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
if ps := dluo.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if value, ok := dluo.mutation.UpdatedAt(); ok {
|
||||
_spec.SetField(directlink.FieldUpdatedAt, field.TypeTime, value)
|
||||
}
|
||||
if value, ok := dluo.mutation.DeletedAt(); ok {
|
||||
_spec.SetField(directlink.FieldDeletedAt, field.TypeTime, value)
|
||||
}
|
||||
if dluo.mutation.DeletedAtCleared() {
|
||||
_spec.ClearField(directlink.FieldDeletedAt, field.TypeTime)
|
||||
}
|
||||
if value, ok := dluo.mutation.Name(); ok {
|
||||
_spec.SetField(directlink.FieldName, field.TypeString, value)
|
||||
}
|
||||
if value, ok := dluo.mutation.Downloads(); ok {
|
||||
_spec.SetField(directlink.FieldDownloads, field.TypeInt, value)
|
||||
}
|
||||
if value, ok := dluo.mutation.AddedDownloads(); ok {
|
||||
_spec.AddField(directlink.FieldDownloads, field.TypeInt, value)
|
||||
}
|
||||
if value, ok := dluo.mutation.Speed(); ok {
|
||||
_spec.SetField(directlink.FieldSpeed, field.TypeInt, value)
|
||||
}
|
||||
if value, ok := dluo.mutation.AddedSpeed(); ok {
|
||||
_spec.AddField(directlink.FieldSpeed, field.TypeInt, value)
|
||||
}
|
||||
if dluo.mutation.FileCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: directlink.FileTable,
|
||||
Columns: []string{directlink.FileColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(file.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := dluo.mutation.FileIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: directlink.FileTable,
|
||||
Columns: []string{directlink.FileColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(file.FieldID, field.TypeInt),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
_node = &DirectLink{config: dluo.config}
|
||||
_spec.Assign = _node.assignValues
|
||||
_spec.ScanValues = _node.scanValues
|
||||
if err = sqlgraph.UpdateNode(ctx, dluo.driver, _spec); err != nil {
|
||||
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||
err = &NotFoundError{directlink.Label}
|
||||
} else if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
dluo.mutation.done = true
|
||||
return _node, nil
|
||||
}
|
||||
638
ent/ent.go
Normal file
638
ent/ent.go
Normal file
@@ -0,0 +1,638 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/davaccount"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/directlink"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/entity"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/file"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/fsevent"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/group"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/metadata"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/node"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/oauthclient"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/oauthgrant"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/passkey"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/setting"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/share"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/storagepolicy"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/task"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/user"
|
||||
)
|
||||
|
||||
// ent aliases to avoid import conflicts in user's code.
|
||||
type (
|
||||
Op = ent.Op
|
||||
Hook = ent.Hook
|
||||
Value = ent.Value
|
||||
Query = ent.Query
|
||||
QueryContext = ent.QueryContext
|
||||
Querier = ent.Querier
|
||||
QuerierFunc = ent.QuerierFunc
|
||||
Interceptor = ent.Interceptor
|
||||
InterceptFunc = ent.InterceptFunc
|
||||
Traverser = ent.Traverser
|
||||
TraverseFunc = ent.TraverseFunc
|
||||
Policy = ent.Policy
|
||||
Mutator = ent.Mutator
|
||||
Mutation = ent.Mutation
|
||||
MutateFunc = ent.MutateFunc
|
||||
)
|
||||
|
||||
type clientCtxKey struct{}
|
||||
|
||||
// FromContext returns a Client stored inside a context, or nil if there isn't one.
|
||||
func FromContext(ctx context.Context) *Client {
|
||||
c, _ := ctx.Value(clientCtxKey{}).(*Client)
|
||||
return c
|
||||
}
|
||||
|
||||
// NewContext returns a new context with the given Client attached.
|
||||
func NewContext(parent context.Context, c *Client) context.Context {
|
||||
return context.WithValue(parent, clientCtxKey{}, c)
|
||||
}
|
||||
|
||||
type txCtxKey struct{}
|
||||
|
||||
// TxFromContext returns a Tx stored inside a context, or nil if there isn't one.
|
||||
func TxFromContext(ctx context.Context) *Tx {
|
||||
tx, _ := ctx.Value(txCtxKey{}).(*Tx)
|
||||
return tx
|
||||
}
|
||||
|
||||
// NewTxContext returns a new context with the given Tx attached.
|
||||
func NewTxContext(parent context.Context, tx *Tx) context.Context {
|
||||
return context.WithValue(parent, txCtxKey{}, tx)
|
||||
}
|
||||
|
||||
// OrderFunc applies an ordering on the sql selector.
|
||||
// Deprecated: Use Asc/Desc functions or the package builders instead.
|
||||
type OrderFunc func(*sql.Selector)
|
||||
|
||||
var (
|
||||
initCheck sync.Once
|
||||
columnCheck sql.ColumnCheck
|
||||
)
|
||||
|
||||
// columnChecker checks if the column exists in the given table.
|
||||
func checkColumn(table, column string) error {
|
||||
initCheck.Do(func() {
|
||||
columnCheck = sql.NewColumnCheck(map[string]func(string) bool{
|
||||
davaccount.Table: davaccount.ValidColumn,
|
||||
directlink.Table: directlink.ValidColumn,
|
||||
entity.Table: entity.ValidColumn,
|
||||
file.Table: file.ValidColumn,
|
||||
fsevent.Table: fsevent.ValidColumn,
|
||||
group.Table: group.ValidColumn,
|
||||
metadata.Table: metadata.ValidColumn,
|
||||
node.Table: node.ValidColumn,
|
||||
oauthclient.Table: oauthclient.ValidColumn,
|
||||
oauthgrant.Table: oauthgrant.ValidColumn,
|
||||
passkey.Table: passkey.ValidColumn,
|
||||
setting.Table: setting.ValidColumn,
|
||||
share.Table: share.ValidColumn,
|
||||
storagepolicy.Table: storagepolicy.ValidColumn,
|
||||
task.Table: task.ValidColumn,
|
||||
user.Table: user.ValidColumn,
|
||||
})
|
||||
})
|
||||
return columnCheck(table, column)
|
||||
}
|
||||
|
||||
// Asc applies the given fields in ASC order.
|
||||
func Asc(fields ...string) func(*sql.Selector) {
|
||||
return func(s *sql.Selector) {
|
||||
for _, f := range fields {
|
||||
if err := checkColumn(s.TableName(), f); err != nil {
|
||||
s.AddError(&ValidationError{Name: f, err: fmt.Errorf("ent: %w", err)})
|
||||
}
|
||||
s.OrderBy(sql.Asc(s.C(f)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Desc applies the given fields in DESC order.
|
||||
func Desc(fields ...string) func(*sql.Selector) {
|
||||
return func(s *sql.Selector) {
|
||||
for _, f := range fields {
|
||||
if err := checkColumn(s.TableName(), f); err != nil {
|
||||
s.AddError(&ValidationError{Name: f, err: fmt.Errorf("ent: %w", err)})
|
||||
}
|
||||
s.OrderBy(sql.Desc(s.C(f)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// AggregateFunc applies an aggregation step on the group-by traversal/selector.
|
||||
type AggregateFunc func(*sql.Selector) string
|
||||
|
||||
// As is a pseudo aggregation function for renaming another other functions with custom names. For example:
|
||||
//
|
||||
// GroupBy(field1, field2).
|
||||
// Aggregate(ent.As(ent.Sum(field1), "sum_field1"), (ent.As(ent.Sum(field2), "sum_field2")).
|
||||
// Scan(ctx, &v)
|
||||
func As(fn AggregateFunc, end string) AggregateFunc {
|
||||
return func(s *sql.Selector) string {
|
||||
return sql.As(fn(s), end)
|
||||
}
|
||||
}
|
||||
|
||||
// Count applies the "count" aggregation function on each group.
|
||||
func Count() AggregateFunc {
|
||||
return func(s *sql.Selector) string {
|
||||
return sql.Count("*")
|
||||
}
|
||||
}
|
||||
|
||||
// Max applies the "max" aggregation function on the given field of each group.
|
||||
func Max(field string) AggregateFunc {
|
||||
return func(s *sql.Selector) string {
|
||||
if err := checkColumn(s.TableName(), field); err != nil {
|
||||
s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)})
|
||||
return ""
|
||||
}
|
||||
return sql.Max(s.C(field))
|
||||
}
|
||||
}
|
||||
|
||||
// Mean applies the "mean" aggregation function on the given field of each group.
|
||||
func Mean(field string) AggregateFunc {
|
||||
return func(s *sql.Selector) string {
|
||||
if err := checkColumn(s.TableName(), field); err != nil {
|
||||
s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)})
|
||||
return ""
|
||||
}
|
||||
return sql.Avg(s.C(field))
|
||||
}
|
||||
}
|
||||
|
||||
// Min applies the "min" aggregation function on the given field of each group.
|
||||
func Min(field string) AggregateFunc {
|
||||
return func(s *sql.Selector) string {
|
||||
if err := checkColumn(s.TableName(), field); err != nil {
|
||||
s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)})
|
||||
return ""
|
||||
}
|
||||
return sql.Min(s.C(field))
|
||||
}
|
||||
}
|
||||
|
||||
// Sum applies the "sum" aggregation function on the given field of each group.
|
||||
func Sum(field string) AggregateFunc {
|
||||
return func(s *sql.Selector) string {
|
||||
if err := checkColumn(s.TableName(), field); err != nil {
|
||||
s.AddError(&ValidationError{Name: field, err: fmt.Errorf("ent: %w", err)})
|
||||
return ""
|
||||
}
|
||||
return sql.Sum(s.C(field))
|
||||
}
|
||||
}
|
||||
|
||||
// ValidationError returns when validating a field or edge fails.
|
||||
type ValidationError struct {
|
||||
Name string // Field or edge name.
|
||||
err error
|
||||
}
|
||||
|
||||
// Error implements the error interface.
|
||||
func (e *ValidationError) Error() string {
|
||||
return e.err.Error()
|
||||
}
|
||||
|
||||
// Unwrap implements the errors.Wrapper interface.
|
||||
func (e *ValidationError) Unwrap() error {
|
||||
return e.err
|
||||
}
|
||||
|
||||
// IsValidationError returns a boolean indicating whether the error is a validation error.
|
||||
func IsValidationError(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
var e *ValidationError
|
||||
return errors.As(err, &e)
|
||||
}
|
||||
|
||||
// NotFoundError returns when trying to fetch a specific entity and it was not found in the database.
|
||||
type NotFoundError struct {
|
||||
label string
|
||||
}
|
||||
|
||||
// Error implements the error interface.
|
||||
func (e *NotFoundError) Error() string {
|
||||
return "ent: " + e.label + " not found"
|
||||
}
|
||||
|
||||
// IsNotFound returns a boolean indicating whether the error is a not found error.
|
||||
func IsNotFound(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
var e *NotFoundError
|
||||
return errors.As(err, &e)
|
||||
}
|
||||
|
||||
// MaskNotFound masks not found error.
|
||||
func MaskNotFound(err error) error {
|
||||
if IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// NotSingularError returns when trying to fetch a singular entity and more then one was found in the database.
|
||||
type NotSingularError struct {
|
||||
label string
|
||||
}
|
||||
|
||||
// Error implements the error interface.
|
||||
func (e *NotSingularError) Error() string {
|
||||
return "ent: " + e.label + " not singular"
|
||||
}
|
||||
|
||||
// IsNotSingular returns a boolean indicating whether the error is a not singular error.
|
||||
func IsNotSingular(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
var e *NotSingularError
|
||||
return errors.As(err, &e)
|
||||
}
|
||||
|
||||
// NotLoadedError returns when trying to get a node that was not loaded by the query.
|
||||
type NotLoadedError struct {
|
||||
edge string
|
||||
}
|
||||
|
||||
// Error implements the error interface.
|
||||
func (e *NotLoadedError) Error() string {
|
||||
return "ent: " + e.edge + " edge was not loaded"
|
||||
}
|
||||
|
||||
// IsNotLoaded returns a boolean indicating whether the error is a not loaded error.
|
||||
func IsNotLoaded(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
var e *NotLoadedError
|
||||
return errors.As(err, &e)
|
||||
}
|
||||
|
||||
// ConstraintError returns when trying to create/update one or more entities and
|
||||
// one or more of their constraints failed. For example, violation of edge or
|
||||
// field uniqueness.
|
||||
type ConstraintError struct {
|
||||
msg string
|
||||
wrap error
|
||||
}
|
||||
|
||||
// Error implements the error interface.
|
||||
func (e ConstraintError) Error() string {
|
||||
return "ent: constraint failed: " + e.msg
|
||||
}
|
||||
|
||||
// Unwrap implements the errors.Wrapper interface.
|
||||
func (e *ConstraintError) Unwrap() error {
|
||||
return e.wrap
|
||||
}
|
||||
|
||||
// IsConstraintError returns a boolean indicating whether the error is a constraint failure.
|
||||
func IsConstraintError(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
var e *ConstraintError
|
||||
return errors.As(err, &e)
|
||||
}
|
||||
|
||||
// selector embedded by the different Select/GroupBy builders.
|
||||
type selector struct {
|
||||
label string
|
||||
flds *[]string
|
||||
fns []AggregateFunc
|
||||
scan func(context.Context, any) error
|
||||
}
|
||||
|
||||
// ScanX is like Scan, but panics if an error occurs.
|
||||
func (s *selector) ScanX(ctx context.Context, v any) {
|
||||
if err := s.scan(ctx, v); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Strings returns list of strings from a selector. It is only allowed when selecting one field.
|
||||
func (s *selector) Strings(ctx context.Context) ([]string, error) {
|
||||
if len(*s.flds) > 1 {
|
||||
return nil, errors.New("ent: Strings is not achievable when selecting more than 1 field")
|
||||
}
|
||||
var v []string
|
||||
if err := s.scan(ctx, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// StringsX is like Strings, but panics if an error occurs.
|
||||
func (s *selector) StringsX(ctx context.Context) []string {
|
||||
v, err := s.Strings(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// String returns a single string from a selector. It is only allowed when selecting one field.
|
||||
func (s *selector) String(ctx context.Context) (_ string, err error) {
|
||||
var v []string
|
||||
if v, err = s.Strings(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(v) {
|
||||
case 1:
|
||||
return v[0], nil
|
||||
case 0:
|
||||
err = &NotFoundError{s.label}
|
||||
default:
|
||||
err = fmt.Errorf("ent: Strings returned %d results when one was expected", len(v))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// StringX is like String, but panics if an error occurs.
|
||||
func (s *selector) StringX(ctx context.Context) string {
|
||||
v, err := s.String(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Ints returns list of ints from a selector. It is only allowed when selecting one field.
|
||||
func (s *selector) Ints(ctx context.Context) ([]int, error) {
|
||||
if len(*s.flds) > 1 {
|
||||
return nil, errors.New("ent: Ints is not achievable when selecting more than 1 field")
|
||||
}
|
||||
var v []int
|
||||
if err := s.scan(ctx, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// IntsX is like Ints, but panics if an error occurs.
|
||||
func (s *selector) IntsX(ctx context.Context) []int {
|
||||
v, err := s.Ints(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Int returns a single int from a selector. It is only allowed when selecting one field.
|
||||
func (s *selector) Int(ctx context.Context) (_ int, err error) {
|
||||
var v []int
|
||||
if v, err = s.Ints(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(v) {
|
||||
case 1:
|
||||
return v[0], nil
|
||||
case 0:
|
||||
err = &NotFoundError{s.label}
|
||||
default:
|
||||
err = fmt.Errorf("ent: Ints returned %d results when one was expected", len(v))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// IntX is like Int, but panics if an error occurs.
|
||||
func (s *selector) IntX(ctx context.Context) int {
|
||||
v, err := s.Int(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Float64s returns list of float64s from a selector. It is only allowed when selecting one field.
|
||||
func (s *selector) Float64s(ctx context.Context) ([]float64, error) {
|
||||
if len(*s.flds) > 1 {
|
||||
return nil, errors.New("ent: Float64s is not achievable when selecting more than 1 field")
|
||||
}
|
||||
var v []float64
|
||||
if err := s.scan(ctx, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// Float64sX is like Float64s, but panics if an error occurs.
|
||||
func (s *selector) Float64sX(ctx context.Context) []float64 {
|
||||
v, err := s.Float64s(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Float64 returns a single float64 from a selector. It is only allowed when selecting one field.
|
||||
func (s *selector) Float64(ctx context.Context) (_ float64, err error) {
|
||||
var v []float64
|
||||
if v, err = s.Float64s(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(v) {
|
||||
case 1:
|
||||
return v[0], nil
|
||||
case 0:
|
||||
err = &NotFoundError{s.label}
|
||||
default:
|
||||
err = fmt.Errorf("ent: Float64s returned %d results when one was expected", len(v))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Float64X is like Float64, but panics if an error occurs.
|
||||
func (s *selector) Float64X(ctx context.Context) float64 {
|
||||
v, err := s.Float64(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Bools returns list of bools from a selector. It is only allowed when selecting one field.
|
||||
func (s *selector) Bools(ctx context.Context) ([]bool, error) {
|
||||
if len(*s.flds) > 1 {
|
||||
return nil, errors.New("ent: Bools is not achievable when selecting more than 1 field")
|
||||
}
|
||||
var v []bool
|
||||
if err := s.scan(ctx, &v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// BoolsX is like Bools, but panics if an error occurs.
|
||||
func (s *selector) BoolsX(ctx context.Context) []bool {
|
||||
v, err := s.Bools(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Bool returns a single bool from a selector. It is only allowed when selecting one field.
|
||||
func (s *selector) Bool(ctx context.Context) (_ bool, err error) {
|
||||
var v []bool
|
||||
if v, err = s.Bools(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(v) {
|
||||
case 1:
|
||||
return v[0], nil
|
||||
case 0:
|
||||
err = &NotFoundError{s.label}
|
||||
default:
|
||||
err = fmt.Errorf("ent: Bools returned %d results when one was expected", len(v))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// BoolX is like Bool, but panics if an error occurs.
|
||||
func (s *selector) BoolX(ctx context.Context) bool {
|
||||
v, err := s.Bool(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// withHooks invokes the builder operation with the given hooks, if any.
|
||||
func withHooks[V Value, M any, PM interface {
|
||||
*M
|
||||
Mutation
|
||||
}](ctx context.Context, exec func(context.Context) (V, error), mutation PM, hooks []Hook) (value V, err error) {
|
||||
if len(hooks) == 0 {
|
||||
return exec(ctx)
|
||||
}
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutationT, ok := any(m).(PM)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
// Set the mutation to the builder.
|
||||
*mutation = *mutationT
|
||||
return exec(ctx)
|
||||
})
|
||||
for i := len(hooks) - 1; i >= 0; i-- {
|
||||
if hooks[i] == nil {
|
||||
return value, fmt.Errorf("ent: uninitialized hook (forgotten import ent/runtime?)")
|
||||
}
|
||||
mut = hooks[i](mut)
|
||||
}
|
||||
v, err := mut.Mutate(ctx, mutation)
|
||||
if err != nil {
|
||||
return value, err
|
||||
}
|
||||
nv, ok := v.(V)
|
||||
if !ok {
|
||||
return value, fmt.Errorf("unexpected node type %T returned from %T", v, mutation)
|
||||
}
|
||||
return nv, nil
|
||||
}
|
||||
|
||||
// setContextOp returns a new context with the given QueryContext attached (including its op) in case it does not exist.
|
||||
func setContextOp(ctx context.Context, qc *QueryContext, op string) context.Context {
|
||||
if ent.QueryFromContext(ctx) == nil {
|
||||
qc.Op = op
|
||||
ctx = ent.NewQueryContext(ctx, qc)
|
||||
}
|
||||
return ctx
|
||||
}
|
||||
|
||||
func querierAll[V Value, Q interface {
|
||||
sqlAll(context.Context, ...queryHook) (V, error)
|
||||
}]() Querier {
|
||||
return QuerierFunc(func(ctx context.Context, q Query) (Value, error) {
|
||||
query, ok := q.(Q)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected query type %T", q)
|
||||
}
|
||||
return query.sqlAll(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
func querierCount[Q interface {
|
||||
sqlCount(context.Context) (int, error)
|
||||
}]() Querier {
|
||||
return QuerierFunc(func(ctx context.Context, q Query) (Value, error) {
|
||||
query, ok := q.(Q)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected query type %T", q)
|
||||
}
|
||||
return query.sqlCount(ctx)
|
||||
})
|
||||
}
|
||||
|
||||
func withInterceptors[V Value](ctx context.Context, q Query, qr Querier, inters []Interceptor) (v V, err error) {
|
||||
for i := len(inters) - 1; i >= 0; i-- {
|
||||
qr = inters[i].Intercept(qr)
|
||||
}
|
||||
rv, err := qr.Query(ctx, q)
|
||||
if err != nil {
|
||||
return v, err
|
||||
}
|
||||
vt, ok := rv.(V)
|
||||
if !ok {
|
||||
return v, fmt.Errorf("unexpected type %T returned from %T. expected type: %T", vt, q, v)
|
||||
}
|
||||
return vt, nil
|
||||
}
|
||||
|
||||
func scanWithInterceptors[Q1 ent.Query, Q2 interface {
|
||||
sqlScan(context.Context, Q1, any) error
|
||||
}](ctx context.Context, rootQuery Q1, selectOrGroup Q2, inters []Interceptor, v any) error {
|
||||
rv := reflect.ValueOf(v)
|
||||
var qr Querier = QuerierFunc(func(ctx context.Context, q Query) (Value, error) {
|
||||
query, ok := q.(Q1)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected query type %T", q)
|
||||
}
|
||||
if err := selectOrGroup.sqlScan(ctx, query, v); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if k := rv.Kind(); k == reflect.Pointer && rv.Elem().CanInterface() {
|
||||
return rv.Elem().Interface(), nil
|
||||
}
|
||||
return v, nil
|
||||
})
|
||||
for i := len(inters) - 1; i >= 0; i-- {
|
||||
qr = inters[i].Intercept(qr)
|
||||
}
|
||||
vv, err := qr.Query(ctx, rootQuery)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
switch rv2 := reflect.ValueOf(vv); {
|
||||
case rv.IsNil(), rv2.IsNil(), rv.Kind() != reflect.Pointer:
|
||||
case rv.Type() == rv2.Type():
|
||||
rv.Elem().Set(rv2.Elem())
|
||||
case rv.Elem().Type() == rv2.Type():
|
||||
rv.Elem().Set(rv2)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// queryHook describes an internal hook for the different sqlAll methods.
|
||||
type queryHook func(context.Context, *sqlgraph.QuerySpec)
|
||||
29
ent/entc.go
Normal file
29
ent/entc.go
Normal file
@@ -0,0 +1,29 @@
|
||||
//go:build ignore
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"entgo.io/ent/entc"
|
||||
"entgo.io/ent/entc/gen"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := entc.Generate("./schema", &gen.Config{
|
||||
Features: []gen.Feature{
|
||||
gen.FeatureIntercept,
|
||||
gen.FeatureSnapshot,
|
||||
gen.FeatureUpsert,
|
||||
gen.FeatureUpsert,
|
||||
gen.FeatureExecQuery,
|
||||
},
|
||||
Templates: []*gen.Template{
|
||||
gen.MustParse(gen.NewTemplate("edge_helper").ParseFiles("templates/edgehelper.tmpl")),
|
||||
gen.MustParse(gen.NewTemplate("mutation_helper").ParseFiles("templates/mutationhelper.tmpl")),
|
||||
gen.MustParse(gen.NewTemplate("create_helper").ParseFiles("templates/createhelper.tmpl")),
|
||||
},
|
||||
}); err != nil {
|
||||
log.Fatal("running ent codegen:", err)
|
||||
}
|
||||
}
|
||||
317
ent/entity.go
Normal file
317
ent/entity.go
Normal file
@@ -0,0 +1,317 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/entity"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/storagepolicy"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/user"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
"github.com/gofrs/uuid"
|
||||
)
|
||||
|
||||
// Entity is the model entity for the Entity schema.
|
||||
type Entity struct {
|
||||
config `json:"-"`
|
||||
// ID of the ent.
|
||||
ID int `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"`
|
||||
// DeletedAt holds the value of the "deleted_at" field.
|
||||
DeletedAt *time.Time `json:"deleted_at,omitempty"`
|
||||
// Type holds the value of the "type" field.
|
||||
Type int `json:"type,omitempty"`
|
||||
// Source holds the value of the "source" field.
|
||||
Source string `json:"source,omitempty"`
|
||||
// Size holds the value of the "size" field.
|
||||
Size int64 `json:"size,omitempty"`
|
||||
// ReferenceCount holds the value of the "reference_count" field.
|
||||
ReferenceCount int `json:"reference_count,omitempty"`
|
||||
// StoragePolicyEntities holds the value of the "storage_policy_entities" field.
|
||||
StoragePolicyEntities int `json:"storage_policy_entities,omitempty"`
|
||||
// CreatedBy holds the value of the "created_by" field.
|
||||
CreatedBy int `json:"created_by,omitempty"`
|
||||
// UploadSessionID holds the value of the "upload_session_id" field.
|
||||
UploadSessionID *uuid.UUID `json:"upload_session_id,omitempty"`
|
||||
// Props holds the value of the "props" field.
|
||||
Props *types.EntityProps `json:"props,omitempty"`
|
||||
// Edges holds the relations/edges for other nodes in the graph.
|
||||
// The values are being populated by the EntityQuery when eager-loading is set.
|
||||
Edges EntityEdges `json:"edges"`
|
||||
selectValues sql.SelectValues
|
||||
}
|
||||
|
||||
// EntityEdges holds the relations/edges for other nodes in the graph.
|
||||
type EntityEdges struct {
|
||||
// File holds the value of the file edge.
|
||||
File []*File `json:"file,omitempty"`
|
||||
// User holds the value of the user edge.
|
||||
User *User `json:"user,omitempty"`
|
||||
// StoragePolicy holds the value of the storage_policy edge.
|
||||
StoragePolicy *StoragePolicy `json:"storage_policy,omitempty"`
|
||||
// loadedTypes holds the information for reporting if a
|
||||
// type was loaded (or requested) in eager-loading or not.
|
||||
loadedTypes [3]bool
|
||||
}
|
||||
|
||||
// FileOrErr returns the File value or an error if the edge
|
||||
// was not loaded in eager-loading.
|
||||
func (e EntityEdges) FileOrErr() ([]*File, error) {
|
||||
if e.loadedTypes[0] {
|
||||
return e.File, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "file"}
|
||||
}
|
||||
|
||||
// UserOrErr returns the User value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e EntityEdges) UserOrErr() (*User, error) {
|
||||
if e.loadedTypes[1] {
|
||||
if e.User == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: user.Label}
|
||||
}
|
||||
return e.User, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "user"}
|
||||
}
|
||||
|
||||
// StoragePolicyOrErr returns the StoragePolicy value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e EntityEdges) StoragePolicyOrErr() (*StoragePolicy, error) {
|
||||
if e.loadedTypes[2] {
|
||||
if e.StoragePolicy == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: storagepolicy.Label}
|
||||
}
|
||||
return e.StoragePolicy, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "storage_policy"}
|
||||
}
|
||||
|
||||
// scanValues returns the types for scanning values from sql.Rows.
|
||||
func (*Entity) scanValues(columns []string) ([]any, error) {
|
||||
values := make([]any, len(columns))
|
||||
for i := range columns {
|
||||
switch columns[i] {
|
||||
case entity.FieldUploadSessionID:
|
||||
values[i] = &sql.NullScanner{S: new(uuid.UUID)}
|
||||
case entity.FieldProps:
|
||||
values[i] = new([]byte)
|
||||
case entity.FieldID, entity.FieldType, entity.FieldSize, entity.FieldReferenceCount, entity.FieldStoragePolicyEntities, entity.FieldCreatedBy:
|
||||
values[i] = new(sql.NullInt64)
|
||||
case entity.FieldSource:
|
||||
values[i] = new(sql.NullString)
|
||||
case entity.FieldCreatedAt, entity.FieldUpdatedAt, entity.FieldDeletedAt:
|
||||
values[i] = new(sql.NullTime)
|
||||
default:
|
||||
values[i] = new(sql.UnknownType)
|
||||
}
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// assignValues assigns the values that were returned from sql.Rows (after scanning)
|
||||
// to the Entity fields.
|
||||
func (e *Entity) 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 entity.FieldID:
|
||||
value, ok := values[i].(*sql.NullInt64)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field id", value)
|
||||
}
|
||||
e.ID = int(value.Int64)
|
||||
case entity.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 {
|
||||
e.CreatedAt = value.Time
|
||||
}
|
||||
case entity.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 {
|
||||
e.UpdatedAt = value.Time
|
||||
}
|
||||
case entity.FieldDeletedAt:
|
||||
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field deleted_at", values[i])
|
||||
} else if value.Valid {
|
||||
e.DeletedAt = new(time.Time)
|
||||
*e.DeletedAt = value.Time
|
||||
}
|
||||
case entity.FieldType:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field type", values[i])
|
||||
} else if value.Valid {
|
||||
e.Type = int(value.Int64)
|
||||
}
|
||||
case entity.FieldSource:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field source", values[i])
|
||||
} else if value.Valid {
|
||||
e.Source = value.String
|
||||
}
|
||||
case entity.FieldSize:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field size", values[i])
|
||||
} else if value.Valid {
|
||||
e.Size = value.Int64
|
||||
}
|
||||
case entity.FieldReferenceCount:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field reference_count", values[i])
|
||||
} else if value.Valid {
|
||||
e.ReferenceCount = int(value.Int64)
|
||||
}
|
||||
case entity.FieldStoragePolicyEntities:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field storage_policy_entities", values[i])
|
||||
} else if value.Valid {
|
||||
e.StoragePolicyEntities = int(value.Int64)
|
||||
}
|
||||
case entity.FieldCreatedBy:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field created_by", values[i])
|
||||
} else if value.Valid {
|
||||
e.CreatedBy = int(value.Int64)
|
||||
}
|
||||
case entity.FieldUploadSessionID:
|
||||
if value, ok := values[i].(*sql.NullScanner); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field upload_session_id", values[i])
|
||||
} else if value.Valid {
|
||||
e.UploadSessionID = new(uuid.UUID)
|
||||
*e.UploadSessionID = *value.S.(*uuid.UUID)
|
||||
}
|
||||
case entity.FieldProps:
|
||||
if value, ok := values[i].(*[]byte); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field props", values[i])
|
||||
} else if value != nil && len(*value) > 0 {
|
||||
if err := json.Unmarshal(*value, &e.Props); err != nil {
|
||||
return fmt.Errorf("unmarshal field props: %w", err)
|
||||
}
|
||||
}
|
||||
default:
|
||||
e.selectValues.Set(columns[i], values[i])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value returns the ent.Value that was dynamically selected and assigned to the Entity.
|
||||
// This includes values selected through modifiers, order, etc.
|
||||
func (e *Entity) Value(name string) (ent.Value, error) {
|
||||
return e.selectValues.Get(name)
|
||||
}
|
||||
|
||||
// QueryFile queries the "file" edge of the Entity entity.
|
||||
func (e *Entity) QueryFile() *FileQuery {
|
||||
return NewEntityClient(e.config).QueryFile(e)
|
||||
}
|
||||
|
||||
// QueryUser queries the "user" edge of the Entity entity.
|
||||
func (e *Entity) QueryUser() *UserQuery {
|
||||
return NewEntityClient(e.config).QueryUser(e)
|
||||
}
|
||||
|
||||
// QueryStoragePolicy queries the "storage_policy" edge of the Entity entity.
|
||||
func (e *Entity) QueryStoragePolicy() *StoragePolicyQuery {
|
||||
return NewEntityClient(e.config).QueryStoragePolicy(e)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this Entity.
|
||||
// Note that you need to call Entity.Unwrap() before calling this method if this Entity
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (e *Entity) Update() *EntityUpdateOne {
|
||||
return NewEntityClient(e.config).UpdateOne(e)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the Entity 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 (e *Entity) Unwrap() *Entity {
|
||||
_tx, ok := e.config.driver.(*txDriver)
|
||||
if !ok {
|
||||
panic("ent: Entity is not a transactional entity")
|
||||
}
|
||||
e.config.driver = _tx.drv
|
||||
return e
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer.
|
||||
func (e *Entity) String() string {
|
||||
var builder strings.Builder
|
||||
builder.WriteString("Entity(")
|
||||
builder.WriteString(fmt.Sprintf("id=%v, ", e.ID))
|
||||
builder.WriteString("created_at=")
|
||||
builder.WriteString(e.CreatedAt.Format(time.ANSIC))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("updated_at=")
|
||||
builder.WriteString(e.UpdatedAt.Format(time.ANSIC))
|
||||
builder.WriteString(", ")
|
||||
if v := e.DeletedAt; v != nil {
|
||||
builder.WriteString("deleted_at=")
|
||||
builder.WriteString(v.Format(time.ANSIC))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("type=")
|
||||
builder.WriteString(fmt.Sprintf("%v", e.Type))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("source=")
|
||||
builder.WriteString(e.Source)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("size=")
|
||||
builder.WriteString(fmt.Sprintf("%v", e.Size))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("reference_count=")
|
||||
builder.WriteString(fmt.Sprintf("%v", e.ReferenceCount))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("storage_policy_entities=")
|
||||
builder.WriteString(fmt.Sprintf("%v", e.StoragePolicyEntities))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("created_by=")
|
||||
builder.WriteString(fmt.Sprintf("%v", e.CreatedBy))
|
||||
builder.WriteString(", ")
|
||||
if v := e.UploadSessionID; v != nil {
|
||||
builder.WriteString("upload_session_id=")
|
||||
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("props=")
|
||||
builder.WriteString(fmt.Sprintf("%v", e.Props))
|
||||
builder.WriteByte(')')
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
// SetFile manually set the edge as loaded state.
|
||||
func (e *Entity) SetFile(v []*File) {
|
||||
e.Edges.File = v
|
||||
e.Edges.loadedTypes[0] = true
|
||||
}
|
||||
|
||||
// SetUser manually set the edge as loaded state.
|
||||
func (e *Entity) SetUser(v *User) {
|
||||
e.Edges.User = v
|
||||
e.Edges.loadedTypes[1] = true
|
||||
}
|
||||
|
||||
// SetStoragePolicy manually set the edge as loaded state.
|
||||
func (e *Entity) SetStoragePolicy(v *StoragePolicy) {
|
||||
e.Edges.StoragePolicy = v
|
||||
e.Edges.loadedTypes[2] = true
|
||||
}
|
||||
|
||||
// Entities is a parsable slice of Entity.
|
||||
type Entities []*Entity
|
||||
224
ent/entity/entity.go
Normal file
224
ent/entity/entity.go
Normal file
@@ -0,0 +1,224 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
)
|
||||
|
||||
const (
|
||||
// Label holds the string label denoting the entity type in the database.
|
||||
Label = "entity"
|
||||
// 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"
|
||||
// FieldDeletedAt holds the string denoting the deleted_at field in the database.
|
||||
FieldDeletedAt = "deleted_at"
|
||||
// FieldType holds the string denoting the type field in the database.
|
||||
FieldType = "type"
|
||||
// FieldSource holds the string denoting the source field in the database.
|
||||
FieldSource = "source"
|
||||
// FieldSize holds the string denoting the size field in the database.
|
||||
FieldSize = "size"
|
||||
// FieldReferenceCount holds the string denoting the reference_count field in the database.
|
||||
FieldReferenceCount = "reference_count"
|
||||
// FieldStoragePolicyEntities holds the string denoting the storage_policy_entities field in the database.
|
||||
FieldStoragePolicyEntities = "storage_policy_entities"
|
||||
// FieldCreatedBy holds the string denoting the created_by field in the database.
|
||||
FieldCreatedBy = "created_by"
|
||||
// FieldUploadSessionID holds the string denoting the upload_session_id field in the database.
|
||||
FieldUploadSessionID = "upload_session_id"
|
||||
// FieldProps holds the string denoting the props field in the database.
|
||||
FieldProps = "recycle_options"
|
||||
// EdgeFile holds the string denoting the file edge name in mutations.
|
||||
EdgeFile = "file"
|
||||
// EdgeUser holds the string denoting the user edge name in mutations.
|
||||
EdgeUser = "user"
|
||||
// EdgeStoragePolicy holds the string denoting the storage_policy edge name in mutations.
|
||||
EdgeStoragePolicy = "storage_policy"
|
||||
// Table holds the table name of the entity in the database.
|
||||
Table = "entities"
|
||||
// FileTable is the table that holds the file relation/edge. The primary key declared below.
|
||||
FileTable = "file_entities"
|
||||
// FileInverseTable is the table name for the File entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "file" package.
|
||||
FileInverseTable = "files"
|
||||
// UserTable is the table that holds the user relation/edge.
|
||||
UserTable = "entities"
|
||||
// UserInverseTable is the table name for the User entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "user" package.
|
||||
UserInverseTable = "users"
|
||||
// UserColumn is the table column denoting the user relation/edge.
|
||||
UserColumn = "created_by"
|
||||
// StoragePolicyTable is the table that holds the storage_policy relation/edge.
|
||||
StoragePolicyTable = "entities"
|
||||
// StoragePolicyInverseTable is the table name for the StoragePolicy entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "storagepolicy" package.
|
||||
StoragePolicyInverseTable = "storage_policies"
|
||||
// StoragePolicyColumn is the table column denoting the storage_policy relation/edge.
|
||||
StoragePolicyColumn = "storage_policy_entities"
|
||||
)
|
||||
|
||||
// Columns holds all SQL columns for entity fields.
|
||||
var Columns = []string{
|
||||
FieldID,
|
||||
FieldCreatedAt,
|
||||
FieldUpdatedAt,
|
||||
FieldDeletedAt,
|
||||
FieldType,
|
||||
FieldSource,
|
||||
FieldSize,
|
||||
FieldReferenceCount,
|
||||
FieldStoragePolicyEntities,
|
||||
FieldCreatedBy,
|
||||
FieldUploadSessionID,
|
||||
FieldProps,
|
||||
}
|
||||
|
||||
var (
|
||||
// FilePrimaryKey and FileColumn2 are the table columns denoting the
|
||||
// primary key for the file relation (M2M).
|
||||
FilePrimaryKey = []string{"file_id", "entity_id"}
|
||||
)
|
||||
|
||||
// ValidColumn reports if the column name is valid (part of the table columns).
|
||||
func ValidColumn(column string) bool {
|
||||
for i := range Columns {
|
||||
if column == Columns[i] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Note that the variables below are initialized by the runtime
|
||||
// package on the initialization of the application. Therefore,
|
||||
// it should be imported in the main as follows:
|
||||
//
|
||||
// import _ "github.com/cloudreve/Cloudreve/v4/ent/runtime"
|
||||
var (
|
||||
Hooks [1]ent.Hook
|
||||
Interceptors [1]ent.Interceptor
|
||||
// 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
|
||||
// DefaultReferenceCount holds the default value on creation for the "reference_count" field.
|
||||
DefaultReferenceCount int
|
||||
)
|
||||
|
||||
// OrderOption defines the ordering options for the Entity queries.
|
||||
type OrderOption func(*sql.Selector)
|
||||
|
||||
// ByID orders the results by the id field.
|
||||
func ByID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByCreatedAt orders the results by the created_at field.
|
||||
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByUpdatedAt orders the results by the updated_at field.
|
||||
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByDeletedAt orders the results by the deleted_at field.
|
||||
func ByDeletedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldDeletedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByType orders the results by the type field.
|
||||
func ByType(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldType, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// BySource orders the results by the source field.
|
||||
func BySource(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldSource, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// BySize orders the results by the size field.
|
||||
func BySize(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldSize, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByReferenceCount orders the results by the reference_count field.
|
||||
func ByReferenceCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldReferenceCount, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByStoragePolicyEntities orders the results by the storage_policy_entities field.
|
||||
func ByStoragePolicyEntities(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldStoragePolicyEntities, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByCreatedBy orders the results by the created_by field.
|
||||
func ByCreatedBy(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldCreatedBy, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByUploadSessionID orders the results by the upload_session_id field.
|
||||
func ByUploadSessionID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldUploadSessionID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByFileCount orders the results by file count.
|
||||
func ByFileCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborsCount(s, newFileStep(), opts...)
|
||||
}
|
||||
}
|
||||
|
||||
// ByFile orders the results by file terms.
|
||||
func ByFile(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborTerms(s, newFileStep(), append([]sql.OrderTerm{term}, terms...)...)
|
||||
}
|
||||
}
|
||||
|
||||
// ByUserField orders the results by user field.
|
||||
func ByUserField(field string, opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborTerms(s, newUserStep(), sql.OrderByField(field, opts...))
|
||||
}
|
||||
}
|
||||
|
||||
// ByStoragePolicyField orders the results by storage_policy field.
|
||||
func ByStoragePolicyField(field string, opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborTerms(s, newStoragePolicyStep(), sql.OrderByField(field, opts...))
|
||||
}
|
||||
}
|
||||
func newFileStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(FileInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2M, true, FileTable, FilePrimaryKey...),
|
||||
)
|
||||
}
|
||||
func newUserStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(UserInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, UserTable, UserColumn),
|
||||
)
|
||||
}
|
||||
func newStoragePolicyStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(StoragePolicyInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, StoragePolicyTable, StoragePolicyColumn),
|
||||
)
|
||||
}
|
||||
616
ent/entity/where.go
Normal file
616
ent/entity/where.go
Normal file
@@ -0,0 +1,616 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package entity
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||
"github.com/gofrs/uuid"
|
||||
)
|
||||
|
||||
// ID filters vertices based on their ID field.
|
||||
func ID(id int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDEQ applies the EQ predicate on the ID field.
|
||||
func IDEQ(id int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDNEQ applies the NEQ predicate on the ID field.
|
||||
func IDNEQ(id int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDIn applies the In predicate on the ID field.
|
||||
func IDIn(ids ...int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDNotIn applies the NotIn predicate on the ID field.
|
||||
func IDNotIn(ids ...int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNotIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDGT applies the GT predicate on the ID field.
|
||||
func IDGT(id int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldGT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDGTE applies the GTE predicate on the ID field.
|
||||
func IDGTE(id int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldGTE(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLT applies the LT predicate on the ID field.
|
||||
func IDLT(id int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldLT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLTE applies the LTE predicate on the ID field.
|
||||
func IDLTE(id int) predicate.Entity {
|
||||
return predicate.Entity(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.Entity {
|
||||
return predicate.Entity(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.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAt applies equality check predicate on the "deleted_at" field. It's identical to DeletedAtEQ.
|
||||
func DeletedAt(v time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// Type applies equality check predicate on the "type" field. It's identical to TypeEQ.
|
||||
func Type(v int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldType, v))
|
||||
}
|
||||
|
||||
// Source applies equality check predicate on the "source" field. It's identical to SourceEQ.
|
||||
func Source(v string) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldSource, v))
|
||||
}
|
||||
|
||||
// Size applies equality check predicate on the "size" field. It's identical to SizeEQ.
|
||||
func Size(v int64) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldSize, v))
|
||||
}
|
||||
|
||||
// ReferenceCount applies equality check predicate on the "reference_count" field. It's identical to ReferenceCountEQ.
|
||||
func ReferenceCount(v int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldReferenceCount, v))
|
||||
}
|
||||
|
||||
// StoragePolicyEntities applies equality check predicate on the "storage_policy_entities" field. It's identical to StoragePolicyEntitiesEQ.
|
||||
func StoragePolicyEntities(v int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldStoragePolicyEntities, v))
|
||||
}
|
||||
|
||||
// CreatedBy applies equality check predicate on the "created_by" field. It's identical to CreatedByEQ.
|
||||
func CreatedBy(v int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldCreatedBy, v))
|
||||
}
|
||||
|
||||
// UploadSessionID applies equality check predicate on the "upload_session_id" field. It's identical to UploadSessionIDEQ.
|
||||
func UploadSessionID(v uuid.UUID) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldUploadSessionID, v))
|
||||
}
|
||||
|
||||
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
|
||||
func CreatedAtEQ(v time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
|
||||
func CreatedAtNEQ(v time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtIn applies the In predicate on the "created_at" field.
|
||||
func CreatedAtIn(vs ...time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldIn(FieldCreatedAt, vs...))
|
||||
}
|
||||
|
||||
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
|
||||
func CreatedAtNotIn(vs ...time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNotIn(FieldCreatedAt, vs...))
|
||||
}
|
||||
|
||||
// CreatedAtGT applies the GT predicate on the "created_at" field.
|
||||
func CreatedAtGT(v time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldGT(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
|
||||
func CreatedAtGTE(v time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldGTE(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtLT applies the LT predicate on the "created_at" field.
|
||||
func CreatedAtLT(v time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldLT(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
|
||||
func CreatedAtLTE(v time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldLTE(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
|
||||
func UpdatedAtEQ(v time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
|
||||
func UpdatedAtNEQ(v time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtIn applies the In predicate on the "updated_at" field.
|
||||
func UpdatedAtIn(vs ...time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldIn(FieldUpdatedAt, vs...))
|
||||
}
|
||||
|
||||
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
|
||||
func UpdatedAtNotIn(vs ...time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNotIn(FieldUpdatedAt, vs...))
|
||||
}
|
||||
|
||||
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
|
||||
func UpdatedAtGT(v time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldGT(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
|
||||
func UpdatedAtGTE(v time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldGTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
|
||||
func UpdatedAtLT(v time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldLT(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
|
||||
func UpdatedAtLTE(v time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldLTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtEQ applies the EQ predicate on the "deleted_at" field.
|
||||
func DeletedAtEQ(v time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtNEQ applies the NEQ predicate on the "deleted_at" field.
|
||||
func DeletedAtNEQ(v time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNEQ(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtIn applies the In predicate on the "deleted_at" field.
|
||||
func DeletedAtIn(vs ...time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldIn(FieldDeletedAt, vs...))
|
||||
}
|
||||
|
||||
// DeletedAtNotIn applies the NotIn predicate on the "deleted_at" field.
|
||||
func DeletedAtNotIn(vs ...time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNotIn(FieldDeletedAt, vs...))
|
||||
}
|
||||
|
||||
// DeletedAtGT applies the GT predicate on the "deleted_at" field.
|
||||
func DeletedAtGT(v time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldGT(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtGTE applies the GTE predicate on the "deleted_at" field.
|
||||
func DeletedAtGTE(v time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldGTE(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtLT applies the LT predicate on the "deleted_at" field.
|
||||
func DeletedAtLT(v time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldLT(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtLTE applies the LTE predicate on the "deleted_at" field.
|
||||
func DeletedAtLTE(v time.Time) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldLTE(FieldDeletedAt, v))
|
||||
}
|
||||
|
||||
// DeletedAtIsNil applies the IsNil predicate on the "deleted_at" field.
|
||||
func DeletedAtIsNil() predicate.Entity {
|
||||
return predicate.Entity(sql.FieldIsNull(FieldDeletedAt))
|
||||
}
|
||||
|
||||
// DeletedAtNotNil applies the NotNil predicate on the "deleted_at" field.
|
||||
func DeletedAtNotNil() predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNotNull(FieldDeletedAt))
|
||||
}
|
||||
|
||||
// TypeEQ applies the EQ predicate on the "type" field.
|
||||
func TypeEQ(v int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldType, v))
|
||||
}
|
||||
|
||||
// TypeNEQ applies the NEQ predicate on the "type" field.
|
||||
func TypeNEQ(v int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNEQ(FieldType, v))
|
||||
}
|
||||
|
||||
// TypeIn applies the In predicate on the "type" field.
|
||||
func TypeIn(vs ...int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldIn(FieldType, vs...))
|
||||
}
|
||||
|
||||
// TypeNotIn applies the NotIn predicate on the "type" field.
|
||||
func TypeNotIn(vs ...int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNotIn(FieldType, vs...))
|
||||
}
|
||||
|
||||
// TypeGT applies the GT predicate on the "type" field.
|
||||
func TypeGT(v int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldGT(FieldType, v))
|
||||
}
|
||||
|
||||
// TypeGTE applies the GTE predicate on the "type" field.
|
||||
func TypeGTE(v int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldGTE(FieldType, v))
|
||||
}
|
||||
|
||||
// TypeLT applies the LT predicate on the "type" field.
|
||||
func TypeLT(v int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldLT(FieldType, v))
|
||||
}
|
||||
|
||||
// TypeLTE applies the LTE predicate on the "type" field.
|
||||
func TypeLTE(v int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldLTE(FieldType, v))
|
||||
}
|
||||
|
||||
// SourceEQ applies the EQ predicate on the "source" field.
|
||||
func SourceEQ(v string) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldSource, v))
|
||||
}
|
||||
|
||||
// SourceNEQ applies the NEQ predicate on the "source" field.
|
||||
func SourceNEQ(v string) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNEQ(FieldSource, v))
|
||||
}
|
||||
|
||||
// SourceIn applies the In predicate on the "source" field.
|
||||
func SourceIn(vs ...string) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldIn(FieldSource, vs...))
|
||||
}
|
||||
|
||||
// SourceNotIn applies the NotIn predicate on the "source" field.
|
||||
func SourceNotIn(vs ...string) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNotIn(FieldSource, vs...))
|
||||
}
|
||||
|
||||
// SourceGT applies the GT predicate on the "source" field.
|
||||
func SourceGT(v string) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldGT(FieldSource, v))
|
||||
}
|
||||
|
||||
// SourceGTE applies the GTE predicate on the "source" field.
|
||||
func SourceGTE(v string) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldGTE(FieldSource, v))
|
||||
}
|
||||
|
||||
// SourceLT applies the LT predicate on the "source" field.
|
||||
func SourceLT(v string) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldLT(FieldSource, v))
|
||||
}
|
||||
|
||||
// SourceLTE applies the LTE predicate on the "source" field.
|
||||
func SourceLTE(v string) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldLTE(FieldSource, v))
|
||||
}
|
||||
|
||||
// SourceContains applies the Contains predicate on the "source" field.
|
||||
func SourceContains(v string) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldContains(FieldSource, v))
|
||||
}
|
||||
|
||||
// SourceHasPrefix applies the HasPrefix predicate on the "source" field.
|
||||
func SourceHasPrefix(v string) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldHasPrefix(FieldSource, v))
|
||||
}
|
||||
|
||||
// SourceHasSuffix applies the HasSuffix predicate on the "source" field.
|
||||
func SourceHasSuffix(v string) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldHasSuffix(FieldSource, v))
|
||||
}
|
||||
|
||||
// SourceEqualFold applies the EqualFold predicate on the "source" field.
|
||||
func SourceEqualFold(v string) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEqualFold(FieldSource, v))
|
||||
}
|
||||
|
||||
// SourceContainsFold applies the ContainsFold predicate on the "source" field.
|
||||
func SourceContainsFold(v string) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldContainsFold(FieldSource, v))
|
||||
}
|
||||
|
||||
// SizeEQ applies the EQ predicate on the "size" field.
|
||||
func SizeEQ(v int64) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldSize, v))
|
||||
}
|
||||
|
||||
// SizeNEQ applies the NEQ predicate on the "size" field.
|
||||
func SizeNEQ(v int64) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNEQ(FieldSize, v))
|
||||
}
|
||||
|
||||
// SizeIn applies the In predicate on the "size" field.
|
||||
func SizeIn(vs ...int64) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldIn(FieldSize, vs...))
|
||||
}
|
||||
|
||||
// SizeNotIn applies the NotIn predicate on the "size" field.
|
||||
func SizeNotIn(vs ...int64) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNotIn(FieldSize, vs...))
|
||||
}
|
||||
|
||||
// SizeGT applies the GT predicate on the "size" field.
|
||||
func SizeGT(v int64) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldGT(FieldSize, v))
|
||||
}
|
||||
|
||||
// SizeGTE applies the GTE predicate on the "size" field.
|
||||
func SizeGTE(v int64) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldGTE(FieldSize, v))
|
||||
}
|
||||
|
||||
// SizeLT applies the LT predicate on the "size" field.
|
||||
func SizeLT(v int64) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldLT(FieldSize, v))
|
||||
}
|
||||
|
||||
// SizeLTE applies the LTE predicate on the "size" field.
|
||||
func SizeLTE(v int64) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldLTE(FieldSize, v))
|
||||
}
|
||||
|
||||
// ReferenceCountEQ applies the EQ predicate on the "reference_count" field.
|
||||
func ReferenceCountEQ(v int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldReferenceCount, v))
|
||||
}
|
||||
|
||||
// ReferenceCountNEQ applies the NEQ predicate on the "reference_count" field.
|
||||
func ReferenceCountNEQ(v int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNEQ(FieldReferenceCount, v))
|
||||
}
|
||||
|
||||
// ReferenceCountIn applies the In predicate on the "reference_count" field.
|
||||
func ReferenceCountIn(vs ...int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldIn(FieldReferenceCount, vs...))
|
||||
}
|
||||
|
||||
// ReferenceCountNotIn applies the NotIn predicate on the "reference_count" field.
|
||||
func ReferenceCountNotIn(vs ...int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNotIn(FieldReferenceCount, vs...))
|
||||
}
|
||||
|
||||
// ReferenceCountGT applies the GT predicate on the "reference_count" field.
|
||||
func ReferenceCountGT(v int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldGT(FieldReferenceCount, v))
|
||||
}
|
||||
|
||||
// ReferenceCountGTE applies the GTE predicate on the "reference_count" field.
|
||||
func ReferenceCountGTE(v int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldGTE(FieldReferenceCount, v))
|
||||
}
|
||||
|
||||
// ReferenceCountLT applies the LT predicate on the "reference_count" field.
|
||||
func ReferenceCountLT(v int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldLT(FieldReferenceCount, v))
|
||||
}
|
||||
|
||||
// ReferenceCountLTE applies the LTE predicate on the "reference_count" field.
|
||||
func ReferenceCountLTE(v int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldLTE(FieldReferenceCount, v))
|
||||
}
|
||||
|
||||
// StoragePolicyEntitiesEQ applies the EQ predicate on the "storage_policy_entities" field.
|
||||
func StoragePolicyEntitiesEQ(v int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldStoragePolicyEntities, v))
|
||||
}
|
||||
|
||||
// StoragePolicyEntitiesNEQ applies the NEQ predicate on the "storage_policy_entities" field.
|
||||
func StoragePolicyEntitiesNEQ(v int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNEQ(FieldStoragePolicyEntities, v))
|
||||
}
|
||||
|
||||
// StoragePolicyEntitiesIn applies the In predicate on the "storage_policy_entities" field.
|
||||
func StoragePolicyEntitiesIn(vs ...int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldIn(FieldStoragePolicyEntities, vs...))
|
||||
}
|
||||
|
||||
// StoragePolicyEntitiesNotIn applies the NotIn predicate on the "storage_policy_entities" field.
|
||||
func StoragePolicyEntitiesNotIn(vs ...int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNotIn(FieldStoragePolicyEntities, vs...))
|
||||
}
|
||||
|
||||
// CreatedByEQ applies the EQ predicate on the "created_by" field.
|
||||
func CreatedByEQ(v int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldCreatedBy, v))
|
||||
}
|
||||
|
||||
// CreatedByNEQ applies the NEQ predicate on the "created_by" field.
|
||||
func CreatedByNEQ(v int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNEQ(FieldCreatedBy, v))
|
||||
}
|
||||
|
||||
// CreatedByIn applies the In predicate on the "created_by" field.
|
||||
func CreatedByIn(vs ...int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldIn(FieldCreatedBy, vs...))
|
||||
}
|
||||
|
||||
// CreatedByNotIn applies the NotIn predicate on the "created_by" field.
|
||||
func CreatedByNotIn(vs ...int) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNotIn(FieldCreatedBy, vs...))
|
||||
}
|
||||
|
||||
// CreatedByIsNil applies the IsNil predicate on the "created_by" field.
|
||||
func CreatedByIsNil() predicate.Entity {
|
||||
return predicate.Entity(sql.FieldIsNull(FieldCreatedBy))
|
||||
}
|
||||
|
||||
// CreatedByNotNil applies the NotNil predicate on the "created_by" field.
|
||||
func CreatedByNotNil() predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNotNull(FieldCreatedBy))
|
||||
}
|
||||
|
||||
// UploadSessionIDEQ applies the EQ predicate on the "upload_session_id" field.
|
||||
func UploadSessionIDEQ(v uuid.UUID) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldEQ(FieldUploadSessionID, v))
|
||||
}
|
||||
|
||||
// UploadSessionIDNEQ applies the NEQ predicate on the "upload_session_id" field.
|
||||
func UploadSessionIDNEQ(v uuid.UUID) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNEQ(FieldUploadSessionID, v))
|
||||
}
|
||||
|
||||
// UploadSessionIDIn applies the In predicate on the "upload_session_id" field.
|
||||
func UploadSessionIDIn(vs ...uuid.UUID) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldIn(FieldUploadSessionID, vs...))
|
||||
}
|
||||
|
||||
// UploadSessionIDNotIn applies the NotIn predicate on the "upload_session_id" field.
|
||||
func UploadSessionIDNotIn(vs ...uuid.UUID) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNotIn(FieldUploadSessionID, vs...))
|
||||
}
|
||||
|
||||
// UploadSessionIDGT applies the GT predicate on the "upload_session_id" field.
|
||||
func UploadSessionIDGT(v uuid.UUID) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldGT(FieldUploadSessionID, v))
|
||||
}
|
||||
|
||||
// UploadSessionIDGTE applies the GTE predicate on the "upload_session_id" field.
|
||||
func UploadSessionIDGTE(v uuid.UUID) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldGTE(FieldUploadSessionID, v))
|
||||
}
|
||||
|
||||
// UploadSessionIDLT applies the LT predicate on the "upload_session_id" field.
|
||||
func UploadSessionIDLT(v uuid.UUID) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldLT(FieldUploadSessionID, v))
|
||||
}
|
||||
|
||||
// UploadSessionIDLTE applies the LTE predicate on the "upload_session_id" field.
|
||||
func UploadSessionIDLTE(v uuid.UUID) predicate.Entity {
|
||||
return predicate.Entity(sql.FieldLTE(FieldUploadSessionID, v))
|
||||
}
|
||||
|
||||
// UploadSessionIDIsNil applies the IsNil predicate on the "upload_session_id" field.
|
||||
func UploadSessionIDIsNil() predicate.Entity {
|
||||
return predicate.Entity(sql.FieldIsNull(FieldUploadSessionID))
|
||||
}
|
||||
|
||||
// UploadSessionIDNotNil applies the NotNil predicate on the "upload_session_id" field.
|
||||
func UploadSessionIDNotNil() predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNotNull(FieldUploadSessionID))
|
||||
}
|
||||
|
||||
// PropsIsNil applies the IsNil predicate on the "props" field.
|
||||
func PropsIsNil() predicate.Entity {
|
||||
return predicate.Entity(sql.FieldIsNull(FieldProps))
|
||||
}
|
||||
|
||||
// PropsNotNil applies the NotNil predicate on the "props" field.
|
||||
func PropsNotNil() predicate.Entity {
|
||||
return predicate.Entity(sql.FieldNotNull(FieldProps))
|
||||
}
|
||||
|
||||
// HasFile applies the HasEdge predicate on the "file" edge.
|
||||
func HasFile() predicate.Entity {
|
||||
return predicate.Entity(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2M, true, FileTable, FilePrimaryKey...),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasFileWith applies the HasEdge predicate on the "file" edge with a given conditions (other predicates).
|
||||
func HasFileWith(preds ...predicate.File) predicate.Entity {
|
||||
return predicate.Entity(func(s *sql.Selector) {
|
||||
step := newFileStep()
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// HasUser applies the HasEdge predicate on the "user" edge.
|
||||
func HasUser() predicate.Entity {
|
||||
return predicate.Entity(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, UserTable, UserColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasUserWith applies the HasEdge predicate on the "user" edge with a given conditions (other predicates).
|
||||
func HasUserWith(preds ...predicate.User) predicate.Entity {
|
||||
return predicate.Entity(func(s *sql.Selector) {
|
||||
step := newUserStep()
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// HasStoragePolicy applies the HasEdge predicate on the "storage_policy" edge.
|
||||
func HasStoragePolicy() predicate.Entity {
|
||||
return predicate.Entity(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, StoragePolicyTable, StoragePolicyColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasStoragePolicyWith applies the HasEdge predicate on the "storage_policy" edge with a given conditions (other predicates).
|
||||
func HasStoragePolicyWith(preds ...predicate.StoragePolicy) predicate.Entity {
|
||||
return predicate.Entity(func(s *sql.Selector) {
|
||||
step := newStoragePolicyStep()
|
||||
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.Entity) predicate.Entity {
|
||||
return predicate.Entity(sql.AndPredicates(predicates...))
|
||||
}
|
||||
|
||||
// Or groups predicates with the OR operator between them.
|
||||
func Or(predicates ...predicate.Entity) predicate.Entity {
|
||||
return predicate.Entity(sql.OrPredicates(predicates...))
|
||||
}
|
||||
|
||||
// Not applies the not operator on the given predicate.
|
||||
func Not(p predicate.Entity) predicate.Entity {
|
||||
return predicate.Entity(sql.NotPredicates(p))
|
||||
}
|
||||
1267
ent/entity_create.go
Normal file
1267
ent/entity_create.go
Normal file
File diff suppressed because it is too large
Load Diff
88
ent/entity_delete.go
Normal file
88
ent/entity_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/cloudreve/Cloudreve/v4/ent/entity"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||
)
|
||||
|
||||
// EntityDelete is the builder for deleting a Entity entity.
|
||||
type EntityDelete struct {
|
||||
config
|
||||
hooks []Hook
|
||||
mutation *EntityMutation
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the EntityDelete builder.
|
||||
func (ed *EntityDelete) Where(ps ...predicate.Entity) *EntityDelete {
|
||||
ed.mutation.Where(ps...)
|
||||
return ed
|
||||
}
|
||||
|
||||
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||
func (ed *EntityDelete) Exec(ctx context.Context) (int, error) {
|
||||
return withHooks(ctx, ed.sqlExec, ed.mutation, ed.hooks)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (ed *EntityDelete) ExecX(ctx context.Context) int {
|
||||
n, err := ed.Exec(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (ed *EntityDelete) sqlExec(ctx context.Context) (int, error) {
|
||||
_spec := sqlgraph.NewDeleteSpec(entity.Table, sqlgraph.NewFieldSpec(entity.FieldID, field.TypeInt))
|
||||
if ps := ed.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
affected, err := sqlgraph.DeleteNodes(ctx, ed.driver, _spec)
|
||||
if err != nil && sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
ed.mutation.done = true
|
||||
return affected, err
|
||||
}
|
||||
|
||||
// EntityDeleteOne is the builder for deleting a single Entity entity.
|
||||
type EntityDeleteOne struct {
|
||||
ed *EntityDelete
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the EntityDelete builder.
|
||||
func (edo *EntityDeleteOne) Where(ps ...predicate.Entity) *EntityDeleteOne {
|
||||
edo.ed.mutation.Where(ps...)
|
||||
return edo
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (edo *EntityDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := edo.ed.Exec(ctx)
|
||||
switch {
|
||||
case err != nil:
|
||||
return err
|
||||
case n == 0:
|
||||
return &NotFoundError{entity.Label}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (edo *EntityDeleteOne) ExecX(ctx context.Context) {
|
||||
if err := edo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
786
ent/entity_query.go
Normal file
786
ent/entity_query.go
Normal file
@@ -0,0 +1,786 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/entity"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/file"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/storagepolicy"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/user"
|
||||
)
|
||||
|
||||
// EntityQuery is the builder for querying Entity entities.
|
||||
type EntityQuery struct {
|
||||
config
|
||||
ctx *QueryContext
|
||||
order []entity.OrderOption
|
||||
inters []Interceptor
|
||||
predicates []predicate.Entity
|
||||
withFile *FileQuery
|
||||
withUser *UserQuery
|
||||
withStoragePolicy *StoragePolicyQuery
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the EntityQuery builder.
|
||||
func (eq *EntityQuery) Where(ps ...predicate.Entity) *EntityQuery {
|
||||
eq.predicates = append(eq.predicates, ps...)
|
||||
return eq
|
||||
}
|
||||
|
||||
// Limit the number of records to be returned by this query.
|
||||
func (eq *EntityQuery) Limit(limit int) *EntityQuery {
|
||||
eq.ctx.Limit = &limit
|
||||
return eq
|
||||
}
|
||||
|
||||
// Offset to start from.
|
||||
func (eq *EntityQuery) Offset(offset int) *EntityQuery {
|
||||
eq.ctx.Offset = &offset
|
||||
return eq
|
||||
}
|
||||
|
||||
// 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 (eq *EntityQuery) Unique(unique bool) *EntityQuery {
|
||||
eq.ctx.Unique = &unique
|
||||
return eq
|
||||
}
|
||||
|
||||
// Order specifies how the records should be ordered.
|
||||
func (eq *EntityQuery) Order(o ...entity.OrderOption) *EntityQuery {
|
||||
eq.order = append(eq.order, o...)
|
||||
return eq
|
||||
}
|
||||
|
||||
// QueryFile chains the current query on the "file" edge.
|
||||
func (eq *EntityQuery) QueryFile() *FileQuery {
|
||||
query := (&FileClient{config: eq.config}).Query()
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := eq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector := eq.sqlQuery(ctx)
|
||||
if err := selector.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(entity.Table, entity.FieldID, selector),
|
||||
sqlgraph.To(file.Table, file.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2M, true, entity.FileTable, entity.FilePrimaryKey...),
|
||||
)
|
||||
fromU = sqlgraph.SetNeighbors(eq.driver.Dialect(), step)
|
||||
return fromU, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// QueryUser chains the current query on the "user" edge.
|
||||
func (eq *EntityQuery) QueryUser() *UserQuery {
|
||||
query := (&UserClient{config: eq.config}).Query()
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := eq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector := eq.sqlQuery(ctx)
|
||||
if err := selector.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(entity.Table, entity.FieldID, selector),
|
||||
sqlgraph.To(user.Table, user.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, entity.UserTable, entity.UserColumn),
|
||||
)
|
||||
fromU = sqlgraph.SetNeighbors(eq.driver.Dialect(), step)
|
||||
return fromU, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// QueryStoragePolicy chains the current query on the "storage_policy" edge.
|
||||
func (eq *EntityQuery) QueryStoragePolicy() *StoragePolicyQuery {
|
||||
query := (&StoragePolicyClient{config: eq.config}).Query()
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := eq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector := eq.sqlQuery(ctx)
|
||||
if err := selector.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(entity.Table, entity.FieldID, selector),
|
||||
sqlgraph.To(storagepolicy.Table, storagepolicy.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, entity.StoragePolicyTable, entity.StoragePolicyColumn),
|
||||
)
|
||||
fromU = sqlgraph.SetNeighbors(eq.driver.Dialect(), step)
|
||||
return fromU, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// First returns the first Entity entity from the query.
|
||||
// Returns a *NotFoundError when no Entity was found.
|
||||
func (eq *EntityQuery) First(ctx context.Context) (*Entity, error) {
|
||||
nodes, err := eq.Limit(1).All(setContextOp(ctx, eq.ctx, "First"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nil, &NotFoundError{entity.Label}
|
||||
}
|
||||
return nodes[0], nil
|
||||
}
|
||||
|
||||
// FirstX is like First, but panics if an error occurs.
|
||||
func (eq *EntityQuery) FirstX(ctx context.Context) *Entity {
|
||||
node, err := eq.First(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// FirstID returns the first Entity ID from the query.
|
||||
// Returns a *NotFoundError when no Entity ID was found.
|
||||
func (eq *EntityQuery) FirstID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = eq.Limit(1).IDs(setContextOp(ctx, eq.ctx, "FirstID")); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
err = &NotFoundError{entity.Label}
|
||||
return
|
||||
}
|
||||
return ids[0], nil
|
||||
}
|
||||
|
||||
// FirstIDX is like FirstID, but panics if an error occurs.
|
||||
func (eq *EntityQuery) FirstIDX(ctx context.Context) int {
|
||||
id, err := eq.FirstID(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// Only returns a single Entity entity found by the query, ensuring it only returns one.
|
||||
// Returns a *NotSingularError when more than one Entity entity is found.
|
||||
// Returns a *NotFoundError when no Entity entities are found.
|
||||
func (eq *EntityQuery) Only(ctx context.Context) (*Entity, error) {
|
||||
nodes, err := eq.Limit(2).All(setContextOp(ctx, eq.ctx, "Only"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch len(nodes) {
|
||||
case 1:
|
||||
return nodes[0], nil
|
||||
case 0:
|
||||
return nil, &NotFoundError{entity.Label}
|
||||
default:
|
||||
return nil, &NotSingularError{entity.Label}
|
||||
}
|
||||
}
|
||||
|
||||
// OnlyX is like Only, but panics if an error occurs.
|
||||
func (eq *EntityQuery) OnlyX(ctx context.Context) *Entity {
|
||||
node, err := eq.Only(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// OnlyID is like Only, but returns the only Entity ID in the query.
|
||||
// Returns a *NotSingularError when more than one Entity ID is found.
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (eq *EntityQuery) OnlyID(ctx context.Context) (id int, err error) {
|
||||
var ids []int
|
||||
if ids, err = eq.Limit(2).IDs(setContextOp(ctx, eq.ctx, "OnlyID")); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
case 1:
|
||||
id = ids[0]
|
||||
case 0:
|
||||
err = &NotFoundError{entity.Label}
|
||||
default:
|
||||
err = &NotSingularError{entity.Label}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// OnlyIDX is like OnlyID, but panics if an error occurs.
|
||||
func (eq *EntityQuery) OnlyIDX(ctx context.Context) int {
|
||||
id, err := eq.OnlyID(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// All executes the query and returns a list of Entities.
|
||||
func (eq *EntityQuery) All(ctx context.Context) ([]*Entity, error) {
|
||||
ctx = setContextOp(ctx, eq.ctx, "All")
|
||||
if err := eq.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
qr := querierAll[[]*Entity, *EntityQuery]()
|
||||
return withInterceptors[[]*Entity](ctx, eq, qr, eq.inters)
|
||||
}
|
||||
|
||||
// AllX is like All, but panics if an error occurs.
|
||||
func (eq *EntityQuery) AllX(ctx context.Context) []*Entity {
|
||||
nodes, err := eq.All(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
// IDs executes the query and returns a list of Entity IDs.
|
||||
func (eq *EntityQuery) IDs(ctx context.Context) (ids []int, err error) {
|
||||
if eq.ctx.Unique == nil && eq.path != nil {
|
||||
eq.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, eq.ctx, "IDs")
|
||||
if err = eq.Select(entity.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
// IDsX is like IDs, but panics if an error occurs.
|
||||
func (eq *EntityQuery) IDsX(ctx context.Context) []int {
|
||||
ids, err := eq.IDs(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (eq *EntityQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, eq.ctx, "Count")
|
||||
if err := eq.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return withInterceptors[int](ctx, eq, querierCount[*EntityQuery](), eq.inters)
|
||||
}
|
||||
|
||||
// CountX is like Count, but panics if an error occurs.
|
||||
func (eq *EntityQuery) CountX(ctx context.Context) int {
|
||||
count, err := eq.Count(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (eq *EntityQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, eq.ctx, "Exist")
|
||||
switch _, err := eq.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 (eq *EntityQuery) ExistX(ctx context.Context) bool {
|
||||
exist, err := eq.Exist(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return exist
|
||||
}
|
||||
|
||||
// Clone returns a duplicate of the EntityQuery builder, including all associated steps. It can be
|
||||
// used to prepare common query builders and use them differently after the clone is made.
|
||||
func (eq *EntityQuery) Clone() *EntityQuery {
|
||||
if eq == nil {
|
||||
return nil
|
||||
}
|
||||
return &EntityQuery{
|
||||
config: eq.config,
|
||||
ctx: eq.ctx.Clone(),
|
||||
order: append([]entity.OrderOption{}, eq.order...),
|
||||
inters: append([]Interceptor{}, eq.inters...),
|
||||
predicates: append([]predicate.Entity{}, eq.predicates...),
|
||||
withFile: eq.withFile.Clone(),
|
||||
withUser: eq.withUser.Clone(),
|
||||
withStoragePolicy: eq.withStoragePolicy.Clone(),
|
||||
// clone intermediate query.
|
||||
sql: eq.sql.Clone(),
|
||||
path: eq.path,
|
||||
}
|
||||
}
|
||||
|
||||
// WithFile tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "file" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (eq *EntityQuery) WithFile(opts ...func(*FileQuery)) *EntityQuery {
|
||||
query := (&FileClient{config: eq.config}).Query()
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
eq.withFile = query
|
||||
return eq
|
||||
}
|
||||
|
||||
// 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 (eq *EntityQuery) WithUser(opts ...func(*UserQuery)) *EntityQuery {
|
||||
query := (&UserClient{config: eq.config}).Query()
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
eq.withUser = query
|
||||
return eq
|
||||
}
|
||||
|
||||
// WithStoragePolicy tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "storage_policy" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (eq *EntityQuery) WithStoragePolicy(opts ...func(*StoragePolicyQuery)) *EntityQuery {
|
||||
query := (&StoragePolicyClient{config: eq.config}).Query()
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
eq.withStoragePolicy = query
|
||||
return eq
|
||||
}
|
||||
|
||||
// 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.Entity.Query().
|
||||
// GroupBy(entity.FieldCreatedAt).
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (eq *EntityQuery) GroupBy(field string, fields ...string) *EntityGroupBy {
|
||||
eq.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &EntityGroupBy{build: eq}
|
||||
grbuild.flds = &eq.ctx.Fields
|
||||
grbuild.label = entity.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 {
|
||||
// CreatedAt time.Time `json:"created_at,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.Entity.Query().
|
||||
// Select(entity.FieldCreatedAt).
|
||||
// Scan(ctx, &v)
|
||||
func (eq *EntityQuery) Select(fields ...string) *EntitySelect {
|
||||
eq.ctx.Fields = append(eq.ctx.Fields, fields...)
|
||||
sbuild := &EntitySelect{EntityQuery: eq}
|
||||
sbuild.label = entity.Label
|
||||
sbuild.flds, sbuild.scan = &eq.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
// Aggregate returns a EntitySelect configured with the given aggregations.
|
||||
func (eq *EntityQuery) Aggregate(fns ...AggregateFunc) *EntitySelect {
|
||||
return eq.Select().Aggregate(fns...)
|
||||
}
|
||||
|
||||
func (eq *EntityQuery) prepareQuery(ctx context.Context) error {
|
||||
for _, inter := range eq.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, eq); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range eq.ctx.Fields {
|
||||
if !entity.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
}
|
||||
if eq.path != nil {
|
||||
prev, err := eq.path(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
eq.sql = prev
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (eq *EntityQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Entity, error) {
|
||||
var (
|
||||
nodes = []*Entity{}
|
||||
_spec = eq.querySpec()
|
||||
loadedTypes = [3]bool{
|
||||
eq.withFile != nil,
|
||||
eq.withUser != nil,
|
||||
eq.withStoragePolicy != nil,
|
||||
}
|
||||
)
|
||||
_spec.ScanValues = func(columns []string) ([]any, error) {
|
||||
return (*Entity).scanValues(nil, columns)
|
||||
}
|
||||
_spec.Assign = func(columns []string, values []any) error {
|
||||
node := &Entity{config: eq.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, eq.driver, _spec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nodes, nil
|
||||
}
|
||||
if query := eq.withFile; query != nil {
|
||||
if err := eq.loadFile(ctx, query, nodes,
|
||||
func(n *Entity) { n.Edges.File = []*File{} },
|
||||
func(n *Entity, e *File) { n.Edges.File = append(n.Edges.File, e) }); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if query := eq.withUser; query != nil {
|
||||
if err := eq.loadUser(ctx, query, nodes, nil,
|
||||
func(n *Entity, e *User) { n.Edges.User = e }); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if query := eq.withStoragePolicy; query != nil {
|
||||
if err := eq.loadStoragePolicy(ctx, query, nodes, nil,
|
||||
func(n *Entity, e *StoragePolicy) { n.Edges.StoragePolicy = e }); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
func (eq *EntityQuery) loadFile(ctx context.Context, query *FileQuery, nodes []*Entity, init func(*Entity), assign func(*Entity, *File)) error {
|
||||
edgeIDs := make([]driver.Value, len(nodes))
|
||||
byID := make(map[int]*Entity)
|
||||
nids := make(map[int]map[*Entity]struct{})
|
||||
for i, node := range nodes {
|
||||
edgeIDs[i] = node.ID
|
||||
byID[node.ID] = node
|
||||
if init != nil {
|
||||
init(node)
|
||||
}
|
||||
}
|
||||
query.Where(func(s *sql.Selector) {
|
||||
joinT := sql.Table(entity.FileTable)
|
||||
s.Join(joinT).On(s.C(file.FieldID), joinT.C(entity.FilePrimaryKey[0]))
|
||||
s.Where(sql.InValues(joinT.C(entity.FilePrimaryKey[1]), edgeIDs...))
|
||||
columns := s.SelectedColumns()
|
||||
s.Select(joinT.C(entity.FilePrimaryKey[1]))
|
||||
s.AppendSelect(columns...)
|
||||
s.SetDistinct(false)
|
||||
})
|
||||
if err := query.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
qr := QuerierFunc(func(ctx context.Context, q Query) (Value, error) {
|
||||
return query.sqlAll(ctx, func(_ context.Context, spec *sqlgraph.QuerySpec) {
|
||||
assign := spec.Assign
|
||||
values := spec.ScanValues
|
||||
spec.ScanValues = func(columns []string) ([]any, error) {
|
||||
values, err := values(columns[1:])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return append([]any{new(sql.NullInt64)}, values...), nil
|
||||
}
|
||||
spec.Assign = func(columns []string, values []any) error {
|
||||
outValue := int(values[0].(*sql.NullInt64).Int64)
|
||||
inValue := int(values[1].(*sql.NullInt64).Int64)
|
||||
if nids[inValue] == nil {
|
||||
nids[inValue] = map[*Entity]struct{}{byID[outValue]: {}}
|
||||
return assign(columns[1:], values[1:])
|
||||
}
|
||||
nids[inValue][byID[outValue]] = struct{}{}
|
||||
return nil
|
||||
}
|
||||
})
|
||||
})
|
||||
neighbors, err := withInterceptors[[]*File](ctx, query, qr, query.inters)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, n := range neighbors {
|
||||
nodes, ok := nids[n.ID]
|
||||
if !ok {
|
||||
return fmt.Errorf(`unexpected "file" node returned %v`, n.ID)
|
||||
}
|
||||
for kn := range nodes {
|
||||
assign(kn, n)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (eq *EntityQuery) loadUser(ctx context.Context, query *UserQuery, nodes []*Entity, init func(*Entity), assign func(*Entity, *User)) error {
|
||||
ids := make([]int, 0, len(nodes))
|
||||
nodeids := make(map[int][]*Entity)
|
||||
for i := range nodes {
|
||||
fk := nodes[i].CreatedBy
|
||||
if _, ok := nodeids[fk]; !ok {
|
||||
ids = append(ids, fk)
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
query.Where(user.IDIn(ids...))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, n := range neighbors {
|
||||
nodes, ok := nodeids[n.ID]
|
||||
if !ok {
|
||||
return fmt.Errorf(`unexpected foreign-key "created_by" returned %v`, n.ID)
|
||||
}
|
||||
for i := range nodes {
|
||||
assign(nodes[i], n)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (eq *EntityQuery) loadStoragePolicy(ctx context.Context, query *StoragePolicyQuery, nodes []*Entity, init func(*Entity), assign func(*Entity, *StoragePolicy)) error {
|
||||
ids := make([]int, 0, len(nodes))
|
||||
nodeids := make(map[int][]*Entity)
|
||||
for i := range nodes {
|
||||
fk := nodes[i].StoragePolicyEntities
|
||||
if _, ok := nodeids[fk]; !ok {
|
||||
ids = append(ids, fk)
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
query.Where(storagepolicy.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 "storage_policy_entities" returned %v`, n.ID)
|
||||
}
|
||||
for i := range nodes {
|
||||
assign(nodes[i], n)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (eq *EntityQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := eq.querySpec()
|
||||
_spec.Node.Columns = eq.ctx.Fields
|
||||
if len(eq.ctx.Fields) > 0 {
|
||||
_spec.Unique = eq.ctx.Unique != nil && *eq.ctx.Unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, eq.driver, _spec)
|
||||
}
|
||||
|
||||
func (eq *EntityQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
_spec := sqlgraph.NewQuerySpec(entity.Table, entity.Columns, sqlgraph.NewFieldSpec(entity.FieldID, field.TypeInt))
|
||||
_spec.From = eq.sql
|
||||
if unique := eq.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
} else if eq.path != nil {
|
||||
_spec.Unique = true
|
||||
}
|
||||
if fields := eq.ctx.Fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, entity.FieldID)
|
||||
for i := range fields {
|
||||
if fields[i] != entity.FieldID {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
|
||||
}
|
||||
}
|
||||
if eq.withUser != nil {
|
||||
_spec.Node.AddColumnOnce(entity.FieldCreatedBy)
|
||||
}
|
||||
if eq.withStoragePolicy != nil {
|
||||
_spec.Node.AddColumnOnce(entity.FieldStoragePolicyEntities)
|
||||
}
|
||||
}
|
||||
if ps := eq.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := eq.ctx.Limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := eq.ctx.Offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := eq.order; len(ps) > 0 {
|
||||
_spec.Order = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
return _spec
|
||||
}
|
||||
|
||||
func (eq *EntityQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(eq.driver.Dialect())
|
||||
t1 := builder.Table(entity.Table)
|
||||
columns := eq.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = entity.Columns
|
||||
}
|
||||
selector := builder.Select(t1.Columns(columns...)...).From(t1)
|
||||
if eq.sql != nil {
|
||||
selector = eq.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if eq.ctx.Unique != nil && *eq.ctx.Unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, p := range eq.predicates {
|
||||
p(selector)
|
||||
}
|
||||
for _, p := range eq.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := eq.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 := eq.ctx.Limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
}
|
||||
|
||||
// EntityGroupBy is the group-by builder for Entity entities.
|
||||
type EntityGroupBy struct {
|
||||
selector
|
||||
build *EntityQuery
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the group-by query.
|
||||
func (egb *EntityGroupBy) Aggregate(fns ...AggregateFunc) *EntityGroupBy {
|
||||
egb.fns = append(egb.fns, fns...)
|
||||
return egb
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (egb *EntityGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, egb.build.ctx, "GroupBy")
|
||||
if err := egb.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return scanWithInterceptors[*EntityQuery, *EntityGroupBy](ctx, egb.build, egb, egb.build.inters, v)
|
||||
}
|
||||
|
||||
func (egb *EntityGroupBy) sqlScan(ctx context.Context, root *EntityQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx).Select()
|
||||
aggregation := make([]string, 0, len(egb.fns))
|
||||
for _, fn := range egb.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
if len(selector.SelectedColumns()) == 0 {
|
||||
columns := make([]string, 0, len(*egb.flds)+len(egb.fns))
|
||||
for _, f := range *egb.flds {
|
||||
columns = append(columns, selector.C(f))
|
||||
}
|
||||
columns = append(columns, aggregation...)
|
||||
selector.Select(columns...)
|
||||
}
|
||||
selector.GroupBy(selector.Columns(*egb.flds...)...)
|
||||
if err := selector.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := egb.build.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
// EntitySelect is the builder for selecting fields of Entity entities.
|
||||
type EntitySelect struct {
|
||||
*EntityQuery
|
||||
selector
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the selector query.
|
||||
func (es *EntitySelect) Aggregate(fns ...AggregateFunc) *EntitySelect {
|
||||
es.fns = append(es.fns, fns...)
|
||||
return es
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (es *EntitySelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, es.ctx, "Select")
|
||||
if err := es.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return scanWithInterceptors[*EntityQuery, *EntitySelect](ctx, es.EntityQuery, es, es.inters, v)
|
||||
}
|
||||
|
||||
func (es *EntitySelect) sqlScan(ctx context.Context, root *EntityQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx)
|
||||
aggregation := make([]string, 0, len(es.fns))
|
||||
for _, fn := range es.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
switch n := len(*es.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 := es.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
1017
ent/entity_update.go
Normal file
1017
ent/entity_update.go
Normal file
File diff suppressed because it is too large
Load Diff
84
ent/enttest/enttest.go
Normal file
84
ent/enttest/enttest.go
Normal file
@@ -0,0 +1,84 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package enttest
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/cloudreve/Cloudreve/v4/ent"
|
||||
// required by schema hooks.
|
||||
_ "github.com/cloudreve/Cloudreve/v4/ent/runtime"
|
||||
|
||||
"entgo.io/ent/dialect/sql/schema"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/migrate"
|
||||
)
|
||||
|
||||
type (
|
||||
// TestingT is the interface that is shared between
|
||||
// testing.T and testing.B and used by enttest.
|
||||
TestingT interface {
|
||||
FailNow()
|
||||
Error(...any)
|
||||
}
|
||||
|
||||
// Option configures client creation.
|
||||
Option func(*options)
|
||||
|
||||
options struct {
|
||||
opts []ent.Option
|
||||
migrateOpts []schema.MigrateOption
|
||||
}
|
||||
)
|
||||
|
||||
// WithOptions forwards options to client creation.
|
||||
func WithOptions(opts ...ent.Option) Option {
|
||||
return func(o *options) {
|
||||
o.opts = append(o.opts, opts...)
|
||||
}
|
||||
}
|
||||
|
||||
// WithMigrateOptions forwards options to auto migration.
|
||||
func WithMigrateOptions(opts ...schema.MigrateOption) Option {
|
||||
return func(o *options) {
|
||||
o.migrateOpts = append(o.migrateOpts, opts...)
|
||||
}
|
||||
}
|
||||
|
||||
func newOptions(opts []Option) *options {
|
||||
o := &options{}
|
||||
for _, opt := range opts {
|
||||
opt(o)
|
||||
}
|
||||
return o
|
||||
}
|
||||
|
||||
// Open calls ent.Open and auto-run migration.
|
||||
func Open(t TestingT, driverName, dataSourceName string, opts ...Option) *ent.Client {
|
||||
o := newOptions(opts)
|
||||
c, err := ent.Open(driverName, dataSourceName, o.opts...)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.FailNow()
|
||||
}
|
||||
migrateSchema(t, c, o)
|
||||
return c
|
||||
}
|
||||
|
||||
// NewClient calls ent.NewClient and auto-run migration.
|
||||
func NewClient(t TestingT, opts ...Option) *ent.Client {
|
||||
o := newOptions(opts)
|
||||
c := ent.NewClient(o.opts...)
|
||||
migrateSchema(t, c, o)
|
||||
return c
|
||||
}
|
||||
func migrateSchema(t TestingT, c *ent.Client, o *options) {
|
||||
tables, err := schema.CopyTables(migrate.Tables)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
t.FailNow()
|
||||
}
|
||||
if err := migrate.Create(context.Background(), c.Schema, tables, o.migrateOpts...); err != nil {
|
||||
t.Error(err)
|
||||
t.FailNow()
|
||||
}
|
||||
}
|
||||
424
ent/file.go
Normal file
424
ent/file.go
Normal file
@@ -0,0 +1,424 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/file"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/storagepolicy"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/user"
|
||||
"github.com/cloudreve/Cloudreve/v4/inventory/types"
|
||||
)
|
||||
|
||||
// File is the model entity for the File schema.
|
||||
type File struct {
|
||||
config `json:"-"`
|
||||
// ID of the ent.
|
||||
ID int `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"`
|
||||
// Type holds the value of the "type" field.
|
||||
Type int `json:"type,omitempty"`
|
||||
// Name holds the value of the "name" field.
|
||||
Name string `json:"name,omitempty"`
|
||||
// OwnerID holds the value of the "owner_id" field.
|
||||
OwnerID int `json:"owner_id,omitempty"`
|
||||
// Size holds the value of the "size" field.
|
||||
Size int64 `json:"size,omitempty"`
|
||||
// PrimaryEntity holds the value of the "primary_entity" field.
|
||||
PrimaryEntity int `json:"primary_entity,omitempty"`
|
||||
// FileChildren holds the value of the "file_children" field.
|
||||
FileChildren int `json:"file_children,omitempty"`
|
||||
// IsSymbolic holds the value of the "is_symbolic" field.
|
||||
IsSymbolic bool `json:"is_symbolic,omitempty"`
|
||||
// Props holds the value of the "props" field.
|
||||
Props *types.FileProps `json:"props,omitempty"`
|
||||
// StoragePolicyFiles holds the value of the "storage_policy_files" field.
|
||||
StoragePolicyFiles int `json:"storage_policy_files,omitempty"`
|
||||
// Edges holds the relations/edges for other nodes in the graph.
|
||||
// The values are being populated by the FileQuery when eager-loading is set.
|
||||
Edges FileEdges `json:"edges"`
|
||||
selectValues sql.SelectValues
|
||||
}
|
||||
|
||||
// FileEdges holds the relations/edges for other nodes in the graph.
|
||||
type FileEdges struct {
|
||||
// Owner holds the value of the owner edge.
|
||||
Owner *User `json:"owner,omitempty"`
|
||||
// StoragePolicies holds the value of the storage_policies edge.
|
||||
StoragePolicies *StoragePolicy `json:"storage_policies,omitempty"`
|
||||
// Parent holds the value of the parent edge.
|
||||
Parent *File `json:"parent,omitempty"`
|
||||
// Children holds the value of the children edge.
|
||||
Children []*File `json:"children,omitempty"`
|
||||
// Metadata holds the value of the metadata edge.
|
||||
Metadata []*Metadata `json:"metadata,omitempty"`
|
||||
// Entities holds the value of the entities edge.
|
||||
Entities []*Entity `json:"entities,omitempty"`
|
||||
// Shares holds the value of the shares edge.
|
||||
Shares []*Share `json:"shares,omitempty"`
|
||||
// DirectLinks holds the value of the direct_links edge.
|
||||
DirectLinks []*DirectLink `json:"direct_links,omitempty"`
|
||||
// loadedTypes holds the information for reporting if a
|
||||
// type was loaded (or requested) in eager-loading or not.
|
||||
loadedTypes [8]bool
|
||||
}
|
||||
|
||||
// OwnerOrErr returns the Owner value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e FileEdges) OwnerOrErr() (*User, error) {
|
||||
if e.loadedTypes[0] {
|
||||
if e.Owner == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: user.Label}
|
||||
}
|
||||
return e.Owner, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "owner"}
|
||||
}
|
||||
|
||||
// StoragePoliciesOrErr returns the StoragePolicies value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e FileEdges) StoragePoliciesOrErr() (*StoragePolicy, error) {
|
||||
if e.loadedTypes[1] {
|
||||
if e.StoragePolicies == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: storagepolicy.Label}
|
||||
}
|
||||
return e.StoragePolicies, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "storage_policies"}
|
||||
}
|
||||
|
||||
// ParentOrErr returns the Parent value or an error if the edge
|
||||
// was not loaded in eager-loading, or loaded but was not found.
|
||||
func (e FileEdges) ParentOrErr() (*File, error) {
|
||||
if e.loadedTypes[2] {
|
||||
if e.Parent == nil {
|
||||
// Edge was loaded but was not found.
|
||||
return nil, &NotFoundError{label: file.Label}
|
||||
}
|
||||
return e.Parent, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "parent"}
|
||||
}
|
||||
|
||||
// ChildrenOrErr returns the Children value or an error if the edge
|
||||
// was not loaded in eager-loading.
|
||||
func (e FileEdges) ChildrenOrErr() ([]*File, error) {
|
||||
if e.loadedTypes[3] {
|
||||
return e.Children, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "children"}
|
||||
}
|
||||
|
||||
// MetadataOrErr returns the Metadata value or an error if the edge
|
||||
// was not loaded in eager-loading.
|
||||
func (e FileEdges) MetadataOrErr() ([]*Metadata, error) {
|
||||
if e.loadedTypes[4] {
|
||||
return e.Metadata, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "metadata"}
|
||||
}
|
||||
|
||||
// EntitiesOrErr returns the Entities value or an error if the edge
|
||||
// was not loaded in eager-loading.
|
||||
func (e FileEdges) EntitiesOrErr() ([]*Entity, error) {
|
||||
if e.loadedTypes[5] {
|
||||
return e.Entities, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "entities"}
|
||||
}
|
||||
|
||||
// SharesOrErr returns the Shares value or an error if the edge
|
||||
// was not loaded in eager-loading.
|
||||
func (e FileEdges) SharesOrErr() ([]*Share, error) {
|
||||
if e.loadedTypes[6] {
|
||||
return e.Shares, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "shares"}
|
||||
}
|
||||
|
||||
// DirectLinksOrErr returns the DirectLinks value or an error if the edge
|
||||
// was not loaded in eager-loading.
|
||||
func (e FileEdges) DirectLinksOrErr() ([]*DirectLink, error) {
|
||||
if e.loadedTypes[7] {
|
||||
return e.DirectLinks, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "direct_links"}
|
||||
}
|
||||
|
||||
// scanValues returns the types for scanning values from sql.Rows.
|
||||
func (*File) scanValues(columns []string) ([]any, error) {
|
||||
values := make([]any, len(columns))
|
||||
for i := range columns {
|
||||
switch columns[i] {
|
||||
case file.FieldProps:
|
||||
values[i] = new([]byte)
|
||||
case file.FieldIsSymbolic:
|
||||
values[i] = new(sql.NullBool)
|
||||
case file.FieldID, file.FieldType, file.FieldOwnerID, file.FieldSize, file.FieldPrimaryEntity, file.FieldFileChildren, file.FieldStoragePolicyFiles:
|
||||
values[i] = new(sql.NullInt64)
|
||||
case file.FieldName:
|
||||
values[i] = new(sql.NullString)
|
||||
case file.FieldCreatedAt, file.FieldUpdatedAt:
|
||||
values[i] = new(sql.NullTime)
|
||||
default:
|
||||
values[i] = new(sql.UnknownType)
|
||||
}
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// assignValues assigns the values that were returned from sql.Rows (after scanning)
|
||||
// to the File fields.
|
||||
func (f *File) 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 file.FieldID:
|
||||
value, ok := values[i].(*sql.NullInt64)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field id", value)
|
||||
}
|
||||
f.ID = int(value.Int64)
|
||||
case file.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 {
|
||||
f.CreatedAt = value.Time
|
||||
}
|
||||
case file.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 {
|
||||
f.UpdatedAt = value.Time
|
||||
}
|
||||
case file.FieldType:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field type", values[i])
|
||||
} else if value.Valid {
|
||||
f.Type = int(value.Int64)
|
||||
}
|
||||
case file.FieldName:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field name", values[i])
|
||||
} else if value.Valid {
|
||||
f.Name = value.String
|
||||
}
|
||||
case file.FieldOwnerID:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field owner_id", values[i])
|
||||
} else if value.Valid {
|
||||
f.OwnerID = int(value.Int64)
|
||||
}
|
||||
case file.FieldSize:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field size", values[i])
|
||||
} else if value.Valid {
|
||||
f.Size = value.Int64
|
||||
}
|
||||
case file.FieldPrimaryEntity:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field primary_entity", values[i])
|
||||
} else if value.Valid {
|
||||
f.PrimaryEntity = int(value.Int64)
|
||||
}
|
||||
case file.FieldFileChildren:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field file_children", values[i])
|
||||
} else if value.Valid {
|
||||
f.FileChildren = int(value.Int64)
|
||||
}
|
||||
case file.FieldIsSymbolic:
|
||||
if value, ok := values[i].(*sql.NullBool); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field is_symbolic", values[i])
|
||||
} else if value.Valid {
|
||||
f.IsSymbolic = value.Bool
|
||||
}
|
||||
case file.FieldProps:
|
||||
if value, ok := values[i].(*[]byte); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field props", values[i])
|
||||
} else if value != nil && len(*value) > 0 {
|
||||
if err := json.Unmarshal(*value, &f.Props); err != nil {
|
||||
return fmt.Errorf("unmarshal field props: %w", err)
|
||||
}
|
||||
}
|
||||
case file.FieldStoragePolicyFiles:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field storage_policy_files", values[i])
|
||||
} else if value.Valid {
|
||||
f.StoragePolicyFiles = int(value.Int64)
|
||||
}
|
||||
default:
|
||||
f.selectValues.Set(columns[i], values[i])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value returns the ent.Value that was dynamically selected and assigned to the File.
|
||||
// This includes values selected through modifiers, order, etc.
|
||||
func (f *File) Value(name string) (ent.Value, error) {
|
||||
return f.selectValues.Get(name)
|
||||
}
|
||||
|
||||
// QueryOwner queries the "owner" edge of the File entity.
|
||||
func (f *File) QueryOwner() *UserQuery {
|
||||
return NewFileClient(f.config).QueryOwner(f)
|
||||
}
|
||||
|
||||
// QueryStoragePolicies queries the "storage_policies" edge of the File entity.
|
||||
func (f *File) QueryStoragePolicies() *StoragePolicyQuery {
|
||||
return NewFileClient(f.config).QueryStoragePolicies(f)
|
||||
}
|
||||
|
||||
// QueryParent queries the "parent" edge of the File entity.
|
||||
func (f *File) QueryParent() *FileQuery {
|
||||
return NewFileClient(f.config).QueryParent(f)
|
||||
}
|
||||
|
||||
// QueryChildren queries the "children" edge of the File entity.
|
||||
func (f *File) QueryChildren() *FileQuery {
|
||||
return NewFileClient(f.config).QueryChildren(f)
|
||||
}
|
||||
|
||||
// QueryMetadata queries the "metadata" edge of the File entity.
|
||||
func (f *File) QueryMetadata() *MetadataQuery {
|
||||
return NewFileClient(f.config).QueryMetadata(f)
|
||||
}
|
||||
|
||||
// QueryEntities queries the "entities" edge of the File entity.
|
||||
func (f *File) QueryEntities() *EntityQuery {
|
||||
return NewFileClient(f.config).QueryEntities(f)
|
||||
}
|
||||
|
||||
// QueryShares queries the "shares" edge of the File entity.
|
||||
func (f *File) QueryShares() *ShareQuery {
|
||||
return NewFileClient(f.config).QueryShares(f)
|
||||
}
|
||||
|
||||
// QueryDirectLinks queries the "direct_links" edge of the File entity.
|
||||
func (f *File) QueryDirectLinks() *DirectLinkQuery {
|
||||
return NewFileClient(f.config).QueryDirectLinks(f)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this File.
|
||||
// Note that you need to call File.Unwrap() before calling this method if this File
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (f *File) Update() *FileUpdateOne {
|
||||
return NewFileClient(f.config).UpdateOne(f)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the File 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 (f *File) Unwrap() *File {
|
||||
_tx, ok := f.config.driver.(*txDriver)
|
||||
if !ok {
|
||||
panic("ent: File is not a transactional entity")
|
||||
}
|
||||
f.config.driver = _tx.drv
|
||||
return f
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer.
|
||||
func (f *File) String() string {
|
||||
var builder strings.Builder
|
||||
builder.WriteString("File(")
|
||||
builder.WriteString(fmt.Sprintf("id=%v, ", f.ID))
|
||||
builder.WriteString("created_at=")
|
||||
builder.WriteString(f.CreatedAt.Format(time.ANSIC))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("updated_at=")
|
||||
builder.WriteString(f.UpdatedAt.Format(time.ANSIC))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("type=")
|
||||
builder.WriteString(fmt.Sprintf("%v", f.Type))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("name=")
|
||||
builder.WriteString(f.Name)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("owner_id=")
|
||||
builder.WriteString(fmt.Sprintf("%v", f.OwnerID))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("size=")
|
||||
builder.WriteString(fmt.Sprintf("%v", f.Size))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("primary_entity=")
|
||||
builder.WriteString(fmt.Sprintf("%v", f.PrimaryEntity))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("file_children=")
|
||||
builder.WriteString(fmt.Sprintf("%v", f.FileChildren))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("is_symbolic=")
|
||||
builder.WriteString(fmt.Sprintf("%v", f.IsSymbolic))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("props=")
|
||||
builder.WriteString(fmt.Sprintf("%v", f.Props))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("storage_policy_files=")
|
||||
builder.WriteString(fmt.Sprintf("%v", f.StoragePolicyFiles))
|
||||
builder.WriteByte(')')
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
// SetOwner manually set the edge as loaded state.
|
||||
func (e *File) SetOwner(v *User) {
|
||||
e.Edges.Owner = v
|
||||
e.Edges.loadedTypes[0] = true
|
||||
}
|
||||
|
||||
// SetStoragePolicies manually set the edge as loaded state.
|
||||
func (e *File) SetStoragePolicies(v *StoragePolicy) {
|
||||
e.Edges.StoragePolicies = v
|
||||
e.Edges.loadedTypes[1] = true
|
||||
}
|
||||
|
||||
// SetParent manually set the edge as loaded state.
|
||||
func (e *File) SetParent(v *File) {
|
||||
e.Edges.Parent = v
|
||||
e.Edges.loadedTypes[2] = true
|
||||
}
|
||||
|
||||
// SetChildren manually set the edge as loaded state.
|
||||
func (e *File) SetChildren(v []*File) {
|
||||
e.Edges.Children = v
|
||||
e.Edges.loadedTypes[3] = true
|
||||
}
|
||||
|
||||
// SetMetadata manually set the edge as loaded state.
|
||||
func (e *File) SetMetadata(v []*Metadata) {
|
||||
e.Edges.Metadata = v
|
||||
e.Edges.loadedTypes[4] = true
|
||||
}
|
||||
|
||||
// SetEntities manually set the edge as loaded state.
|
||||
func (e *File) SetEntities(v []*Entity) {
|
||||
e.Edges.Entities = v
|
||||
e.Edges.loadedTypes[5] = true
|
||||
}
|
||||
|
||||
// SetShares manually set the edge as loaded state.
|
||||
func (e *File) SetShares(v []*Share) {
|
||||
e.Edges.Shares = v
|
||||
e.Edges.loadedTypes[6] = true
|
||||
}
|
||||
|
||||
// SetDirectLinks manually set the edge as loaded state.
|
||||
func (e *File) SetDirectLinks(v []*DirectLink) {
|
||||
e.Edges.DirectLinks = v
|
||||
e.Edges.loadedTypes[7] = true
|
||||
}
|
||||
|
||||
// Files is a parsable slice of File.
|
||||
type Files []*File
|
||||
360
ent/file/file.go
Normal file
360
ent/file/file.go
Normal file
@@ -0,0 +1,360 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package file
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
)
|
||||
|
||||
const (
|
||||
// Label holds the string label denoting the file type in the database.
|
||||
Label = "file"
|
||||
// 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"
|
||||
// FieldType holds the string denoting the type field in the database.
|
||||
FieldType = "type"
|
||||
// FieldName holds the string denoting the name field in the database.
|
||||
FieldName = "name"
|
||||
// FieldOwnerID holds the string denoting the owner_id field in the database.
|
||||
FieldOwnerID = "owner_id"
|
||||
// FieldSize holds the string denoting the size field in the database.
|
||||
FieldSize = "size"
|
||||
// FieldPrimaryEntity holds the string denoting the primary_entity field in the database.
|
||||
FieldPrimaryEntity = "primary_entity"
|
||||
// FieldFileChildren holds the string denoting the file_children field in the database.
|
||||
FieldFileChildren = "file_children"
|
||||
// FieldIsSymbolic holds the string denoting the is_symbolic field in the database.
|
||||
FieldIsSymbolic = "is_symbolic"
|
||||
// FieldProps holds the string denoting the props field in the database.
|
||||
FieldProps = "props"
|
||||
// FieldStoragePolicyFiles holds the string denoting the storage_policy_files field in the database.
|
||||
FieldStoragePolicyFiles = "storage_policy_files"
|
||||
// EdgeOwner holds the string denoting the owner edge name in mutations.
|
||||
EdgeOwner = "owner"
|
||||
// EdgeStoragePolicies holds the string denoting the storage_policies edge name in mutations.
|
||||
EdgeStoragePolicies = "storage_policies"
|
||||
// EdgeParent holds the string denoting the parent edge name in mutations.
|
||||
EdgeParent = "parent"
|
||||
// EdgeChildren holds the string denoting the children edge name in mutations.
|
||||
EdgeChildren = "children"
|
||||
// EdgeMetadata holds the string denoting the metadata edge name in mutations.
|
||||
EdgeMetadata = "metadata"
|
||||
// EdgeEntities holds the string denoting the entities edge name in mutations.
|
||||
EdgeEntities = "entities"
|
||||
// EdgeShares holds the string denoting the shares edge name in mutations.
|
||||
EdgeShares = "shares"
|
||||
// EdgeDirectLinks holds the string denoting the direct_links edge name in mutations.
|
||||
EdgeDirectLinks = "direct_links"
|
||||
// Table holds the table name of the file in the database.
|
||||
Table = "files"
|
||||
// OwnerTable is the table that holds the owner relation/edge.
|
||||
OwnerTable = "files"
|
||||
// OwnerInverseTable is the table name for the User entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "user" package.
|
||||
OwnerInverseTable = "users"
|
||||
// OwnerColumn is the table column denoting the owner relation/edge.
|
||||
OwnerColumn = "owner_id"
|
||||
// StoragePoliciesTable is the table that holds the storage_policies relation/edge.
|
||||
StoragePoliciesTable = "files"
|
||||
// StoragePoliciesInverseTable is the table name for the StoragePolicy entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "storagepolicy" package.
|
||||
StoragePoliciesInverseTable = "storage_policies"
|
||||
// StoragePoliciesColumn is the table column denoting the storage_policies relation/edge.
|
||||
StoragePoliciesColumn = "storage_policy_files"
|
||||
// ParentTable is the table that holds the parent relation/edge.
|
||||
ParentTable = "files"
|
||||
// ParentColumn is the table column denoting the parent relation/edge.
|
||||
ParentColumn = "file_children"
|
||||
// ChildrenTable is the table that holds the children relation/edge.
|
||||
ChildrenTable = "files"
|
||||
// ChildrenColumn is the table column denoting the children relation/edge.
|
||||
ChildrenColumn = "file_children"
|
||||
// MetadataTable is the table that holds the metadata relation/edge.
|
||||
MetadataTable = "metadata"
|
||||
// MetadataInverseTable is the table name for the Metadata entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "metadata" package.
|
||||
MetadataInverseTable = "metadata"
|
||||
// MetadataColumn is the table column denoting the metadata relation/edge.
|
||||
MetadataColumn = "file_id"
|
||||
// EntitiesTable is the table that holds the entities relation/edge. The primary key declared below.
|
||||
EntitiesTable = "file_entities"
|
||||
// EntitiesInverseTable is the table name for the Entity entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "entity" package.
|
||||
EntitiesInverseTable = "entities"
|
||||
// SharesTable is the table that holds the shares relation/edge.
|
||||
SharesTable = "shares"
|
||||
// SharesInverseTable is the table name for the Share entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "share" package.
|
||||
SharesInverseTable = "shares"
|
||||
// SharesColumn is the table column denoting the shares relation/edge.
|
||||
SharesColumn = "file_shares"
|
||||
// DirectLinksTable is the table that holds the direct_links relation/edge.
|
||||
DirectLinksTable = "direct_links"
|
||||
// DirectLinksInverseTable is the table name for the DirectLink entity.
|
||||
// It exists in this package in order to avoid circular dependency with the "directlink" package.
|
||||
DirectLinksInverseTable = "direct_links"
|
||||
// DirectLinksColumn is the table column denoting the direct_links relation/edge.
|
||||
DirectLinksColumn = "file_id"
|
||||
)
|
||||
|
||||
// Columns holds all SQL columns for file fields.
|
||||
var Columns = []string{
|
||||
FieldID,
|
||||
FieldCreatedAt,
|
||||
FieldUpdatedAt,
|
||||
FieldType,
|
||||
FieldName,
|
||||
FieldOwnerID,
|
||||
FieldSize,
|
||||
FieldPrimaryEntity,
|
||||
FieldFileChildren,
|
||||
FieldIsSymbolic,
|
||||
FieldProps,
|
||||
FieldStoragePolicyFiles,
|
||||
}
|
||||
|
||||
var (
|
||||
// EntitiesPrimaryKey and EntitiesColumn2 are the table columns denoting the
|
||||
// primary key for the entities relation (M2M).
|
||||
EntitiesPrimaryKey = []string{"file_id", "entity_id"}
|
||||
)
|
||||
|
||||
// ValidColumn reports if the column name is valid (part of the table columns).
|
||||
func ValidColumn(column string) bool {
|
||||
for i := range Columns {
|
||||
if column == Columns[i] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Note that the variables below are initialized by the runtime
|
||||
// package on the initialization of the application. Therefore,
|
||||
// it should be imported in the main as follows:
|
||||
//
|
||||
// import _ "github.com/cloudreve/Cloudreve/v4/ent/runtime"
|
||||
var (
|
||||
Hooks [1]ent.Hook
|
||||
// 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
|
||||
// DefaultSize holds the default value on creation for the "size" field.
|
||||
DefaultSize int64
|
||||
// DefaultIsSymbolic holds the default value on creation for the "is_symbolic" field.
|
||||
DefaultIsSymbolic bool
|
||||
)
|
||||
|
||||
// OrderOption defines the ordering options for the File queries.
|
||||
type OrderOption func(*sql.Selector)
|
||||
|
||||
// ByID orders the results by the id field.
|
||||
func ByID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByCreatedAt orders the results by the created_at field.
|
||||
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByUpdatedAt orders the results by the updated_at field.
|
||||
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByType orders the results by the type field.
|
||||
func ByType(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldType, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByName orders the results by the name field.
|
||||
func ByName(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldName, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByOwnerID orders the results by the owner_id field.
|
||||
func ByOwnerID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldOwnerID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// BySize orders the results by the size field.
|
||||
func BySize(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldSize, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByPrimaryEntity orders the results by the primary_entity field.
|
||||
func ByPrimaryEntity(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldPrimaryEntity, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByFileChildren orders the results by the file_children field.
|
||||
func ByFileChildren(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldFileChildren, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByIsSymbolic orders the results by the is_symbolic field.
|
||||
func ByIsSymbolic(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldIsSymbolic, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByStoragePolicyFiles orders the results by the storage_policy_files field.
|
||||
func ByStoragePolicyFiles(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldStoragePolicyFiles, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByOwnerField orders the results by owner field.
|
||||
func ByOwnerField(field string, opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborTerms(s, newOwnerStep(), sql.OrderByField(field, opts...))
|
||||
}
|
||||
}
|
||||
|
||||
// ByStoragePoliciesField orders the results by storage_policies field.
|
||||
func ByStoragePoliciesField(field string, opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborTerms(s, newStoragePoliciesStep(), sql.OrderByField(field, opts...))
|
||||
}
|
||||
}
|
||||
|
||||
// ByParentField orders the results by parent field.
|
||||
func ByParentField(field string, opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborTerms(s, newParentStep(), sql.OrderByField(field, opts...))
|
||||
}
|
||||
}
|
||||
|
||||
// ByChildrenCount orders the results by children count.
|
||||
func ByChildrenCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborsCount(s, newChildrenStep(), opts...)
|
||||
}
|
||||
}
|
||||
|
||||
// ByChildren orders the results by children terms.
|
||||
func ByChildren(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborTerms(s, newChildrenStep(), append([]sql.OrderTerm{term}, terms...)...)
|
||||
}
|
||||
}
|
||||
|
||||
// ByMetadataCount orders the results by metadata count.
|
||||
func ByMetadataCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborsCount(s, newMetadataStep(), opts...)
|
||||
}
|
||||
}
|
||||
|
||||
// ByMetadata orders the results by metadata terms.
|
||||
func ByMetadata(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborTerms(s, newMetadataStep(), append([]sql.OrderTerm{term}, terms...)...)
|
||||
}
|
||||
}
|
||||
|
||||
// ByEntitiesCount orders the results by entities count.
|
||||
func ByEntitiesCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborsCount(s, newEntitiesStep(), opts...)
|
||||
}
|
||||
}
|
||||
|
||||
// ByEntities orders the results by entities terms.
|
||||
func ByEntities(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborTerms(s, newEntitiesStep(), append([]sql.OrderTerm{term}, terms...)...)
|
||||
}
|
||||
}
|
||||
|
||||
// BySharesCount orders the results by shares count.
|
||||
func BySharesCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborsCount(s, newSharesStep(), opts...)
|
||||
}
|
||||
}
|
||||
|
||||
// ByShares orders the results by shares terms.
|
||||
func ByShares(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborTerms(s, newSharesStep(), append([]sql.OrderTerm{term}, terms...)...)
|
||||
}
|
||||
}
|
||||
|
||||
// ByDirectLinksCount orders the results by direct_links count.
|
||||
func ByDirectLinksCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborsCount(s, newDirectLinksStep(), opts...)
|
||||
}
|
||||
}
|
||||
|
||||
// ByDirectLinks orders the results by direct_links terms.
|
||||
func ByDirectLinks(term sql.OrderTerm, terms ...sql.OrderTerm) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
sqlgraph.OrderByNeighborTerms(s, newDirectLinksStep(), append([]sql.OrderTerm{term}, terms...)...)
|
||||
}
|
||||
}
|
||||
func newOwnerStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(OwnerInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, OwnerTable, OwnerColumn),
|
||||
)
|
||||
}
|
||||
func newStoragePoliciesStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(StoragePoliciesInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, StoragePoliciesTable, StoragePoliciesColumn),
|
||||
)
|
||||
}
|
||||
func newParentStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, ParentTable, ParentColumn),
|
||||
)
|
||||
}
|
||||
func newChildrenStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, ChildrenTable, ChildrenColumn),
|
||||
)
|
||||
}
|
||||
func newMetadataStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(MetadataInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, MetadataTable, MetadataColumn),
|
||||
)
|
||||
}
|
||||
func newEntitiesStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(EntitiesInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2M, false, EntitiesTable, EntitiesPrimaryKey...),
|
||||
)
|
||||
}
|
||||
func newSharesStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(SharesInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, SharesTable, SharesColumn),
|
||||
)
|
||||
}
|
||||
func newDirectLinksStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.To(DirectLinksInverseTable, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, DirectLinksTable, DirectLinksColumn),
|
||||
)
|
||||
}
|
||||
680
ent/file/where.go
Normal file
680
ent/file/where.go
Normal file
@@ -0,0 +1,680 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package file
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||
)
|
||||
|
||||
// ID filters vertices based on their ID field.
|
||||
func ID(id int) predicate.File {
|
||||
return predicate.File(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDEQ applies the EQ predicate on the ID field.
|
||||
func IDEQ(id int) predicate.File {
|
||||
return predicate.File(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDNEQ applies the NEQ predicate on the ID field.
|
||||
func IDNEQ(id int) predicate.File {
|
||||
return predicate.File(sql.FieldNEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDIn applies the In predicate on the ID field.
|
||||
func IDIn(ids ...int) predicate.File {
|
||||
return predicate.File(sql.FieldIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDNotIn applies the NotIn predicate on the ID field.
|
||||
func IDNotIn(ids ...int) predicate.File {
|
||||
return predicate.File(sql.FieldNotIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDGT applies the GT predicate on the ID field.
|
||||
func IDGT(id int) predicate.File {
|
||||
return predicate.File(sql.FieldGT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDGTE applies the GTE predicate on the ID field.
|
||||
func IDGTE(id int) predicate.File {
|
||||
return predicate.File(sql.FieldGTE(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLT applies the LT predicate on the ID field.
|
||||
func IDLT(id int) predicate.File {
|
||||
return predicate.File(sql.FieldLT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLTE applies the LTE predicate on the ID field.
|
||||
func IDLTE(id int) predicate.File {
|
||||
return predicate.File(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.File {
|
||||
return predicate.File(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.File {
|
||||
return predicate.File(sql.FieldEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// Type applies equality check predicate on the "type" field. It's identical to TypeEQ.
|
||||
func Type(v int) predicate.File {
|
||||
return predicate.File(sql.FieldEQ(FieldType, v))
|
||||
}
|
||||
|
||||
// Name applies equality check predicate on the "name" field. It's identical to NameEQ.
|
||||
func Name(v string) predicate.File {
|
||||
return predicate.File(sql.FieldEQ(FieldName, v))
|
||||
}
|
||||
|
||||
// OwnerID applies equality check predicate on the "owner_id" field. It's identical to OwnerIDEQ.
|
||||
func OwnerID(v int) predicate.File {
|
||||
return predicate.File(sql.FieldEQ(FieldOwnerID, v))
|
||||
}
|
||||
|
||||
// Size applies equality check predicate on the "size" field. It's identical to SizeEQ.
|
||||
func Size(v int64) predicate.File {
|
||||
return predicate.File(sql.FieldEQ(FieldSize, v))
|
||||
}
|
||||
|
||||
// PrimaryEntity applies equality check predicate on the "primary_entity" field. It's identical to PrimaryEntityEQ.
|
||||
func PrimaryEntity(v int) predicate.File {
|
||||
return predicate.File(sql.FieldEQ(FieldPrimaryEntity, v))
|
||||
}
|
||||
|
||||
// FileChildren applies equality check predicate on the "file_children" field. It's identical to FileChildrenEQ.
|
||||
func FileChildren(v int) predicate.File {
|
||||
return predicate.File(sql.FieldEQ(FieldFileChildren, v))
|
||||
}
|
||||
|
||||
// IsSymbolic applies equality check predicate on the "is_symbolic" field. It's identical to IsSymbolicEQ.
|
||||
func IsSymbolic(v bool) predicate.File {
|
||||
return predicate.File(sql.FieldEQ(FieldIsSymbolic, v))
|
||||
}
|
||||
|
||||
// StoragePolicyFiles applies equality check predicate on the "storage_policy_files" field. It's identical to StoragePolicyFilesEQ.
|
||||
func StoragePolicyFiles(v int) predicate.File {
|
||||
return predicate.File(sql.FieldEQ(FieldStoragePolicyFiles, v))
|
||||
}
|
||||
|
||||
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
|
||||
func CreatedAtEQ(v time.Time) predicate.File {
|
||||
return predicate.File(sql.FieldEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
|
||||
func CreatedAtNEQ(v time.Time) predicate.File {
|
||||
return predicate.File(sql.FieldNEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtIn applies the In predicate on the "created_at" field.
|
||||
func CreatedAtIn(vs ...time.Time) predicate.File {
|
||||
return predicate.File(sql.FieldIn(FieldCreatedAt, vs...))
|
||||
}
|
||||
|
||||
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
|
||||
func CreatedAtNotIn(vs ...time.Time) predicate.File {
|
||||
return predicate.File(sql.FieldNotIn(FieldCreatedAt, vs...))
|
||||
}
|
||||
|
||||
// CreatedAtGT applies the GT predicate on the "created_at" field.
|
||||
func CreatedAtGT(v time.Time) predicate.File {
|
||||
return predicate.File(sql.FieldGT(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
|
||||
func CreatedAtGTE(v time.Time) predicate.File {
|
||||
return predicate.File(sql.FieldGTE(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtLT applies the LT predicate on the "created_at" field.
|
||||
func CreatedAtLT(v time.Time) predicate.File {
|
||||
return predicate.File(sql.FieldLT(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
|
||||
func CreatedAtLTE(v time.Time) predicate.File {
|
||||
return predicate.File(sql.FieldLTE(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
|
||||
func UpdatedAtEQ(v time.Time) predicate.File {
|
||||
return predicate.File(sql.FieldEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
|
||||
func UpdatedAtNEQ(v time.Time) predicate.File {
|
||||
return predicate.File(sql.FieldNEQ(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtIn applies the In predicate on the "updated_at" field.
|
||||
func UpdatedAtIn(vs ...time.Time) predicate.File {
|
||||
return predicate.File(sql.FieldIn(FieldUpdatedAt, vs...))
|
||||
}
|
||||
|
||||
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
|
||||
func UpdatedAtNotIn(vs ...time.Time) predicate.File {
|
||||
return predicate.File(sql.FieldNotIn(FieldUpdatedAt, vs...))
|
||||
}
|
||||
|
||||
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
|
||||
func UpdatedAtGT(v time.Time) predicate.File {
|
||||
return predicate.File(sql.FieldGT(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
|
||||
func UpdatedAtGTE(v time.Time) predicate.File {
|
||||
return predicate.File(sql.FieldGTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
|
||||
func UpdatedAtLT(v time.Time) predicate.File {
|
||||
return predicate.File(sql.FieldLT(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
|
||||
func UpdatedAtLTE(v time.Time) predicate.File {
|
||||
return predicate.File(sql.FieldLTE(FieldUpdatedAt, v))
|
||||
}
|
||||
|
||||
// TypeEQ applies the EQ predicate on the "type" field.
|
||||
func TypeEQ(v int) predicate.File {
|
||||
return predicate.File(sql.FieldEQ(FieldType, v))
|
||||
}
|
||||
|
||||
// TypeNEQ applies the NEQ predicate on the "type" field.
|
||||
func TypeNEQ(v int) predicate.File {
|
||||
return predicate.File(sql.FieldNEQ(FieldType, v))
|
||||
}
|
||||
|
||||
// TypeIn applies the In predicate on the "type" field.
|
||||
func TypeIn(vs ...int) predicate.File {
|
||||
return predicate.File(sql.FieldIn(FieldType, vs...))
|
||||
}
|
||||
|
||||
// TypeNotIn applies the NotIn predicate on the "type" field.
|
||||
func TypeNotIn(vs ...int) predicate.File {
|
||||
return predicate.File(sql.FieldNotIn(FieldType, vs...))
|
||||
}
|
||||
|
||||
// TypeGT applies the GT predicate on the "type" field.
|
||||
func TypeGT(v int) predicate.File {
|
||||
return predicate.File(sql.FieldGT(FieldType, v))
|
||||
}
|
||||
|
||||
// TypeGTE applies the GTE predicate on the "type" field.
|
||||
func TypeGTE(v int) predicate.File {
|
||||
return predicate.File(sql.FieldGTE(FieldType, v))
|
||||
}
|
||||
|
||||
// TypeLT applies the LT predicate on the "type" field.
|
||||
func TypeLT(v int) predicate.File {
|
||||
return predicate.File(sql.FieldLT(FieldType, v))
|
||||
}
|
||||
|
||||
// TypeLTE applies the LTE predicate on the "type" field.
|
||||
func TypeLTE(v int) predicate.File {
|
||||
return predicate.File(sql.FieldLTE(FieldType, v))
|
||||
}
|
||||
|
||||
// NameEQ applies the EQ predicate on the "name" field.
|
||||
func NameEQ(v string) predicate.File {
|
||||
return predicate.File(sql.FieldEQ(FieldName, v))
|
||||
}
|
||||
|
||||
// NameNEQ applies the NEQ predicate on the "name" field.
|
||||
func NameNEQ(v string) predicate.File {
|
||||
return predicate.File(sql.FieldNEQ(FieldName, v))
|
||||
}
|
||||
|
||||
// NameIn applies the In predicate on the "name" field.
|
||||
func NameIn(vs ...string) predicate.File {
|
||||
return predicate.File(sql.FieldIn(FieldName, vs...))
|
||||
}
|
||||
|
||||
// NameNotIn applies the NotIn predicate on the "name" field.
|
||||
func NameNotIn(vs ...string) predicate.File {
|
||||
return predicate.File(sql.FieldNotIn(FieldName, vs...))
|
||||
}
|
||||
|
||||
// NameGT applies the GT predicate on the "name" field.
|
||||
func NameGT(v string) predicate.File {
|
||||
return predicate.File(sql.FieldGT(FieldName, v))
|
||||
}
|
||||
|
||||
// NameGTE applies the GTE predicate on the "name" field.
|
||||
func NameGTE(v string) predicate.File {
|
||||
return predicate.File(sql.FieldGTE(FieldName, v))
|
||||
}
|
||||
|
||||
// NameLT applies the LT predicate on the "name" field.
|
||||
func NameLT(v string) predicate.File {
|
||||
return predicate.File(sql.FieldLT(FieldName, v))
|
||||
}
|
||||
|
||||
// NameLTE applies the LTE predicate on the "name" field.
|
||||
func NameLTE(v string) predicate.File {
|
||||
return predicate.File(sql.FieldLTE(FieldName, v))
|
||||
}
|
||||
|
||||
// NameContains applies the Contains predicate on the "name" field.
|
||||
func NameContains(v string) predicate.File {
|
||||
return predicate.File(sql.FieldContains(FieldName, v))
|
||||
}
|
||||
|
||||
// NameHasPrefix applies the HasPrefix predicate on the "name" field.
|
||||
func NameHasPrefix(v string) predicate.File {
|
||||
return predicate.File(sql.FieldHasPrefix(FieldName, v))
|
||||
}
|
||||
|
||||
// NameHasSuffix applies the HasSuffix predicate on the "name" field.
|
||||
func NameHasSuffix(v string) predicate.File {
|
||||
return predicate.File(sql.FieldHasSuffix(FieldName, v))
|
||||
}
|
||||
|
||||
// NameEqualFold applies the EqualFold predicate on the "name" field.
|
||||
func NameEqualFold(v string) predicate.File {
|
||||
return predicate.File(sql.FieldEqualFold(FieldName, v))
|
||||
}
|
||||
|
||||
// NameContainsFold applies the ContainsFold predicate on the "name" field.
|
||||
func NameContainsFold(v string) predicate.File {
|
||||
return predicate.File(sql.FieldContainsFold(FieldName, v))
|
||||
}
|
||||
|
||||
// OwnerIDEQ applies the EQ predicate on the "owner_id" field.
|
||||
func OwnerIDEQ(v int) predicate.File {
|
||||
return predicate.File(sql.FieldEQ(FieldOwnerID, v))
|
||||
}
|
||||
|
||||
// OwnerIDNEQ applies the NEQ predicate on the "owner_id" field.
|
||||
func OwnerIDNEQ(v int) predicate.File {
|
||||
return predicate.File(sql.FieldNEQ(FieldOwnerID, v))
|
||||
}
|
||||
|
||||
// OwnerIDIn applies the In predicate on the "owner_id" field.
|
||||
func OwnerIDIn(vs ...int) predicate.File {
|
||||
return predicate.File(sql.FieldIn(FieldOwnerID, vs...))
|
||||
}
|
||||
|
||||
// OwnerIDNotIn applies the NotIn predicate on the "owner_id" field.
|
||||
func OwnerIDNotIn(vs ...int) predicate.File {
|
||||
return predicate.File(sql.FieldNotIn(FieldOwnerID, vs...))
|
||||
}
|
||||
|
||||
// SizeEQ applies the EQ predicate on the "size" field.
|
||||
func SizeEQ(v int64) predicate.File {
|
||||
return predicate.File(sql.FieldEQ(FieldSize, v))
|
||||
}
|
||||
|
||||
// SizeNEQ applies the NEQ predicate on the "size" field.
|
||||
func SizeNEQ(v int64) predicate.File {
|
||||
return predicate.File(sql.FieldNEQ(FieldSize, v))
|
||||
}
|
||||
|
||||
// SizeIn applies the In predicate on the "size" field.
|
||||
func SizeIn(vs ...int64) predicate.File {
|
||||
return predicate.File(sql.FieldIn(FieldSize, vs...))
|
||||
}
|
||||
|
||||
// SizeNotIn applies the NotIn predicate on the "size" field.
|
||||
func SizeNotIn(vs ...int64) predicate.File {
|
||||
return predicate.File(sql.FieldNotIn(FieldSize, vs...))
|
||||
}
|
||||
|
||||
// SizeGT applies the GT predicate on the "size" field.
|
||||
func SizeGT(v int64) predicate.File {
|
||||
return predicate.File(sql.FieldGT(FieldSize, v))
|
||||
}
|
||||
|
||||
// SizeGTE applies the GTE predicate on the "size" field.
|
||||
func SizeGTE(v int64) predicate.File {
|
||||
return predicate.File(sql.FieldGTE(FieldSize, v))
|
||||
}
|
||||
|
||||
// SizeLT applies the LT predicate on the "size" field.
|
||||
func SizeLT(v int64) predicate.File {
|
||||
return predicate.File(sql.FieldLT(FieldSize, v))
|
||||
}
|
||||
|
||||
// SizeLTE applies the LTE predicate on the "size" field.
|
||||
func SizeLTE(v int64) predicate.File {
|
||||
return predicate.File(sql.FieldLTE(FieldSize, v))
|
||||
}
|
||||
|
||||
// PrimaryEntityEQ applies the EQ predicate on the "primary_entity" field.
|
||||
func PrimaryEntityEQ(v int) predicate.File {
|
||||
return predicate.File(sql.FieldEQ(FieldPrimaryEntity, v))
|
||||
}
|
||||
|
||||
// PrimaryEntityNEQ applies the NEQ predicate on the "primary_entity" field.
|
||||
func PrimaryEntityNEQ(v int) predicate.File {
|
||||
return predicate.File(sql.FieldNEQ(FieldPrimaryEntity, v))
|
||||
}
|
||||
|
||||
// PrimaryEntityIn applies the In predicate on the "primary_entity" field.
|
||||
func PrimaryEntityIn(vs ...int) predicate.File {
|
||||
return predicate.File(sql.FieldIn(FieldPrimaryEntity, vs...))
|
||||
}
|
||||
|
||||
// PrimaryEntityNotIn applies the NotIn predicate on the "primary_entity" field.
|
||||
func PrimaryEntityNotIn(vs ...int) predicate.File {
|
||||
return predicate.File(sql.FieldNotIn(FieldPrimaryEntity, vs...))
|
||||
}
|
||||
|
||||
// PrimaryEntityGT applies the GT predicate on the "primary_entity" field.
|
||||
func PrimaryEntityGT(v int) predicate.File {
|
||||
return predicate.File(sql.FieldGT(FieldPrimaryEntity, v))
|
||||
}
|
||||
|
||||
// PrimaryEntityGTE applies the GTE predicate on the "primary_entity" field.
|
||||
func PrimaryEntityGTE(v int) predicate.File {
|
||||
return predicate.File(sql.FieldGTE(FieldPrimaryEntity, v))
|
||||
}
|
||||
|
||||
// PrimaryEntityLT applies the LT predicate on the "primary_entity" field.
|
||||
func PrimaryEntityLT(v int) predicate.File {
|
||||
return predicate.File(sql.FieldLT(FieldPrimaryEntity, v))
|
||||
}
|
||||
|
||||
// PrimaryEntityLTE applies the LTE predicate on the "primary_entity" field.
|
||||
func PrimaryEntityLTE(v int) predicate.File {
|
||||
return predicate.File(sql.FieldLTE(FieldPrimaryEntity, v))
|
||||
}
|
||||
|
||||
// PrimaryEntityIsNil applies the IsNil predicate on the "primary_entity" field.
|
||||
func PrimaryEntityIsNil() predicate.File {
|
||||
return predicate.File(sql.FieldIsNull(FieldPrimaryEntity))
|
||||
}
|
||||
|
||||
// PrimaryEntityNotNil applies the NotNil predicate on the "primary_entity" field.
|
||||
func PrimaryEntityNotNil() predicate.File {
|
||||
return predicate.File(sql.FieldNotNull(FieldPrimaryEntity))
|
||||
}
|
||||
|
||||
// FileChildrenEQ applies the EQ predicate on the "file_children" field.
|
||||
func FileChildrenEQ(v int) predicate.File {
|
||||
return predicate.File(sql.FieldEQ(FieldFileChildren, v))
|
||||
}
|
||||
|
||||
// FileChildrenNEQ applies the NEQ predicate on the "file_children" field.
|
||||
func FileChildrenNEQ(v int) predicate.File {
|
||||
return predicate.File(sql.FieldNEQ(FieldFileChildren, v))
|
||||
}
|
||||
|
||||
// FileChildrenIn applies the In predicate on the "file_children" field.
|
||||
func FileChildrenIn(vs ...int) predicate.File {
|
||||
return predicate.File(sql.FieldIn(FieldFileChildren, vs...))
|
||||
}
|
||||
|
||||
// FileChildrenNotIn applies the NotIn predicate on the "file_children" field.
|
||||
func FileChildrenNotIn(vs ...int) predicate.File {
|
||||
return predicate.File(sql.FieldNotIn(FieldFileChildren, vs...))
|
||||
}
|
||||
|
||||
// FileChildrenIsNil applies the IsNil predicate on the "file_children" field.
|
||||
func FileChildrenIsNil() predicate.File {
|
||||
return predicate.File(sql.FieldIsNull(FieldFileChildren))
|
||||
}
|
||||
|
||||
// FileChildrenNotNil applies the NotNil predicate on the "file_children" field.
|
||||
func FileChildrenNotNil() predicate.File {
|
||||
return predicate.File(sql.FieldNotNull(FieldFileChildren))
|
||||
}
|
||||
|
||||
// IsSymbolicEQ applies the EQ predicate on the "is_symbolic" field.
|
||||
func IsSymbolicEQ(v bool) predicate.File {
|
||||
return predicate.File(sql.FieldEQ(FieldIsSymbolic, v))
|
||||
}
|
||||
|
||||
// IsSymbolicNEQ applies the NEQ predicate on the "is_symbolic" field.
|
||||
func IsSymbolicNEQ(v bool) predicate.File {
|
||||
return predicate.File(sql.FieldNEQ(FieldIsSymbolic, v))
|
||||
}
|
||||
|
||||
// PropsIsNil applies the IsNil predicate on the "props" field.
|
||||
func PropsIsNil() predicate.File {
|
||||
return predicate.File(sql.FieldIsNull(FieldProps))
|
||||
}
|
||||
|
||||
// PropsNotNil applies the NotNil predicate on the "props" field.
|
||||
func PropsNotNil() predicate.File {
|
||||
return predicate.File(sql.FieldNotNull(FieldProps))
|
||||
}
|
||||
|
||||
// StoragePolicyFilesEQ applies the EQ predicate on the "storage_policy_files" field.
|
||||
func StoragePolicyFilesEQ(v int) predicate.File {
|
||||
return predicate.File(sql.FieldEQ(FieldStoragePolicyFiles, v))
|
||||
}
|
||||
|
||||
// StoragePolicyFilesNEQ applies the NEQ predicate on the "storage_policy_files" field.
|
||||
func StoragePolicyFilesNEQ(v int) predicate.File {
|
||||
return predicate.File(sql.FieldNEQ(FieldStoragePolicyFiles, v))
|
||||
}
|
||||
|
||||
// StoragePolicyFilesIn applies the In predicate on the "storage_policy_files" field.
|
||||
func StoragePolicyFilesIn(vs ...int) predicate.File {
|
||||
return predicate.File(sql.FieldIn(FieldStoragePolicyFiles, vs...))
|
||||
}
|
||||
|
||||
// StoragePolicyFilesNotIn applies the NotIn predicate on the "storage_policy_files" field.
|
||||
func StoragePolicyFilesNotIn(vs ...int) predicate.File {
|
||||
return predicate.File(sql.FieldNotIn(FieldStoragePolicyFiles, vs...))
|
||||
}
|
||||
|
||||
// StoragePolicyFilesIsNil applies the IsNil predicate on the "storage_policy_files" field.
|
||||
func StoragePolicyFilesIsNil() predicate.File {
|
||||
return predicate.File(sql.FieldIsNull(FieldStoragePolicyFiles))
|
||||
}
|
||||
|
||||
// StoragePolicyFilesNotNil applies the NotNil predicate on the "storage_policy_files" field.
|
||||
func StoragePolicyFilesNotNil() predicate.File {
|
||||
return predicate.File(sql.FieldNotNull(FieldStoragePolicyFiles))
|
||||
}
|
||||
|
||||
// HasOwner applies the HasEdge predicate on the "owner" edge.
|
||||
func HasOwner() predicate.File {
|
||||
return predicate.File(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, OwnerTable, OwnerColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasOwnerWith applies the HasEdge predicate on the "owner" edge with a given conditions (other predicates).
|
||||
func HasOwnerWith(preds ...predicate.User) predicate.File {
|
||||
return predicate.File(func(s *sql.Selector) {
|
||||
step := newOwnerStep()
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// HasStoragePolicies applies the HasEdge predicate on the "storage_policies" edge.
|
||||
func HasStoragePolicies() predicate.File {
|
||||
return predicate.File(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, StoragePoliciesTable, StoragePoliciesColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasStoragePoliciesWith applies the HasEdge predicate on the "storage_policies" edge with a given conditions (other predicates).
|
||||
func HasStoragePoliciesWith(preds ...predicate.StoragePolicy) predicate.File {
|
||||
return predicate.File(func(s *sql.Selector) {
|
||||
step := newStoragePoliciesStep()
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// HasParent applies the HasEdge predicate on the "parent" edge.
|
||||
func HasParent() predicate.File {
|
||||
return predicate.File(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, ParentTable, ParentColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasParentWith applies the HasEdge predicate on the "parent" edge with a given conditions (other predicates).
|
||||
func HasParentWith(preds ...predicate.File) predicate.File {
|
||||
return predicate.File(func(s *sql.Selector) {
|
||||
step := newParentStep()
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// HasChildren applies the HasEdge predicate on the "children" edge.
|
||||
func HasChildren() predicate.File {
|
||||
return predicate.File(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, ChildrenTable, ChildrenColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasChildrenWith applies the HasEdge predicate on the "children" edge with a given conditions (other predicates).
|
||||
func HasChildrenWith(preds ...predicate.File) predicate.File {
|
||||
return predicate.File(func(s *sql.Selector) {
|
||||
step := newChildrenStep()
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// HasMetadata applies the HasEdge predicate on the "metadata" edge.
|
||||
func HasMetadata() predicate.File {
|
||||
return predicate.File(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, MetadataTable, MetadataColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasMetadataWith applies the HasEdge predicate on the "metadata" edge with a given conditions (other predicates).
|
||||
func HasMetadataWith(preds ...predicate.Metadata) predicate.File {
|
||||
return predicate.File(func(s *sql.Selector) {
|
||||
step := newMetadataStep()
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// HasEntities applies the HasEdge predicate on the "entities" edge.
|
||||
func HasEntities() predicate.File {
|
||||
return predicate.File(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2M, false, EntitiesTable, EntitiesPrimaryKey...),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasEntitiesWith applies the HasEdge predicate on the "entities" edge with a given conditions (other predicates).
|
||||
func HasEntitiesWith(preds ...predicate.Entity) predicate.File {
|
||||
return predicate.File(func(s *sql.Selector) {
|
||||
step := newEntitiesStep()
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// HasShares applies the HasEdge predicate on the "shares" edge.
|
||||
func HasShares() predicate.File {
|
||||
return predicate.File(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, SharesTable, SharesColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasSharesWith applies the HasEdge predicate on the "shares" edge with a given conditions (other predicates).
|
||||
func HasSharesWith(preds ...predicate.Share) predicate.File {
|
||||
return predicate.File(func(s *sql.Selector) {
|
||||
step := newSharesStep()
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// HasDirectLinks applies the HasEdge predicate on the "direct_links" edge.
|
||||
func HasDirectLinks() predicate.File {
|
||||
return predicate.File(func(s *sql.Selector) {
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, DirectLinksTable, DirectLinksColumn),
|
||||
)
|
||||
sqlgraph.HasNeighbors(s, step)
|
||||
})
|
||||
}
|
||||
|
||||
// HasDirectLinksWith applies the HasEdge predicate on the "direct_links" edge with a given conditions (other predicates).
|
||||
func HasDirectLinksWith(preds ...predicate.DirectLink) predicate.File {
|
||||
return predicate.File(func(s *sql.Selector) {
|
||||
step := newDirectLinksStep()
|
||||
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.File) predicate.File {
|
||||
return predicate.File(sql.AndPredicates(predicates...))
|
||||
}
|
||||
|
||||
// Or groups predicates with the OR operator between them.
|
||||
func Or(predicates ...predicate.File) predicate.File {
|
||||
return predicate.File(sql.OrPredicates(predicates...))
|
||||
}
|
||||
|
||||
// Not applies the not operator on the given predicate.
|
||||
func Not(p predicate.File) predicate.File {
|
||||
return predicate.File(sql.NotPredicates(p))
|
||||
}
|
||||
1431
ent/file_create.go
Normal file
1431
ent/file_create.go
Normal file
File diff suppressed because it is too large
Load Diff
88
ent/file_delete.go
Normal file
88
ent/file_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/cloudreve/Cloudreve/v4/ent/file"
|
||||
"github.com/cloudreve/Cloudreve/v4/ent/predicate"
|
||||
)
|
||||
|
||||
// FileDelete is the builder for deleting a File entity.
|
||||
type FileDelete struct {
|
||||
config
|
||||
hooks []Hook
|
||||
mutation *FileMutation
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the FileDelete builder.
|
||||
func (fd *FileDelete) Where(ps ...predicate.File) *FileDelete {
|
||||
fd.mutation.Where(ps...)
|
||||
return fd
|
||||
}
|
||||
|
||||
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||
func (fd *FileDelete) Exec(ctx context.Context) (int, error) {
|
||||
return withHooks(ctx, fd.sqlExec, fd.mutation, fd.hooks)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (fd *FileDelete) ExecX(ctx context.Context) int {
|
||||
n, err := fd.Exec(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (fd *FileDelete) sqlExec(ctx context.Context) (int, error) {
|
||||
_spec := sqlgraph.NewDeleteSpec(file.Table, sqlgraph.NewFieldSpec(file.FieldID, field.TypeInt))
|
||||
if ps := fd.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
affected, err := sqlgraph.DeleteNodes(ctx, fd.driver, _spec)
|
||||
if err != nil && sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
fd.mutation.done = true
|
||||
return affected, err
|
||||
}
|
||||
|
||||
// FileDeleteOne is the builder for deleting a single File entity.
|
||||
type FileDeleteOne struct {
|
||||
fd *FileDelete
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the FileDelete builder.
|
||||
func (fdo *FileDeleteOne) Where(ps ...predicate.File) *FileDeleteOne {
|
||||
fdo.fd.mutation.Where(ps...)
|
||||
return fdo
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (fdo *FileDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := fdo.fd.Exec(ctx)
|
||||
switch {
|
||||
case err != nil:
|
||||
return err
|
||||
case n == 0:
|
||||
return &NotFoundError{file.Label}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (fdo *FileDeleteOne) ExecX(ctx context.Context) {
|
||||
if err := fdo.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
1156
ent/file_query.go
Normal file
1156
ent/file_query.go
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user