mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-14 20:12:39 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41cec0db05 | ||
|
|
fa1641f05f | ||
|
|
252ef8b73a | ||
|
|
53004e2e90 | ||
|
|
11ed22d052 | ||
|
|
03646e9434 | ||
|
|
2e9b8d9a64 | ||
|
|
2f715baf05 | ||
|
|
ff639ba757 | ||
|
|
16d1fbfd4e | ||
|
|
d2d3fcf57b | ||
|
|
0a64a6d8ce | ||
|
|
d8a07e91a5 | ||
|
|
a1b5c75ca3 | ||
|
|
69bc6a87dd | ||
|
|
c361b0606d | ||
|
|
ac7a141a24 | ||
|
|
527279c953 | ||
|
|
9717699367 | ||
|
|
2590b86e31 | ||
|
|
24d908b257 | ||
|
|
9c3c560d49 | ||
|
|
8711882918 | ||
|
|
27fcbace89 | ||
|
|
30d4301bea | ||
|
|
5d1c577cb2 | ||
|
|
d41a10111d | ||
|
|
93f2ccf3a5 | ||
|
|
a8927d8ec7 | ||
|
|
623a9647c0 | ||
|
|
41c71a1528 | ||
|
|
1847bdf9fd | ||
|
|
7358810659 | ||
|
|
029e5ce9f9 | ||
|
|
8cd848313c | ||
|
|
9033e14bb7 | ||
|
|
8f328d4ab3 | ||
|
|
74e78c3de0 | ||
|
|
002c0b9fda | ||
|
|
f2ca16577e | ||
|
|
6c441637b0 | ||
|
|
0f2ec134b5 | ||
|
|
2c2e50ba58 | ||
|
|
966afd1b4b | ||
|
|
54d228dda5 | ||
|
|
ad4bf5c60d | ||
|
|
e9fb5983cd | ||
|
|
98027cdded | ||
|
|
831862b924 | ||
|
|
a0778e9a42 | ||
|
|
3c68b2e369 | ||
|
|
c896cacf6d | ||
|
|
ed31a52424 | ||
|
|
f63d168ae0 | ||
|
|
3e4d48e010 | ||
|
|
40ec74b9fc | ||
|
|
a0ac5e0240 | ||
|
|
8d5bc448b5 | ||
|
|
7d239d62e8 | ||
|
|
adb5106c1f | ||
|
|
bb73416733 | ||
|
|
55ed0ab0da | ||
|
|
5aeb03018c | ||
|
|
a2bc133747 | ||
|
|
540e90ca8b | ||
|
|
4bc7486c3b | ||
|
|
664b7be30f | ||
|
|
c8cfc93632 | ||
|
|
b4aa3eb023 | ||
|
|
0465540195 | ||
|
|
b0d0de0547 | ||
|
|
bc5d6ecb46 | ||
|
|
03ccb2a08e | ||
|
|
551e2570dd | ||
|
|
8315defe8e | ||
|
|
fc9b489106 | ||
|
|
d774948e09 | ||
|
|
baab0adf7c | ||
|
|
a60a282473 | ||
|
|
317de9c04b | ||
|
|
b8dcae3bcf | ||
|
|
fbc3f42a22 | ||
|
|
98cc641008 | ||
|
|
daf0b99dcb | ||
|
|
90bff0ea17 | ||
|
|
d8fa425a27 | ||
|
|
50e5372fed | ||
|
|
c7c933776d | ||
|
|
1d86c1bf81 | ||
|
|
b6427d4ec0 | ||
|
|
b0fa2b352f | ||
|
|
54a8606e2a | ||
|
|
a7ddca8930 | ||
|
|
a5d40c9845 | ||
|
|
b0441ca5aa | ||
|
|
3605a316af | ||
|
|
1e97e4cee4 | ||
|
|
0d9c140bc2 | ||
|
|
a1930ea6f2 | ||
|
|
909b96edd2 | ||
|
|
83c10133d1 | ||
|
|
b73d8c3efe | ||
|
|
0d318195bf | ||
|
|
e5af699d0f | ||
|
|
f73031f436 | ||
|
|
64a2a31729 | ||
|
|
8a22dc7347 | ||
|
|
aeb34d2003 | ||
|
|
c4ff604e93 | ||
|
|
ce3f12bbff | ||
|
|
f187f08ae3 | ||
|
|
cbddb57dec | ||
|
|
3375b4ed2b | ||
|
|
d9e466ad3a | ||
|
|
ad18ee7c4f | ||
|
|
038b25c0b1 | ||
|
|
139f79b85a | ||
|
|
7cbb36f278 | ||
|
|
92dcfb5ebc | ||
|
|
42f3c22830 | ||
|
|
8d51364c3d | ||
|
|
33b1d772f7 | ||
|
|
1c214eaca4 | ||
|
|
841481e051 | ||
|
|
2f4478fd32 | ||
|
|
877bee84a1 | ||
|
|
d734dbdac4 | ||
|
|
05865d9b65 | ||
|
|
0dce07ee8b | ||
|
|
b6bb74b6fa | ||
|
|
7050070aa3 | ||
|
|
ff5c216189 | ||
|
|
fe184f8c33 | ||
|
|
73ffd13430 | ||
|
|
f57d06d959 | ||
|
|
1a8401f5f3 | ||
|
|
06af8115f7 | ||
|
|
5015b7a1c1 | ||
|
|
d5b47c2142 | ||
|
|
1dedb2097d | ||
|
|
52071d391b | ||
|
|
0478fd3668 | ||
|
|
c56a64fabd | ||
|
|
1c02158c2a | ||
|
|
80b7a8d4cb | ||
|
|
94a22b62f7 | ||
|
|
51de58b37f | ||
|
|
84bb7d0709 | ||
|
|
6e2bb31281 | ||
|
|
4d4ba64bf7 | ||
|
|
0464856c4a | ||
|
|
e316ebf528 | ||
|
|
07fac34713 | ||
|
|
151b9265fc | ||
|
|
6c588bb950 | ||
|
|
90e9d03dec | ||
|
|
e2b68d1f90 | ||
|
|
a2cdaa6419 | ||
|
|
bc3cb29027 | ||
|
|
89a551b964 | ||
|
|
83f169e4fa | ||
|
|
eb4d005031 | ||
|
|
0d28f7f90d | ||
|
|
deff3123de | ||
|
|
8a51119e39 | ||
|
|
f1082bb78f | ||
|
|
7942338328 | ||
|
|
5260a42a0b | ||
|
|
815516d8d3 | ||
|
|
5a0dd510e5 | ||
|
|
0fa1eb85ec | ||
|
|
6dd3274aaf | ||
|
|
d0f6f27d5f | ||
|
|
6a2063b374 | ||
|
|
f2966530c5 | ||
|
|
de28eba3c8 | ||
|
|
d3a1835ed7 | ||
|
|
a495d5e302 | ||
|
|
9a2f11b4e2 | ||
|
|
0dec1ad292 | ||
|
|
8b96acde97 | ||
|
|
5c9748cef9 | ||
|
|
312ab1f0bd | ||
|
|
ea9f40b63f | ||
|
|
b9b013a088 | ||
|
|
dda8f78733 | ||
|
|
ddb1a210ce | ||
|
|
301c99a26c | ||
|
|
c3ae5fc3c5 | ||
|
|
cddcf49044 | ||
|
|
9389503c56 | ||
|
|
72ef0b3884 | ||
|
|
fc66a30ffc | ||
|
|
e984b4e2e1 | ||
|
|
066a85949a | ||
|
|
3099362074 | ||
|
|
80b3d4c1f8 | ||
|
|
000f6dc655 | ||
|
|
5c15d32ff7 | ||
|
|
ae9a01d852 | ||
|
|
0a5f34a2ef | ||
|
|
062af81fb5 | ||
|
|
2cffe1cf5f | ||
|
|
657c4f97d9 | ||
|
|
383f61d0e9 | ||
|
|
18e26c127c | ||
|
|
4a2b10c94e | ||
|
|
99da308196 | ||
|
|
12d811bd76 | ||
|
|
ad8afc8a2e | ||
|
|
dd1a116f48 | ||
|
|
2e61914c48 | ||
|
|
92b283d9eb | ||
|
|
1c2e6503c6 | ||
|
|
16c0613b21 | ||
|
|
1a3cc2a787 | ||
|
|
e2c731abe4 | ||
|
|
7918b1a9c5 | ||
|
|
10102807e2 | ||
|
|
751cf5eea3 | ||
|
|
a8505877ff | ||
|
|
f3380dbd62 | ||
|
|
feef0bc0b1 | ||
|
|
0ee51b45f8 | ||
|
|
8f97953e51 | ||
|
|
b062b36646 | ||
|
|
64fdc11ec4 | ||
|
|
1da3501af5 | ||
|
|
1a0a6ea9a8 | ||
|
|
b480545c19 | ||
|
|
ba1f130d28 | ||
|
|
668c79ea86 | ||
|
|
15c59be787 | ||
|
|
49fb18e073 | ||
|
|
14f7a7e603 | ||
|
|
104fd2b6ec | ||
|
|
0438057c0b | ||
|
|
addcb34e14 | ||
|
|
843dcddea3 | ||
|
|
c842c3166c | ||
|
|
c3df469377 | ||
|
|
243678e166 | ||
|
|
7468427e44 | ||
|
|
d4952154ff | ||
|
|
1785509873 | ||
|
|
9ba0fb3084 | ||
|
|
b6d2df24d8 | ||
|
|
52da41fd6e | ||
|
|
dfff28ab05 | ||
|
|
e2c662e965 | ||
|
|
9392d1fc43 | ||
|
|
9ba6f3c2b0 | ||
|
|
a57157b9fa | ||
|
|
0118fa3ce2 | ||
|
|
105ac31c37 | ||
|
|
7302be4d13 | ||
|
|
636c452535 | ||
|
|
cccba9a82e | ||
|
|
554d47d04a | ||
|
|
25a7169601 | ||
|
|
54859022aa | ||
|
|
53a5c45bd8 | ||
|
|
bfb827b879 | ||
|
|
4e5be8f75e | ||
|
|
29a5fcd25e | ||
|
|
309fda2904 | ||
|
|
88581912ba | ||
|
|
f029945cfc | ||
|
|
4a30397623 | ||
|
|
5debe1db33 | ||
|
|
7a11b39d6d | ||
|
|
e0d149d511 | ||
|
|
3b206cc639 | ||
|
|
889b657451 | ||
|
|
376e03ded1 | ||
|
|
4d702e3234 | ||
|
|
890cc2bb98 | ||
|
|
5aba53d542 | ||
|
|
6f43986c37 | ||
|
|
f407d6a044 | ||
|
|
a56eb5b4dc | ||
|
|
a855317624 | ||
|
|
f4e8bec54c | ||
|
|
6631cbad67 | ||
|
|
d0bcaa8b09 | ||
|
|
bb5d2e84a1 | ||
|
|
f013bc1141 | ||
|
|
2a4c28e8f5 | ||
|
|
d0f669338b | ||
|
|
db3bd9971e | ||
|
|
4d23ad4bac | ||
|
|
50043b1176 | ||
|
|
084d26cbd2 | ||
|
|
d9e514f982 | ||
|
|
317339e716 | ||
|
|
a4f942d8a9 | ||
|
|
6ae5fc31b3 | ||
|
|
3866da508f | ||
|
|
e8e234252a | ||
|
|
d754be0d8e | ||
|
|
2dd2be9922 | ||
|
|
a86c534cb0 | ||
|
|
c7e44a83ad | ||
|
|
f68f3b86c6 | ||
|
|
dad92488e5 | ||
|
|
4bcb13f77f | ||
|
|
9643382bd3 | ||
|
|
af4b75a77c | ||
|
|
c7249a54ac | ||
|
|
65ff800362 | ||
|
|
b5604afd3d | ||
|
|
2fd3539527 | ||
|
|
13e773ef5e | ||
|
|
27e29f0562 | ||
|
|
80a229bce5 | ||
|
|
69d02d2036 | ||
|
|
5c0e580fbe | ||
|
|
a02700c16f | ||
|
|
3b2099350e | ||
|
|
44ab690a01 | ||
|
|
75fb3c41c2 | ||
|
|
17d991786b | ||
|
|
c10ae9f9d2 | ||
|
|
fd64d07e61 | ||
|
|
17b6481f8b | ||
|
|
e979990bf9 | ||
|
|
156e17335f | ||
|
|
a6023840f7 | ||
|
|
b5b0ea3460 | ||
|
|
fa01aec80d | ||
|
|
87bdaf8e60 | ||
|
|
a98397adbb | ||
|
|
aff87d9497 | ||
|
|
9b75c7b76c | ||
|
|
571e0b8132 | ||
|
|
2a3dcb499f | ||
|
|
40c563c4ae | ||
|
|
867616fca8 | ||
|
|
438f17be5e | ||
|
|
83d7b0e440 | ||
|
|
9d5f1b73ad | ||
|
|
c34db70a88 | ||
|
|
5494261902 | ||
|
|
aff148167c | ||
|
|
d7a6a4513a | ||
|
|
baadb22682 | ||
|
|
863953321e | ||
|
|
ddd63a8402 | ||
|
|
75e3089496 | ||
|
|
2fb212b7d6 | ||
|
|
7650cce5a4 | ||
|
|
db9d92ba8f | ||
|
|
7c8e13208b | ||
|
|
d37d216f9d | ||
|
|
96f3697ecb | ||
|
|
42ecbeb8c6 | ||
|
|
a564051f83 | ||
|
|
a862eac1d8 | ||
|
|
913d838770 | ||
|
|
3828a48752 | ||
|
|
77b1a0452e | ||
|
|
26b51ccfd3 | ||
|
|
89edba8028 | ||
|
|
3c43fdec11 | ||
|
|
1b07fe821a | ||
|
|
7c2a828c56 | ||
|
|
67e945f8e8 | ||
|
|
cb151e36eb | ||
|
|
5089c303e1 | ||
|
|
31b6e0d94a | ||
|
|
ec7b20649e | ||
|
|
1c0ccb477a | ||
|
|
4b321142bb | ||
|
|
de31e57333 | ||
|
|
95717a7e62 | ||
|
|
6b4c3c6ed1 | ||
|
|
a23a263513 | ||
|
|
f881ff7cb0 | ||
|
|
6cea1c35bb | ||
|
|
a42e9e3fc8 | ||
|
|
d1d3400b69 | ||
|
|
76bb7b0338 | ||
|
|
3fa08aa930 | ||
|
|
0b729496ee | ||
|
|
616cf17d9e | ||
|
|
27cb485d55 | ||
|
|
22ec77b570 | ||
|
|
b197ba61ce | ||
|
|
a5a2fea045 | ||
|
|
0dc6e56aae | ||
|
|
bf76168ba5 | ||
|
|
2854ab2ace | ||
|
|
e95c909ee5 | ||
|
|
ba1bb0a3d3 | ||
|
|
11fd61458c | ||
|
|
d56e94b875 | ||
|
|
d73fa8eab2 | ||
|
|
d089c5789c | ||
|
|
202c6989a1 | ||
|
|
9fac6f15ce | ||
|
|
9703ca9d33 | ||
|
|
d8e96f0f97 | ||
|
|
a3c5cc4578 | ||
|
|
5553d83605 | ||
|
|
8fab636998 | ||
|
|
e2326a7998 | ||
|
|
0fd2e9216d | ||
|
|
759332aa92 | ||
|
|
b408edf97b | ||
|
|
f0f1f59a44 | ||
|
|
ac68d73f0c | ||
|
|
2e70ec0a15 | ||
|
|
de15f29d1f | ||
|
|
809e1cf8ee | ||
|
|
c9dda3c01f | ||
|
|
6752cdc826 | ||
|
|
ee90246aa5 | ||
|
|
2d2b6f0325 | ||
|
|
83455a3fee | ||
|
|
728bb1bc9d | ||
|
|
f26ca5661e | ||
|
|
5fcbe7e307 | ||
|
|
aee9a7ba98 | ||
|
|
41cdd438d7 | ||
|
|
b23475ac0c | ||
|
|
e76e0499d7 | ||
|
|
cbfeab964e | ||
|
|
498f010ec3 | ||
|
|
20008264fe | ||
|
|
b650bdd68d | ||
|
|
41def4ba03 | ||
|
|
707b87a96f | ||
|
|
cbe0c4665f | ||
|
|
dec709fb3a | ||
|
|
4dd3aee5c2 | ||
|
|
6bd248fd1f | ||
|
|
be297b90ce | ||
|
|
dfdb838ce4 | ||
|
|
be3aee1a4b | ||
|
|
588e02b29e | ||
|
|
659086861d | ||
|
|
0c53d4f334 | ||
|
|
8e07ec55db | ||
|
|
129d05258a | ||
|
|
46ef146225 | ||
|
|
35df02aeac | ||
|
|
b3f796972e | ||
|
|
a994fbd77a | ||
|
|
e5dc1f5972 | ||
|
|
df2cedeead | ||
|
|
ebbdc70311 | ||
|
|
f385cdceb7 | ||
|
|
2649573b99 | ||
|
|
a1b2b32e08 | ||
|
|
f3a3a0869d | ||
|
|
b2687b2258 | ||
|
|
28c2d20d9f | ||
|
|
c620ad6a36 | ||
|
|
d0a1443a41 | ||
|
|
2b462b07de | ||
|
|
87dfc66132 | ||
|
|
5d7f213cbf | ||
|
|
36d5f4e4ca | ||
|
|
a5638a4e54 | ||
|
|
72ccd1b111 | ||
|
|
3f2ef60468 | ||
|
|
372436323a | ||
|
|
0b8e5eec32 | ||
|
|
9caa3c9c5e | ||
|
|
3020652fa1 | ||
|
|
537bd50469 | ||
|
|
6bc6998b0e | ||
|
|
4e23c77ece | ||
|
|
821399ade1 | ||
|
|
441b8ec2e2 | ||
|
|
fafdd8342f | ||
|
|
50dff6762c | ||
|
|
e63492090a | ||
|
|
51b5142af7 | ||
|
|
634b0eee48 | ||
|
|
fd66ae1ecb | ||
|
|
a32196eedd | ||
|
|
3302146759 | ||
|
|
41af8e8e11 | ||
|
|
fa70a7217c | ||
|
|
11a3da65c0 | ||
|
|
089a7b7fae | ||
|
|
99a8d8ad28 | ||
|
|
5436d0bf10 | ||
|
|
a632cb0050 | ||
|
|
df59b8b966 | ||
|
|
d0b8760eb9 | ||
|
|
5fe4ee1da1 | ||
|
|
dfb36e45f1 | ||
|
|
c4128580f2 | ||
|
|
c797159bf5 | ||
|
|
7869b7fe38 | ||
|
|
a5781fe31d | ||
|
|
b26dcc3da2 | ||
|
|
0ff93aca7a | ||
|
|
9934bd2572 | ||
|
|
0435417f43 | ||
|
|
7dc7cfce1d | ||
|
|
98be187d56 | ||
|
|
e236bff1ed | ||
|
|
45be32b254 | ||
|
|
60da9ba178 | ||
|
|
be26e6ff2c | ||
|
|
f5b2961270 | ||
|
|
a0eaf12a01 | ||
|
|
5eb9da9c93 | ||
|
|
5e99561d6e | ||
|
|
1034f576d7 | ||
|
|
71c16b7230 | ||
|
|
aac3261c69 | ||
|
|
f77cf6b477 | ||
|
|
8c2d9b9a12 | ||
|
|
c9fb221a31 | ||
|
|
0a9146c3d1 | ||
|
|
42e471f59a | ||
|
|
a34d4967e6 | ||
|
|
d679ee3c29 | ||
|
|
ebd83dc0f9 | ||
|
|
fd004bdd88 | ||
|
|
e998f8044b | ||
|
|
de64b02612 | ||
|
|
3812e627a8 | ||
|
|
8b46994dc2 | ||
|
|
9817d5d5bf | ||
|
|
5e9529bb88 | ||
|
|
96c9166b0e | ||
|
|
bdf7ead157 | ||
|
|
e28b11ad75 | ||
|
|
c3e860607d | ||
|
|
2fe756e4be | ||
|
|
3b5d812f7a | ||
|
|
5f62625ae6 | ||
|
|
605b6f6632 | ||
|
|
db0414233c | ||
|
|
e2d21c35af | ||
|
|
59e9356c51 | ||
|
|
c1335bae12 | ||
|
|
b28a223337 | ||
|
|
03727ac363 | ||
|
|
1158cf31bc | ||
|
|
41bb15d302 | ||
|
|
b4f38b092f | ||
|
|
73de2ea7f0 | ||
|
|
6e54776509 | ||
|
|
dc1bc15457 | ||
|
|
7cb98e5bdc | ||
|
|
930326116e | ||
|
|
cafc95c3e2 | ||
|
|
89b2d63ef2 | ||
|
|
915c60b150 | ||
|
|
345d5c6b56 | ||
|
|
6c46c2cb7d | ||
|
|
76e0d90736 | ||
|
|
56ca027a0f | ||
|
|
bf4f006736 | ||
|
|
185f9c9920 | ||
|
|
dcd8689d78 | ||
|
|
efb8b45876 | ||
|
|
ac6d4ccf09 | ||
|
|
ac6f2e9693 | ||
|
|
906be3f742 | ||
|
|
5654321380 | ||
|
|
0476b5c97a | ||
|
|
e70e36e4d2 | ||
|
|
901958ba1b | ||
|
|
93a3bf3077 | ||
|
|
7316d83027 | ||
|
|
55902d8548 | ||
|
|
260fda19b3 | ||
|
|
a0a3d0c33e | ||
|
|
438510d298 | ||
|
|
10e623f674 | ||
|
|
4a7148e203 | ||
|
|
d3acd8e96e | ||
|
|
7cbf82ed65 | ||
|
|
709cf61853 | ||
|
|
d86e83259e | ||
|
|
c99112a9e9 | ||
|
|
a22b12677f | ||
|
|
b0dbc22fe5 | ||
|
|
7c857bd080 | ||
|
|
bebafe7697 | ||
|
|
fc1e5a94a9 | ||
|
|
61f735a667 | ||
|
|
b105cc0fd5 | ||
|
|
38577c6ca0 | ||
|
|
47598462f5 | ||
|
|
753c5e255c | ||
|
|
3b18d1fa3d | ||
|
|
a822972d80 | ||
|
|
82553c4dca | ||
|
|
da810c3b43 | ||
|
|
b1403e8b29 | ||
|
|
b244f850e7 | ||
|
|
bad87ff533 | ||
|
|
88ca0c1d13 | ||
|
|
e5f7836bf3 | ||
|
|
7a38c66214 | ||
|
|
c275422251 | ||
|
|
98feeccbe1 | ||
|
|
815bc6c9b5 | ||
|
|
2a58a57a7c | ||
|
|
5bd9368ab4 | ||
|
|
a2cf297d90 | ||
|
|
6239e395b8 | ||
|
|
7c2fee6c99 | ||
|
|
df51edfb06 | ||
|
|
6bf6722bae | ||
|
|
0da1fe28ef |
@@ -5,14 +5,14 @@ exceptions:
|
||||
severity: high
|
||||
reason: "Admin export only; switched to dynamic import to reduce exposure (CVE-2023-30533)"
|
||||
mitigation: "Load only on export; restrict export permissions and data scope"
|
||||
expires_on: "2026-07-06"
|
||||
expires_on: "2026-10-06"
|
||||
owner: "security@your-domain"
|
||||
- package: xlsx
|
||||
advisory: "GHSA-5pgg-2g8v-p4x9"
|
||||
severity: high
|
||||
reason: "Admin export only; switched to dynamic import to reduce exposure (CVE-2024-22363)"
|
||||
mitigation: "Load only on export; restrict export permissions and data scope"
|
||||
expires_on: "2026-07-06"
|
||||
expires_on: "2026-10-06"
|
||||
owner: "security@your-domain"
|
||||
- package: lodash
|
||||
advisory: "GHSA-r5fr-rjxr-66jc"
|
||||
|
||||
@@ -8,6 +8,15 @@ permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
shell:
|
||||
runs-on: macos-15
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- name: Check deployment scripts
|
||||
run: |
|
||||
/bin/bash -n deploy/apple-container.sh
|
||||
/bin/bash deploy/tests/apple-container-test.sh
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -20,7 +29,7 @@ jobs:
|
||||
cache-dependency-path: backend/go.sum
|
||||
- name: Verify Go version
|
||||
run: |
|
||||
go version | grep -q 'go1.26.4'
|
||||
go version | grep -q 'go1.26.5'
|
||||
- name: Unit tests
|
||||
working-directory: backend
|
||||
run: make test-unit
|
||||
@@ -60,7 +69,7 @@ jobs:
|
||||
cache-dependency-path: backend/go.sum
|
||||
- name: Verify Go version
|
||||
run: |
|
||||
go version | grep -q 'go1.26.4'
|
||||
go version | grep -q 'go1.26.5'
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v9
|
||||
with:
|
||||
|
||||
@@ -115,7 +115,7 @@ jobs:
|
||||
|
||||
- name: Verify Go version
|
||||
run: |
|
||||
go version | grep -q 'go1.26.4'
|
||||
go version | grep -q 'go1.26.5'
|
||||
|
||||
# Docker setup for GoReleaser
|
||||
- name: Set up QEMU
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
cache-dependency-path: backend/go.sum
|
||||
- name: Verify Go version
|
||||
run: |
|
||||
go version | grep -q 'go1.26.4'
|
||||
go version | grep -q 'go1.26.5'
|
||||
- name: Run govulncheck
|
||||
working-directory: backend
|
||||
run: |
|
||||
|
||||
@@ -116,9 +116,13 @@ backend/.installed
|
||||
# 其他
|
||||
# ===================
|
||||
tests
|
||||
!deploy/tests/
|
||||
!deploy/tests/**
|
||||
CLAUDE.md
|
||||
.claude
|
||||
scripts
|
||||
!backend/scripts/
|
||||
!backend/scripts/resolve-version.sh
|
||||
.code-review-state
|
||||
#openspec/
|
||||
code-reviews/
|
||||
|
||||
+9
-4
@@ -1,3 +1,4 @@
|
||||
# syntax=docker/dockerfile:1.7
|
||||
# =============================================================================
|
||||
# Sub2API Multi-Stage Dockerfile
|
||||
# =============================================================================
|
||||
@@ -7,16 +8,18 @@
|
||||
# =============================================================================
|
||||
|
||||
ARG NODE_IMAGE=node:24-alpine
|
||||
ARG GOLANG_IMAGE=golang:1.26.4-alpine
|
||||
ARG GOLANG_IMAGE=golang:1.26.5-alpine
|
||||
ARG ALPINE_IMAGE=alpine:3.21
|
||||
ARG POSTGRES_IMAGE=postgres:18-alpine
|
||||
ARG GOPROXY=https://goproxy.cn,direct
|
||||
ARG GOSUMDB=sum.golang.google.cn
|
||||
ARG NPM_CONFIG_REGISTRY=
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Stage 1: Frontend Builder
|
||||
# -----------------------------------------------------------------------------
|
||||
FROM ${NODE_IMAGE} AS frontend-builder
|
||||
ARG NPM_CONFIG_REGISTRY
|
||||
|
||||
WORKDIR /app/frontend
|
||||
|
||||
@@ -25,7 +28,9 @@ RUN corepack enable && corepack prepare pnpm@9 --activate
|
||||
|
||||
# Install dependencies first (better caching)
|
||||
COPY frontend/package.json frontend/pnpm-lock.yaml ./
|
||||
RUN pnpm install --frozen-lockfile
|
||||
RUN --mount=type=cache,id=sub2api-pnpm-store,target=/root/.local/share/pnpm/store \
|
||||
if [ -n "${NPM_CONFIG_REGISTRY}" ]; then pnpm config set registry "${NPM_CONFIG_REGISTRY}"; fi && \
|
||||
pnpm install --frozen-lockfile --prefer-offline
|
||||
|
||||
# Copy frontend source and build.
|
||||
# LegalDocumentView.vue (admin-compliance gate) build-time imports
|
||||
@@ -67,9 +72,9 @@ COPY backend/ ./
|
||||
COPY --from=frontend-builder /app/backend/internal/web/dist ./internal/web/dist
|
||||
|
||||
# Build the binary (BuildType=release for CI builds, embed frontend)
|
||||
# Version precedence: build arg VERSION > cmd/server/VERSION
|
||||
# Version precedence: build arg VERSION > exact git tag > cmd/server/VERSION
|
||||
RUN VERSION_VALUE="${VERSION}" && \
|
||||
if [ -z "${VERSION_VALUE}" ]; then VERSION_VALUE="$(tr -d '\r\n' < ./cmd/server/VERSION)"; fi && \
|
||||
if [ -z "${VERSION_VALUE}" ]; then VERSION_VALUE="$(./scripts/resolve-version.sh)"; fi && \
|
||||
DATE_VALUE="${DATE:-$(date -u +%Y-%m-%dT%H:%M:%SZ)}" && \
|
||||
CGO_ENABLED=0 GOOS=linux go build \
|
||||
-tags embed \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.PHONY: build build-backend build-frontend build-datamanagementd test test-backend test-frontend test-frontend-critical test-datamanagementd secret-scan
|
||||
.PHONY: build build-backend build-frontend test test-backend test-frontend test-frontend-critical
|
||||
|
||||
FRONTEND_CRITICAL_VITEST := \
|
||||
src/views/auth/__tests__/LinuxDoCallbackView.spec.ts \
|
||||
@@ -19,10 +19,6 @@ build-backend:
|
||||
build-frontend:
|
||||
@pnpm --dir frontend run build
|
||||
|
||||
# 编译 datamanagementd(宿主机数据管理进程)
|
||||
build-datamanagementd:
|
||||
@cd datamanagement && go build -o datamanagementd ./cmd/datamanagementd
|
||||
|
||||
# 运行测试(后端 + 前端)
|
||||
test: test-backend test-frontend
|
||||
|
||||
@@ -36,9 +32,3 @@ test-frontend:
|
||||
|
||||
test-frontend-critical:
|
||||
@pnpm --dir frontend exec vitest run $(FRONTEND_CRITICAL_VITEST)
|
||||
|
||||
test-datamanagementd:
|
||||
@cd datamanagement && go test ./...
|
||||
|
||||
secret-scan:
|
||||
@python3 tools/secret_scan.py
|
||||
|
||||
@@ -23,13 +23,19 @@ Please read the following carefully before using this project:
|
||||
- **🚨 Terms of Service Risk**: Using this project may violate the terms of service of Anthropic and other upstream providers. Please review the relevant providers' user agreements before use; all risks arising from such use are borne solely by the user.
|
||||
- **⚖️ Compliant Use**: Use this project only in compliance with the laws and regulations of your country or region. Any unlawful use is strictly prohibited.
|
||||
- **📖 Disclaimer**: This project is provided for technical learning and research purposes only. The authors assume no liability for account bans, service interruptions, data loss, or any other direct or indirect damages resulting from the use of this project.
|
||||
- **🚫 No Commercial Authorization**: The developers of this project have never authorized any individual or organization to conduct any form of commercial operation based on this project. Any commercial activity conducted in the name of or based on this project is unrelated to this project and its developers, and all resulting disputes, losses, and legal liabilities shall be borne solely by the party conducting such activity.
|
||||
|
||||
## ❤️ Sponsors
|
||||
|
||||
> [Want to appear here?](mailto:support@pincc.ai)
|
||||
> [Want to appear here?](mailto:support@sub2api.org)
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://cctk.ai/register?aff=SUB2API"><img src="assets/partners/logos/cctk.jpg" alt="CCTK.AI" width="150"></a></td>
|
||||
<td>Thanks to CCTK.AI for sponsoring this project! <a href="https://cctk.ai/register?aff=SUB2API">CCTK.AI</a> is an AI API gateway focused on stability and cost-effectiveness, offering fast relay services for Claude, OpenAI, Gemini, and other popular models. It works seamlessly with Claude Code, Codex, and other mainstream coding tools, delivering the same model capabilities at a fraction of the official cost. Register via <a href="https://cctk.ai/register?aff=SUB2API">this link</a> for faster, more stable, and more affordable AI API access.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://www.openmodel.ai?ref=sub2api"><img src="assets/partners/logos/openmodel.jpg" alt="openmodel" width="150"></a></td>
|
||||
<td>One API, every top model! <a href="https://www.openmodel.ai?ref=sub2api">OpenModel</a> is a production-grade, high-availability AI API gateway that makes your applications truly fast and stable: automatic failover, smart routing to the best-performing channel, and a production-grade SLA. An SLA that far surpasses any single provider — making stability your core competitive advantage. Works directly with Claude Code, Codex, and Gemini CLI. Register via this link to get started.</td>
|
||||
@@ -41,13 +47,13 @@ Please read the following carefully before using this project:
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://aigocode.com/invite/SUB2API"><img src="assets/partners/logos/aigocode.png" alt="AIGoCode" width="150"></a></td>
|
||||
<td>Thanks to AIGoCode for sponsoring this project! AIGoCode is an all-in-one platform that integrates Claude Code, Codex, and the latest Gemini models, providing you with stable, efficient, and highly cost-effective AI coding services. The platform offers flexible subscription plans, zero risk of account suspension, direct access with no VPN required, and lightning-fast responses. AIGoCode has prepared a special benefit for sub2api users: if you register via <a href="https://aigocode.com/invite/SUB2API">this link</a>, you'll receive an extra 10% bonus credit on your first top-up!</td>
|
||||
<td width="180"><a href="https://apikey.fun/register?aff=SUB2API"><img src="assets/partners/logos/apikey-fun.png" alt="APIKEY.FUN" width="150"></a></td>
|
||||
<td>Thanks to APIKEY.FUN for sponsoring this project! <a href="https://apikey.fun/register?aff=SUB2API">APIKEY.FUN</a> is one of the core contributors to the sub2api open-source project, dedicated to providing open, stable, and cost-effective AI API access. The platform supports API relay services for Claude, OpenAI, Gemini, and other popular models, with pricing starting from as low as 7% of the original rate. Register via the exclusive link: <a href="https://apikey.fun/register?aff=SUB2API">APIKEY</a> to enjoy a permanent 5% discount on all recharges.</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://code.silkapi.com/register?aff=SUB2API"><img src="assets/partners/logos/silkapi.png" alt="silkapi" width="150"></a></td>
|
||||
<td>Thanks to SilkAPI for sponsoring this project! <a href="https://code.silkapi.com/register?aff=SUB2API">SilkAPI</a> is a relay service built on Sub2API, specializing in providing high-speed and stable Codex API relay.</td>
|
||||
<td width="180"><a href="https://aigocode.com/invite/SUB2API"><img src="assets/partners/logos/aigocode.png" alt="AIGoCode" width="150"></a></td>
|
||||
<td>Thanks to AIGoCode for sponsoring this project! AIGoCode is an all-in-one platform that integrates Claude Code, Codex, and the latest Gemini models, providing you with stable, efficient, and highly cost-effective AI coding services. The platform offers flexible subscription plans, zero risk of account suspension, direct access with no VPN required, and lightning-fast responses. AIGoCode has prepared a special benefit for sub2api users: if you register via <a href="https://aigocode.com/invite/SUB2API">this link</a>, you'll receive an extra 10% bonus credit on your first top-up!</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -95,8 +101,8 @@ Please read the following carefully before using this project:
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://apikl.com"><img src="assets/partners/logos/apikl.png" alt="apikl" width="150"></a></td>
|
||||
<td>Thanks to Apikl for sponsoring this project! Built on Sub2API, the platform provides developers with relay services for Codex / Claude series models, focusing on long-term stability, high-speed direct connections, and excellent cost-effectiveness. It offers pay-as-you-go balance billing, enterprise-grade official invoices, and one-on-one dedicated support. <a href="https://apikl.com">Register now</a> for a 1:1 top-up bonus — double your balance!
|
||||
<td width="180"><a href="https://apikl.ai"><img src="assets/partners/logos/apikl.png" alt="apikl" width="150"></a></td>
|
||||
<td>Thanks to Apikl for sponsoring this project! Built on Sub2API, the platform provides developers with relay services for Codex / Claude series models, focusing on long-term stability, high-speed direct connections, and excellent cost-effectiveness. It offers pay-as-you-go balance billing, enterprise-grade official invoices, and one-on-one dedicated support. <a href="https://apikl.ai">Register now</a> for a 1:1 top-up bonus — double your balance!
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -133,6 +139,30 @@ Please read the following carefully before using this project:
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://anpin.ai"><img src="assets/partners/logos/anpin.jpg" alt="anpin" width="150"></a></td>
|
||||
<td>Thanks to <a href="https://anpin.ai">anpin.ai</a> for sponsoring this project! anpin.ai is a premium AI relay service platform dedicated to advancing AI accessibility. With an advanced technical architecture and globally distributed deployment, it provides users with a direct high-speed channel to the world's top-tier large language models.<br>
|
||||
Self-built primary account pool: 1-3s ultra-fast response, supports channel-partner distribution<br>
|
||||
Extreme stability: multi-line intelligent routing + redundant backup system, ensuring year-round high-availability operation;<br>
|
||||
Model authenticity: no content intervention or secondary filtering — experience the purest, most powerful native model capabilities.<br>
|
||||
1:1 top-up, enterprise-grade service with invoicing available. Anpin AI is not just a relay — it's your secure, reliable, and efficient bridge to the frontier world of intelligence.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://www.proxy4free.com/?keyword=4yjqecpc"><img src="assets/partners/logos/proxy4free.png" alt="proxy4free" width="150"></a></td>
|
||||
<td>Thanks to Proxy4Free for sponsoring this project! Proxy4Free is a data proxy service provider for developers and AI applications, offering residential proxies, static residential proxies, ISP proxies, and datacenter proxies for scenarios such as Web Scraping, Browser Automation, and AI Agents. With global IP resources, stable connections, and flexible switching, it helps developers improve data collection success rates and reduce the risk of IP bans. Register via <a href="https://www.proxy4free.com/?keyword=4yjqecpc">this link</a> to get started and easily build more stable and efficient automation workflows.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="http://www.fastaitoken.com/register"><img src="assets/partners/logos/fastaitoken.jpg" alt="fastaitoken" width="150"></a></td>
|
||||
<td>🎉 Thanks to FastAIToken for sponsoring this project! <a href="http://www.fastaitoken.com/register">FastAIToken</a> is an AI API aggregation platform for developers, supporting mainstream large models such as OpenAI, Claude, and Gemini. Top-up at 1:1 — 1 CNY = 1 USD of API credit — letting developers use the world's leading large model services at lower cost and with greater convenience.<br>
|
||||
|
||||
🚀 The platform offers a variety of channels to choose from: an ultra-low-price 0.02x OpenAI promotional group (limited time), groups as low as 0.25x OpenAI, 0.7x Claude with 95% fixed cache, and a 1.2x Claude Max channel. It also provides a public status page showing real-time availability, latency, and operating status of each group for transparent and reliable service, plus 7×24 human technical support (not bots) with fast responses to developer needs.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
## Overview
|
||||
@@ -299,6 +329,7 @@ cd sub2api/deploy
|
||||
|
||||
# 2. Copy environment configuration
|
||||
cp .env.example .env
|
||||
chmod 600 .env
|
||||
|
||||
# 3. Edit configuration (generate secure passwords)
|
||||
nano .env
|
||||
@@ -418,7 +449,23 @@ rm -rf data/ postgres_data/ redis_data/
|
||||
|
||||
---
|
||||
|
||||
### Method 3: Build from Source
|
||||
### Method 3: Apple container (macOS)
|
||||
|
||||
Apple-silicon Macs running macOS 26 can run the full Sub2API, PostgreSQL, and Redis stack with Apple `container` 1.1.0 or newer:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/Wei-Shaw/sub2api.git
|
||||
cd sub2api/deploy
|
||||
./apple-container.sh init
|
||||
./apple-container.sh up
|
||||
./apple-container.sh status
|
||||
```
|
||||
|
||||
This is an operator-managed local workflow; Docker Compose remains the recommended production path. See [deploy/APPLE_CONTAINER.md](deploy/APPLE_CONTAINER.md) for lifecycle commands, persistence, upgrades, and runtime limitations.
|
||||
|
||||
---
|
||||
|
||||
### Method 4: Build from Source
|
||||
|
||||
Build and run from source code for development or customization.
|
||||
|
||||
@@ -447,7 +494,8 @@ pnpm run build
|
||||
|
||||
# 4. Build backend with embedded frontend
|
||||
cd ../backend
|
||||
go build -tags embed -o sub2api ./cmd/server
|
||||
VERSION="$(./scripts/resolve-version.sh)"
|
||||
go build -tags embed -ldflags="-X main.Version=${VERSION}" -o sub2api ./cmd/server
|
||||
|
||||
# 5. Create configuration file
|
||||
cp ../deploy/config.example.yaml ./config.yaml
|
||||
@@ -510,20 +558,20 @@ Additional security-related options are available in `config.yaml`:
|
||||
|
||||
**⚠️ Security Warning: HTTP URL Configuration**
|
||||
|
||||
When `security.url_allowlist.enabled=false`, the system performs minimal URL validation by default, **rejecting HTTP URLs** and only allowing HTTPS. To allow HTTP URLs (e.g., for development or internal testing), you must explicitly set:
|
||||
When `security.url_allowlist.enabled=false`, the system performs minimal URL validation and **allows HTTP URLs by default** (dev-friendly mode; Docker Compose deployments use the same default). For production, explicitly tighten this to HTTPS-only:
|
||||
|
||||
```yaml
|
||||
security:
|
||||
url_allowlist:
|
||||
enabled: false # Disable allowlist checks
|
||||
allow_insecure_http: true # Allow HTTP URLs (⚠️ INSECURE)
|
||||
allow_insecure_http: false # HTTPS only (recommended for production)
|
||||
```
|
||||
|
||||
**Or via environment variable:**
|
||||
|
||||
```bash
|
||||
SECURITY_URL_ALLOWLIST_ENABLED=false
|
||||
SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP=true
|
||||
SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP=false
|
||||
```
|
||||
|
||||
**Risks of allowing HTTP:**
|
||||
@@ -537,7 +585,7 @@ SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP=true
|
||||
- ✅ Testing account connectivity before obtaining HTTPS
|
||||
- ❌ Production environments (use HTTPS only)
|
||||
|
||||
**Example error without this setting:**
|
||||
**Example error for HTTP URLs when `allow_insecure_http: false` is set:**
|
||||
```
|
||||
Invalid base URL: invalid url scheme: http
|
||||
```
|
||||
@@ -548,6 +596,46 @@ If you disable URL validation or response header filtering, harden your network
|
||||
- Enforce TLS-only outbound traffic
|
||||
- Strip sensitive upstream response headers at the proxy
|
||||
|
||||
#### OpenAI Responses WebSocket ingress limits
|
||||
|
||||
`gateway.openai_ws` bounds the lifetime and aggregate count of client-facing
|
||||
Responses WebSocket sessions. These safeguards apply independently from
|
||||
per-turn user and account concurrency slots, which are released between turns.
|
||||
|
||||
```yaml
|
||||
gateway:
|
||||
openai_ws:
|
||||
# Close a client socket idle between completed turns; 0 disables this safeguard.
|
||||
ingress_inter_turn_idle_timeout_seconds: 300
|
||||
# Distributed API-key limit for live client ingress sessions; 0 disables it.
|
||||
max_ingress_connections_per_api_key: 64
|
||||
```
|
||||
|
||||
The connection cap is coordinated through Redis using a 60-second lease that
|
||||
is refreshed every 20 seconds. A process that cannot confirm a lease for a
|
||||
full lease lifetime closes its local WebSocket rather than continuing outside
|
||||
the global cap. Use `http_bridge` for client-WebSocket/upstream-HTTP operation
|
||||
when rolling out or mitigating upstream WebSocket issues.
|
||||
|
||||
#### ⚠️ Important: Creating the Admin Account
|
||||
|
||||
The initial admin account is **only created via the setup wizard** (served at `http://<host>:8080` on first run). The `default.admin_email` / `default.admin_password` fields in `config.yaml` are **not used** to create it — they exist in the template for historical reasons.
|
||||
|
||||
Because step 5 above pre-creates `config.yaml`, the setup wizard will be **skipped on first run**: the server detects an existing config and boots straight into normal mode with an empty `users` table, so the first login attempt fails with `invalid email or password`.
|
||||
|
||||
**Two ways to create the admin account:**
|
||||
|
||||
1. **Recommended — let the wizard generate `config.yaml`:** Skip step 5 (do not run the `cp`). Start `./sub2api` directly; the setup wizard at `http://localhost:8080` walks you through database, Redis, and admin account setup, then writes `config.yaml` for you.
|
||||
|
||||
2. **If you already created `config.yaml`:** Temporarily move it aside so the wizard can trigger on first run, then restore it afterwards:
|
||||
```bash
|
||||
mv config.yaml config.yaml.bak
|
||||
./sub2api # wizard runs at http://localhost:8080 and writes a fresh config.yaml
|
||||
# stop the server (Ctrl+C) once the wizard completes, then restore your config:
|
||||
mv config.yaml.bak config.yaml
|
||||
./sub2api # restart in normal mode and log in with the admin you just created
|
||||
```
|
||||
|
||||
```bash
|
||||
# 6. Run the application
|
||||
./sub2api
|
||||
@@ -587,17 +675,22 @@ Simple Mode is designed for individual developers or internal teams who want qui
|
||||
|
||||
---
|
||||
|
||||
## Grok / xAI OAuth Support
|
||||
## Grok / xAI Support
|
||||
|
||||
Sub2API supports Grok subscription accounts through xAI OAuth and forwards OpenAI-compatible Responses traffic to xAI.
|
||||
Sub2API supports both Grok subscription accounts through xAI OAuth and standard xAI API-key accounts. Both account types forward OpenAI-compatible Responses traffic to xAI.
|
||||
|
||||
### Supported Scope
|
||||
|
||||
- Platform name: `grok`
|
||||
- Account type: OAuth subscription accounts
|
||||
- Public gateway target: `/v1/responses` and `/responses`, forwarded to `${XAI_BASE_URL:-https://api.x.ai/v1}/responses`
|
||||
- Initial models: `grok-4.3`, `grok-build-0.1`, `grok-4.20-0309-reasoning`, `grok-4.20-0309-non-reasoning`, and `grok-4.20-multi-agent-0309`
|
||||
- Out of scope for this provider: public Grok Chat Completions routes, image, video, TTS, transcription, browser automation, cookies, and Grok web scraping
|
||||
- Account types: OAuth subscription accounts and xAI API-key accounts
|
||||
- Public Responses targets: `/v1/responses`, `/responses`, and `/backend-api/codex/responses`, forwarded to the Grok subscription proxy for OAuth accounts or `https://api.x.ai/v1/responses` for API-key accounts
|
||||
- Public Claude-compatible target: `/v1/messages`, converted to xAI Responses and returned as Anthropic Messages output for Claude CLI style clients
|
||||
- Public Chat Completions targets: `/v1/chat/completions` and `/chat/completions`, forwarded to the account-type-specific xAI upstream
|
||||
- Codex CLI style Responses WebSocket ingress is accepted on the Responses targets and bridged to xAI HTTP/SSE Responses upstream
|
||||
- Text models: `grok-4.5`, `grok-4.3`, `grok-build-0.1`, `grok-composer-2.5-fast`, `grok-4.20-0309-reasoning`, `grok-4.20-0309-non-reasoning`, and `grok-4.20-multi-agent-0309`
|
||||
- Media targets for Grok groups: `/v1/images/generations`, `/images/generations`, `/v1/images/edits`, `/images/edits`, `/v1/videos/generations`, `/videos/generations`, `/v1/videos/edits`, `/videos/edits`, `/v1/videos/extensions`, `/videos/extensions`, `/v1/videos/{request_id}`, and `/videos/{request_id}`. Generation, editing, and extension requests require the group image-generation permission.
|
||||
- Media models: `grok-imagine`, `grok-imagine-image-quality`, `grok-imagine-image`, `grok-imagine-edit`, `grok-imagine-video`, and `grok-imagine-video-1.5`
|
||||
- Out of scope for this provider: TTS, transcription, browser automation, cookies, and Grok web scraping
|
||||
|
||||
### OAuth Configuration
|
||||
|
||||
@@ -610,9 +703,10 @@ The Grok OAuth flow uses PKCE and does not require committing private secrets. T
|
||||
| `XAI_OAUTH_REDIRECT_URI` | `http://127.0.0.1:56121/callback` |
|
||||
| `XAI_OAUTH_AUTHORIZE_URL` | `https://auth.x.ai/oauth2/authorize` |
|
||||
| `XAI_OAUTH_TOKEN_URL` | `https://auth.x.ai/oauth2/token` |
|
||||
| `XAI_BASE_URL` | `https://api.x.ai/v1` |
|
||||
| `XAI_BASE_URL` | `https://api.x.ai/v1`; runtime-diagnostics override (account `base_url` controls request forwarding) |
|
||||
| `XAI_GROK_CLI_VERSION` | `0.2.93`; optional override for the client identity sent to `cli-chat-proxy.grok.com` |
|
||||
|
||||
Administrators can create or reauthorize Grok accounts from the dashboard, or use the admin API:
|
||||
Administrators can create Grok OAuth or API-key accounts from the dashboard. OAuth authorization and reauthorization are also available through the admin API:
|
||||
|
||||
| Endpoint | Purpose |
|
||||
|----------|---------|
|
||||
@@ -621,13 +715,47 @@ Administrators can create or reauthorize Grok accounts from the dashboard, or us
|
||||
| `POST /api/v1/admin/grok/oauth/refresh-token` | Validate or refresh a Grok refresh token |
|
||||
| `POST /api/v1/admin/grok/accounts/:id/refresh` | Refresh an existing Grok account |
|
||||
|
||||
Credential storage reuses the existing account JSON fields: `access_token`, `refresh_token`, `token_type`, `expires_at`, optional `email`, optional `subscription_tier`, and `entitlement_status`.
|
||||
OAuth credential storage reuses the existing account JSON fields: `access_token`, `refresh_token`, `token_type`, `expires_at`, `base_url`, optional `email`, optional `subscription_tier`, and `entitlement_status`. OAuth inference defaults to `https://cli-chat-proxy.grok.com/v1`; existing OAuth accounts that stored the old `https://api.x.ai/v1` default are redirected to the subscription proxy at runtime. Explicit custom upstreams remain unchanged.
|
||||
|
||||
For API-key accounts, select **Grok → API Key** in the create-account dialog. The official base URL defaults to `https://api.x.ai/v1`; credentials use the existing `base_url` and `api_key` account fields. OAuth accounts continue to use the subscription flow above.
|
||||
|
||||
### Grok Build CLI Configuration
|
||||
|
||||
1. In the Sub2API admin dashboard, add either a `grok` OAuth account and complete xAI authorization, or add a Grok API-key account.
|
||||
2. Create a Grok group, attach the account to it, then create a Sub2API API key assigned to that group.
|
||||
3. In the user API-key page, click **Use Key** and select **Grok CLI**. The modal generates the correct file and base URL for macOS/Linux or Windows. It also provides an OpenCode configuration on the **OpenCode** tab.
|
||||
4. If configuring manually, save the following as `~/.grok/config.toml` (Windows: `%USERPROFILE%\.grok\config.toml`):
|
||||
|
||||
```toml
|
||||
[models]
|
||||
default = "sub2api-grok"
|
||||
web_search = "sub2api-grok"
|
||||
|
||||
[model."sub2api-grok"]
|
||||
model = "grok-4.5"
|
||||
base_url = "https://your-sub2api.example.com/v1"
|
||||
name = "Grok 4.5 via Sub2API"
|
||||
description = "Grok 4.5 through a Sub2API Grok group"
|
||||
api_key = "sk-your-sub2api-key"
|
||||
api_backend = "responses"
|
||||
context_window = 1000000
|
||||
supports_backend_search = true
|
||||
```
|
||||
|
||||
Back up an existing `config.toml` before merging the entry. The file contains a Sub2API API key, so keep it private and restrict its permissions where supported. Verify the effective configuration and make a smoke request:
|
||||
|
||||
```bash
|
||||
grok inspect
|
||||
grok -p "Reply with sub2api-ok" -m sub2api-grok
|
||||
```
|
||||
|
||||
The `base_url` above is the public Sub2API URL ending in `/v1`, not `api.x.ai` or the internal xAI OAuth proxy URL.
|
||||
|
||||
### Usage And Quota Display
|
||||
|
||||
xAI quota is passive. Sub2API does not invent subscription quota values; it records whitelisted xAI rate-limit headers from successful or rate-limited upstream responses when xAI sends them. Before the first usable upstream response, the dashboard shows quota as unknown and still displays local Sub2API usage stats.
|
||||
|
||||
`401` responses mark the account as needing reauthorization. `403` responses are treated as entitlement or subscription-tier failures instead of token-refresh loops. `429` responses use `Retry-After` or a short cooldown to temporarily remove the account from scheduling.
|
||||
`401` responses temporarily remove accounts with invalid credentials from scheduling. `403` responses are treated as access or entitlement failures instead of token-refresh loops. `429` responses use `Retry-After` or a short cooldown to temporarily remove the account from scheduling.
|
||||
|
||||
---
|
||||
|
||||
@@ -655,12 +783,6 @@ Antigravity accounts support optional **hybrid scheduling**. When enabled, the g
|
||||
|
||||
> **⚠️ Warning**: Anthropic Claude and Antigravity Claude **cannot be mixed within the same conversation context**. Use groups to isolate them properly.
|
||||
|
||||
### Known Issues
|
||||
|
||||
In Claude Code, Plan Mode cannot exit automatically. (Normally when using the native Claude API, after planning is complete, Claude Code will pop up options for users to approve or reject the plan.)
|
||||
|
||||
**Workaround**: Press `Shift + Tab` to manually exit Plan Mode, then type your response to approve or reject the plan.
|
||||
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
@@ -691,16 +813,6 @@ sub2api/
|
||||
└── install.sh # One-click installation script
|
||||
```
|
||||
|
||||
## Disclaimer
|
||||
|
||||
> **Please read carefully before using this project:**
|
||||
>
|
||||
> :rotating_light: **Terms of Service Risk**: Using this project may violate Anthropic's Terms of Service. Please read Anthropic's user agreement carefully before use. All risks arising from the use of this project are borne solely by the user.
|
||||
>
|
||||
> :book: **Disclaimer**: This project is for technical learning and research purposes only. The author assumes no responsibility for account suspension, service interruption, or any other losses caused by the use of this project.
|
||||
|
||||
---
|
||||
|
||||
## Star History
|
||||
|
||||
<a href="https://star-history.com/#Wei-Shaw/sub2api&Date">
|
||||
|
||||
+81
-27
@@ -24,13 +24,19 @@
|
||||
- **🚨 服务条款风险**:使用本项目可能违反 Anthropic 等上游服务商的服务条款。请在使用前仔细阅读相关服务商的用户协议,由此产生的一切风险由用户自行承担。
|
||||
- **⚖️ 合规使用**:请在符合您所在国家或地区法律法规的前提下使用本项目,严禁将其用于任何违法违规用途。
|
||||
- **📖 免责声明**:本项目仅供技术学习与研究使用,作者不对因使用本项目导致的账户封禁、服务中断、数据丢失或其他任何直接或间接损失承担责任。
|
||||
- **🚫 无商业授权**:本项目从未授权任何个人或组织基于本项目开展任何形式的商业化运营。任何以本项目名义或基于本项目从事的商业行为均与本项目及其开发者无关,由此产生的一切纠纷、损失和法律责任由行为主体自行承担。
|
||||
|
||||
## ❤️ 赞助商
|
||||
|
||||
> [想出现在这里?](mailto:support@pincc.ai)
|
||||
> [想出现在这里?](mailto:support@sub2api.org)
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://cctk.ai/register?aff=SUB2API"><img src="assets/partners/logos/cctk.jpg" alt="CCTK.AI" width="150"></a></td>
|
||||
<td>感谢 CCTK.AI 赞助了本项目!<a href="https://cctk.ai/register?aff=SUB2API">CCTK.AI</a> 是一个专注于稳定与性价比的 AI API 网关平台,提供 Claude、OpenAI、Gemini 等主流模型的高速中转服务,无缝兼容 Claude Code、Codex 等主流编程工具,以远低于官方的成本获得同等的模型能力。点击<a href="https://cctk.ai/register?aff=SUB2API">此链接</a>注册,即刻体验更快、更稳、更省的 AI API 接入。</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://www.openmodel.ai?ref=sub2api"><img src="assets/partners/logos/openmodel.jpg" alt="openmodel" width="150"></a></td>
|
||||
<td>一个API,顶级模型随便用!<a href="https://www.openmodel.ai?ref=sub2api">OpenModel</a> 专注于生产级、高可用的 AI API 网关,让你的应用真正做到高速稳定:自动故障转移、智能选最优渠道、生产级 SLA 保障。远超单一供应商的 SLA,让稳定性成为您的核心竞争力。</td>
|
||||
@@ -42,13 +48,13 @@
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://aigocode.com/invite/SUB2API"><img src="assets/partners/logos/aigocode.png" alt="AIGoCode" width="150"></a></td>
|
||||
<td>感谢 AIGoCode 赞助了本项目!AIGoCode 是一站式集成 Claude Code、Codex 以及最新 Gemini 模型的综合平台,为您提供稳定、高效、高性价比的 AI 编程服务。平台提供灵活的订阅方案,零封号风险,免 VPN 直连,响应极速。AIGoCode 为 sub2api 用户准备了专属福利:通过<a href="https://aigocode.com/invite/SUB2API">此链接</a>注册,首次充值可额外获得 10% 赠送额度!</td>
|
||||
<td width="180"><a href="https://apikey.fun/register?aff=SUB2API"><img src="assets/partners/logos/apikey-fun.png" alt="APIKEY.FUN" width="150"></a></td>
|
||||
<td>感谢 APIKEY.FUN 赞助了本项目!<a href="https://apikey.fun/register?aff=SUB2API">APIKEY.FUN</a> 是 sub2api 开源项目的核心贡献者之一,致力于提供开放、稳定、高性价比的 AI API 接入服务。平台支持 Claude、OpenAI、Gemini 等热门模型的 API 中转服务,价格低至官方原价的 7%。通过专属链接 <a href="https://apikey.fun/register?aff=SUB2API">APIKEY</a> 注册,可享受所有充值永久 95 折优惠。</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://code.silkapi.com/register?aff=SUB2API"><img src="assets/partners/logos/silkapi.png" alt="silkapi" width="150"></a></td>
|
||||
<td>感谢 丝绸API 赞助了本项目! <a href="https://code.silkapi.com/register?aff=SUB2API">丝绸API</a> 是基于 Sub2API 搭建的中转服务,专注于提供 Codex 高速稳定API中转。</td>
|
||||
<td width="180"><a href="https://aigocode.com/invite/SUB2API"><img src="assets/partners/logos/aigocode.png" alt="AIGoCode" width="150"></a></td>
|
||||
<td>感谢 AIGoCode 赞助了本项目!AIGoCode 是一站式集成 Claude Code、Codex 以及最新 Gemini 模型的综合平台,为您提供稳定、高效、高性价比的 AI 编程服务。平台提供灵活的订阅方案,零封号风险,免 VPN 直连,响应极速。AIGoCode 为 sub2api 用户准备了专属福利:通过<a href="https://aigocode.com/invite/SUB2API">此链接</a>注册,首次充值可额外获得 10% 赠送额度!</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -98,8 +104,8 @@
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://apikl.com"><img src="assets/partners/logos/apikl.png" alt="apikl" width="150"></a></td>
|
||||
<td>感谢 Apikl 赞助本项目!平台基于 Sub2API 搭建,为开发者提供 Codex / Claude 系列模型的中转服务,专注于长期稳定、高速直连与高性价比。支持按量计费的余额结算、企业级正规发票及一对一专属对接。<a href="https://apikl.com">立即注册</a>即享充值 1:1 赠送 — 余额翻倍!
|
||||
<td width="180"><a href="https://apikl.ai"><img src="assets/partners/logos/apikl.png" alt="apikl" width="150"></a></td>
|
||||
<td>感谢 Apikl 赞助本项目!平台基于 Sub2API 搭建,为开发者提供 Codex / Claude 系列模型的中转服务,专注于长期稳定、高速直连与高性价比。支持按量计费的余额结算、企业级正规发票及一对一专属对接。<a href="https://apikl.ai">立即注册</a>即享充值 1:1 赠送 — 余额翻倍!
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -136,6 +142,31 @@
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://anpin.ai"><img src="assets/partners/logos/anpin.jpg" alt="anpin" width="150"></a></td>
|
||||
<td>感谢 <a href="https://anpin.ai">anpin.ai</a> 赞助本项目!anpin.ai 是一家致力于推动 AI 普惠的高端 AI 中转服务平台。我们以先进的技术架构和全球分布式部署,为用户提供直达国际顶尖大模型的高速通道。<br>
|
||||
自建一手号池:1-3S超快响应 支持同行分发<br>
|
||||
极致稳定:多线智能路由 + 冗余备份系统,确保服务全年无休、高可用运行;<br>
|
||||
模型真实性:不做任何内容干预与二次过滤,让您体验到最纯粹、最强大的原生模型能力。<br>
|
||||
充值1:1 企业级服务可开票,安品Ai不只是中转站,更是您连接前沿智能世界的安全、可靠、高效桥梁
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://www.proxy4free.com/?keyword=4yjqecpc"><img src="assets/partners/logos/proxy4free.png" alt="proxy4free" width="150"></a></td>
|
||||
<td>感谢 Proxy4Free 赞助本项目!Proxy4Free 是面向开发者和 AI 应用的数据代理服务商,提供住宅代理、静态住宅代理、ISP 代理及数据中心代理等多种代理解决方案,适用于 Web Scraping、Browser Automation、AI Agent 等场景。支持全球 IP 资源、稳定连接与灵活切换,帮助开发者提升数据采集成功率,降低 IP 封禁风险。通过<a href="https://www.proxy4free.com/?keyword=4yjqecpc">此链接注册</a>即可开始体验,轻松构建更稳定、高效的自动化工作流。
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="http://www.fastaitoken.com/register"><img src="assets/partners/logos/fastaitoken.jpg" alt="fastaitoken" width="150"></a></td>
|
||||
<td>🎉 感谢 FastAIToken 对本项目的赞助! <a href="http://www.fastaitoken.com/register">FastAIToken</a> 是面向开发者的 AI API 聚合平台,支持 OpenAI、Claude、Gemini 等主流大模型,充值 1:1,1 元 = 1 美元 API 额度,让开发者以更低成本、更便捷地使用全球领先的大模型服务。<br>
|
||||
|
||||
🚀 平台提供多种渠道自由选择:超级低价的0.02x OpenAI 福利分组(限时)、低至 0.25x OpenAI 分组、0.7x Claude 95%固定缓存、1.2x Claude Max 渠道;同时提供公开状态页,实时展示各分组的可用率、延迟及运行状态,服务透明可靠,并提供 7×24 小时真人技术支持(非机器人),快速响应开发者需求。
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
</table>
|
||||
|
||||
## 项目概述
|
||||
@@ -302,6 +333,7 @@ cd sub2api/deploy
|
||||
|
||||
# 2. 复制环境配置文件
|
||||
cp .env.example .env
|
||||
chmod 600 .env
|
||||
|
||||
# 3. 编辑配置(生成安全密码)
|
||||
nano .env
|
||||
@@ -433,7 +465,23 @@ rm -rf data/ postgres_data/ redis_data/
|
||||
|
||||
---
|
||||
|
||||
### 方式三:源码编译
|
||||
### 方式三:Apple container(macOS)
|
||||
|
||||
Apple 芯片 Mac 在 macOS 26 上可使用 Apple `container` 1.1.0 或更高版本运行完整的 Sub2API、PostgreSQL 和 Redis:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/Wei-Shaw/sub2api.git
|
||||
cd sub2api/deploy
|
||||
./apple-container.sh init
|
||||
./apple-container.sh up
|
||||
./apple-container.sh status
|
||||
```
|
||||
|
||||
该方式面向本地开发和人工运维,不提供持续重启监管;生产部署仍推荐 Docker Compose。生命周期命令、持久化、升级和运行时限制见 [deploy/APPLE_CONTAINER.md](deploy/APPLE_CONTAINER.md)。
|
||||
|
||||
---
|
||||
|
||||
### 方式四:源码编译
|
||||
|
||||
从源码编译安装,适合开发或定制需求。
|
||||
|
||||
@@ -462,7 +510,8 @@ pnpm run build
|
||||
|
||||
# 4. 编译后端(嵌入前端)
|
||||
cd ../backend
|
||||
go build -tags embed -o sub2api ./cmd/server
|
||||
VERSION="$(./scripts/resolve-version.sh)"
|
||||
go build -tags embed -ldflags="-X main.Version=${VERSION}" -o sub2api ./cmd/server
|
||||
|
||||
# 5. 创建配置文件
|
||||
cp ../deploy/config.example.yaml ./config.yaml
|
||||
@@ -554,20 +603,20 @@ gateway:
|
||||
|
||||
**⚠️ 安全警告:HTTP URL 配置**
|
||||
|
||||
当 `security.url_allowlist.enabled=false` 时,系统默认执行最小 URL 校验,**拒绝 HTTP URL**,仅允许 HTTPS。要允许 HTTP URL(例如用于开发或内网测试),必须显式设置:
|
||||
当 `security.url_allowlist.enabled=false` 时,系统仅执行最小 URL 校验,且**默认允许 HTTP URL**(开发友好模式,Docker Compose 部署的默认值一致)。生产环境建议显式收紧为仅允许 HTTPS:
|
||||
|
||||
```yaml
|
||||
security:
|
||||
url_allowlist:
|
||||
enabled: false # 禁用白名单检查
|
||||
allow_insecure_http: true # 允许 HTTP URL(⚠️ 不安全)
|
||||
allow_insecure_http: false # 仅允许 HTTPS(生产环境推荐)
|
||||
```
|
||||
|
||||
**或通过环境变量:**
|
||||
|
||||
```bash
|
||||
SECURITY_URL_ALLOWLIST_ENABLED=false
|
||||
SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP=true
|
||||
SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP=false
|
||||
```
|
||||
|
||||
**允许 HTTP 的风险:**
|
||||
@@ -581,7 +630,7 @@ SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP=true
|
||||
- ✅ 获取 HTTPS 前测试账号连通性
|
||||
- ❌ 生产环境(仅使用 HTTPS)
|
||||
|
||||
**未设置此项时的错误示例:**
|
||||
**设置 `allow_insecure_http: false` 后,HTTP URL 会返回如下错误:**
|
||||
```
|
||||
Invalid base URL: invalid url scheme: http
|
||||
```
|
||||
@@ -592,6 +641,25 @@ Invalid base URL: invalid url scheme: http
|
||||
- 强制仅允许 TLS 出站
|
||||
- 在反向代理层移除敏感响应头
|
||||
|
||||
#### ⚠️ 重要:创建管理员账号
|
||||
|
||||
初始管理员账号**只能通过 setup 向导创建**(首次启动时访问 `http://<host>:8080`)。`config.yaml` 中的 `default.admin_email` / `default.admin_password` 字段**不会被用来创建管理员**——它们只是出于历史原因保留在模板里。
|
||||
|
||||
由于上面第 5 步预先创建了 `config.yaml`,**setup 向导在首次启动时会被跳过**:服务检测到 config 已存在,会直接进入正常模式,此时 `users` 表为空,首次登录会返回 `invalid email or password`。
|
||||
|
||||
**创建管理员的两种方式:**
|
||||
|
||||
1. **推荐——让向导自动生成 `config.yaml`:** 跳过上面的第 5 步(不要执行 `cp`)。直接运行 `./sub2api`,访问 `http://localhost:8080`,向导会引导你完成数据库、Redis 和管理员账号配置,并自动写出 `config.yaml`。
|
||||
|
||||
2. **如果你已经创建了 `config.yaml`:** 首次启动前先把它临时移走以触发向导,完成后再恢复:
|
||||
```bash
|
||||
mv config.yaml config.yaml.bak
|
||||
./sub2api # 向导在 http://localhost:8080 启动,并生成新的 config.yaml
|
||||
# 向导完成后 Ctrl+C 停服,再恢复你的配置:
|
||||
mv config.yaml.bak config.yaml
|
||||
./sub2api # 重启进入正常模式,用刚创建的管理员登录
|
||||
```
|
||||
|
||||
```bash
|
||||
# 6. 运行应用
|
||||
./sub2api
|
||||
@@ -678,10 +746,6 @@ Antigravity 账户支持可选的**混合调度**功能。开启后,通用端
|
||||
|
||||
> **⚠️ 注意**:Anthropic Claude 和 Antigravity Claude **不能在同一上下文中混合使用**,请通过分组功能做好隔离。
|
||||
|
||||
|
||||
### 已知问题
|
||||
在 Claude Code 中,无法自动退出Plan Mode。(正常使用原生Claude Api时,Plan 完成后,Claude Code会弹出弹出选项让用户同意或拒绝Plan。)
|
||||
解决办法:shift + Tab,手动退出Plan mode,然后输入内容 告诉 Claude Code 同意或拒绝 Plan
|
||||
---
|
||||
|
||||
## 项目结构
|
||||
@@ -712,16 +776,6 @@ sub2api/
|
||||
└── install.sh # 一键安装脚本
|
||||
```
|
||||
|
||||
## 免责声明
|
||||
|
||||
> **使用本项目前请仔细阅读:**
|
||||
>
|
||||
> :rotating_light: **服务条款风险**: 使用本项目可能违反 Anthropic 的服务条款。请在使用前仔细阅读 Anthropic 的用户协议,使用本项目的一切风险由用户自行承担。
|
||||
>
|
||||
> :book: **免责声明**: 本项目仅供技术学习和研究使用,作者不对因使用本项目导致的账户封禁、服务中断或其他损失承担任何责任。
|
||||
|
||||
---
|
||||
|
||||
## Star History
|
||||
|
||||
<a href="https://star-history.com/#Wei-Shaw/sub2api&Date">
|
||||
|
||||
+80
-29
@@ -23,13 +23,19 @@
|
||||
- **🚨 利用規約のリスク**:本プロジェクトの使用は、Anthropic をはじめとする上流プロバイダーの利用規約に違反する可能性があります。ご利用前に各プロバイダーのユーザー規約を必ずご確認ください。使用により生じるすべてのリスクはユーザーご自身が負うものとします。
|
||||
- **⚖️ 法令遵守**:お住まいの国または地域の法令を遵守した上で本プロジェクトをご利用ください。いかなる違法な目的での使用も固く禁じます。
|
||||
- **📖 免責事項**:本プロジェクトは技術的な学習および研究の目的でのみ提供されます。本プロジェクトの使用により生じたアカウントの停止、サービスの中断、データの損失、その他一切の直接的または間接的な損害について、作者は一切の責任を負いません。
|
||||
- **🚫 商用利用の非許諾**:本プロジェクトの開発者は、いかなる個人または組織に対しても、本プロジェクトを利用したいかなる形態の商業運営も一切許諾していません。本プロジェクトの名義で、または本プロジェクトに基づいて行われる商業行為はすべて本プロジェクトおよびその開発者とは無関係であり、それにより生じる一切の紛争、損失、法的責任は行為者自身が負うものとします。
|
||||
|
||||
## ❤️ スポンサー
|
||||
|
||||
> [こちらに掲載しませんか?](mailto:support@pincc.ai)
|
||||
> [こちらに掲載しませんか?](mailto:support@sub2api.org)
|
||||
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://cctk.ai/register?aff=SUB2API"><img src="assets/partners/logos/cctk.jpg" alt="CCTK.AI" width="150"></a></td>
|
||||
<td>CCTK.AI のご支援に感謝します!<a href="https://cctk.ai/register?aff=SUB2API">CCTK.AI</a> は安定性とコストパフォーマンスにこだわった AI API ゲートウェイで、Claude、OpenAI、Gemini など主要モデルの高速中継サービスを提供しています。Claude Code や Codex などの主要なコーディングツールにシームレスに対応し、公式価格を大きく下回るコストで同等のモデル能力を利用できます。<a href="https://cctk.ai/register?aff=SUB2API">こちらのリンク</a>から登録して、より速く、より安定した、よりお得な AI API 接続をお試しください。</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://www.openmodel.ai?ref=sub2api"><img src="assets/partners/logos/openmodel.jpg" alt="openmodel" width="150"></a></td>
|
||||
<td>1つの API で、トップモデルを使い放題!<a href="https://www.openmodel.ai?ref=sub2api">OpenModel</a> は本番環境グレードで高可用性の AI API ゲートウェイに特化し、アプリを真に高速・安定させます:自動フェイルオーバー、最適なチャネルへのスマートルーティング、本番グレードの SLA 保証。単一プロバイダーをはるかに上回る SLA で、安定性をあなたの核心的な競争力にします。</td>
|
||||
@@ -41,13 +47,13 @@
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://aigocode.com/invite/SUB2API"><img src="assets/partners/logos/aigocode.png" alt="AIGoCode" width="150"></a></td>
|
||||
<td>AIGoCode のご支援に感謝します!AIGoCode は Claude Code、Codex、最新の Gemini モデルを統合したオールインワンプラットフォームで、安定的かつ効率的でコストパフォーマンスに優れた AI コーディングサービスを提供します。柔軟なサブスクリプションプラン、アカウント停止リスクゼロ、VPN 不要の直接アクセス、超高速レスポンスが特長です。AIGoCode は sub2api ユーザー向けに特別特典を用意しています:<a href="https://aigocode.com/invite/SUB2API">こちらのリンク</a>から登録すると、初回チャージ時に 10% のボーナスクレジットを追加プレゼント!</td>
|
||||
<td width="180"><a href="https://apikey.fun/register?aff=SUB2API"><img src="assets/partners/logos/apikey-fun.png" alt="APIKEY.FUN" width="150"></a></td>
|
||||
<td>APIKEY.FUN のご支援に感謝します!<a href="https://apikey.fun/register?aff=SUB2API">APIKEY.FUN</a> は sub2api オープンソースプロジェクトのコアコントリビューターの一つであり、オープンで安定した、コストパフォーマンスに優れた AI API アクセスサービスの提供に取り組んでいます。プラットフォームは Claude、OpenAI、Gemini など人気モデルの API 中継サービスをサポートし、価格は公式料金のわずか 7% から。専用リンク <a href="https://apikey.fun/register?aff=SUB2API">APIKEY</a> から登録すると、すべてのチャージで永久 5% 割引をご利用いただけます。</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://code.silkapi.com/register?aff=SUB2API"><img src="assets/partners/logos/silkapi.png" alt="silkapi" width="150"></a></td>
|
||||
<td>SilkAPI のご支援に感謝します!<a href="https://code.silkapi.com/register?aff=SUB2API">SilkAPI</a> は Sub2API をベースに構築された中継サービスで、高速かつ安定した Codex API 中継の提供に特化しています。</td>
|
||||
<td width="180"><a href="https://aigocode.com/invite/SUB2API"><img src="assets/partners/logos/aigocode.png" alt="AIGoCode" width="150"></a></td>
|
||||
<td>AIGoCode のご支援に感謝します!AIGoCode は Claude Code、Codex、最新の Gemini モデルを統合したオールインワンプラットフォームで、安定的かつ効率的でコストパフォーマンスに優れた AI コーディングサービスを提供します。柔軟なサブスクリプションプラン、アカウント停止リスクゼロ、VPN 不要の直接アクセス、超高速レスポンスが特長です。AIGoCode は sub2api ユーザー向けに特別特典を用意しています:<a href="https://aigocode.com/invite/SUB2API">こちらのリンク</a>から登録すると、初回チャージ時に 10% のボーナスクレジットを追加プレゼント!</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
@@ -97,8 +103,8 @@
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://apikl.com"><img src="assets/partners/logos/apikl.png" alt="apikl" width="150"></a></td>
|
||||
<td>Apikl のご支援に感謝します!Sub2API をベースに構築された本プラットフォームは、開発者向けに Codex / Claude シリーズモデルの中継サービスを提供しています。長期安定性、高速直結、高いコストパフォーマンスを重視し、従量課金の残高ベース課金、エンタープライズグレードの正規請求書、1対1の専属サポートを提供します。<a href="https://apikl.com">今すぐ登録</a>でチャージ 1:1 ボーナス — 残高が倍に!
|
||||
<td width="180"><a href="https://apikl.ai"><img src="assets/partners/logos/apikl.png" alt="apikl" width="150"></a></td>
|
||||
<td>Apikl のご支援に感謝します!Sub2API をベースに構築された本プラットフォームは、開発者向けに Codex / Claude シリーズモデルの中継サービスを提供しています。長期安定性、高速直結、高いコストパフォーマンスを重視し、従量課金の残高ベース課金、エンタープライズグレードの正規請求書、1対1の専属サポートを提供します。<a href="https://apikl.ai">今すぐ登録</a>でチャージ 1:1 ボーナス — 残高が倍に!
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -131,6 +137,30 @@
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://anpin.ai"><img src="assets/partners/logos/anpin.jpg" alt="anpin" width="150"></a></td>
|
||||
<td><a href="https://anpin.ai">anpin.ai</a> のご支援に感謝します!anpin.ai は AI の普及推進に取り組むハイエンド AI 中継サービスプラットフォームです。先進的な技術アーキテクチャとグローバル分散デプロイメントにより、国際トップクラスの大規模モデルへの高速直通ルートを提供します。<br>
|
||||
自社構築の一次アカウントプール:1-3秒の超高速応答、同業者への配布に対応<br>
|
||||
極めて高い安定性:マルチライン・インテリジェントルーティング + 冗長バックアップシステムにより、年中無休の高可用性運用を確保;<br>
|
||||
モデルの真正性:一切のコンテンツ介入や二次フィルタリングを行わず、最も純粋で強力なネイティブモデル能力を体験できます。<br>
|
||||
チャージ 1:1、エンタープライズグレードサービスは請求書発行可能。安品 AI は単なる中継所ではなく、最先端のインテリジェント世界へと繋がる安全・信頼性・高効率の橋渡し役です。
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="https://www.proxy4free.com/?keyword=4yjqecpc"><img src="assets/partners/logos/proxy4free.png" alt="proxy4free" width="150"></a></td>
|
||||
<td>Proxy4Free のご支援に感謝します!Proxy4Free は開発者と AI アプリケーション向けのデータプロキシサービスプロバイダーで、住宅プロキシ、静的住宅プロキシ、ISP プロキシ、データセンタープロキシなど多様なプロキシソリューションを提供しており、Web Scraping、Browser Automation、AI Agent などのシナリオに適しています。グローバル IP リソース、安定した接続、柔軟な切り替えをサポートし、開発者のデータ収集成功率の向上と IP ブロックリスクの低減を支援します。<a href="https://www.proxy4free.com/?keyword=4yjqecpc">こちらのリンクから登録</a>して、より安定した効率的な自動化ワークフローを簡単に構築しましょう。
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td width="180"><a href="http://www.fastaitoken.com/register"><img src="assets/partners/logos/fastaitoken.jpg" alt="fastaitoken" width="150"></a></td>
|
||||
<td>🎉 FastAIToken のご支援に感謝します!<a href="http://www.fastaitoken.com/register">FastAIToken</a> は開発者向けの AI API アグリゲーションプラットフォームで、OpenAI、Claude、Gemini などの主要な大規模モデルに対応しています。チャージは 1:1(1 元 = 1 米ドル分の API クレジット)で、開発者がより低コスト・より手軽に世界トップクラスの大規模モデルサービスを利用できます。<br>
|
||||
|
||||
🚀 プラットフォームでは多彩なチャネルを自由に選択できます:超低価格の 0.02x OpenAI 特典グループ(期間限定)、最低 0.25x の OpenAI グループ、0.7x Claude(95% 固定キャッシュ)、1.2x Claude Max チャネル。さらに、各グループの可用率・レイテンシ・稼働状況をリアルタイムで表示する公開ステータスページを提供し、透明で信頼できるサービスを実現。7×24 時間の有人テクニカルサポート(ボットではありません)により、開発者のニーズに迅速に対応します。
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
## 概要
|
||||
@@ -297,6 +327,7 @@ cd sub2api/deploy
|
||||
|
||||
# 2. 環境設定ファイルをコピー
|
||||
cp .env.example .env
|
||||
chmod 600 .env
|
||||
|
||||
# 3. 設定を編集(セキュアなパスワードを生成)
|
||||
nano .env
|
||||
@@ -416,7 +447,23 @@ rm -rf data/ postgres_data/ redis_data/
|
||||
|
||||
---
|
||||
|
||||
### 方法3: ソースからビルド
|
||||
### 方法3: Apple container(macOS)
|
||||
|
||||
Apple シリコン搭載 Mac と macOS 26 では、Apple `container` 1.1.0 以降を使用して Sub2API、PostgreSQL、Redis の完全なスタックを実行できます:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/Wei-Shaw/sub2api.git
|
||||
cd sub2api/deploy
|
||||
./apple-container.sh init
|
||||
./apple-container.sh up
|
||||
./apple-container.sh status
|
||||
```
|
||||
|
||||
これはローカル開発および手動運用向けです。本番環境では引き続き Docker Compose を推奨します。ライフサイクル、永続化、アップグレード、制限については [deploy/APPLE_CONTAINER.md](deploy/APPLE_CONTAINER.md) を参照してください。
|
||||
|
||||
---
|
||||
|
||||
### 方法4: ソースからビルド
|
||||
|
||||
開発やカスタマイズのためにソースコードからビルドして実行します。
|
||||
|
||||
@@ -445,7 +492,8 @@ pnpm run build
|
||||
|
||||
# 4. フロントエンドを組み込んだバックエンドをビルド
|
||||
cd ../backend
|
||||
go build -tags embed -o sub2api ./cmd/server
|
||||
VERSION="$(./scripts/resolve-version.sh)"
|
||||
go build -tags embed -ldflags="-X main.Version=${VERSION}" -o sub2api ./cmd/server
|
||||
|
||||
# 5. 設定ファイルを作成
|
||||
cp ../deploy/config.example.yaml ./config.yaml
|
||||
@@ -508,20 +556,20 @@ default:
|
||||
|
||||
**⚠️ セキュリティ警告: HTTP URL 設定**
|
||||
|
||||
`security.url_allowlist.enabled=false` の場合、システムはデフォルトで最小限の URL バリデーションを行い、**HTTP URL を拒否**して HTTPS のみを許可します。HTTP URL を許可するには(開発環境や内部テスト用など)、以下を明示的に設定する必要があります:
|
||||
`security.url_allowlist.enabled=false` の場合、システムは最小限の URL バリデーションのみを行い、**デフォルトで HTTP URL を許可**します(開発フレンドリーモード。Docker Compose デプロイのデフォルトも同じです)。本番環境では、以下のように明示的に HTTPS のみに制限することを推奨します:
|
||||
|
||||
```yaml
|
||||
security:
|
||||
url_allowlist:
|
||||
enabled: false # 許可リストチェックを無効化
|
||||
allow_insecure_http: true # HTTP URL を許可(⚠️ セキュリティリスクあり)
|
||||
allow_insecure_http: false # HTTPS のみ許可(本番環境推奨)
|
||||
```
|
||||
|
||||
**または環境変数で設定:**
|
||||
|
||||
```bash
|
||||
SECURITY_URL_ALLOWLIST_ENABLED=false
|
||||
SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP=true
|
||||
SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP=false
|
||||
```
|
||||
|
||||
**HTTP を許可するリスク:**
|
||||
@@ -535,7 +583,7 @@ SECURITY_URL_ALLOWLIST_ALLOW_INSECURE_HTTP=true
|
||||
- ✅ HTTPS 取得前のアカウント接続テスト
|
||||
- ❌ 本番環境(HTTPS のみを使用)
|
||||
|
||||
**この設定なしで表示されるエラー例:**
|
||||
**`allow_insecure_http: false` 設定時に HTTP URL で表示されるエラー例:**
|
||||
```
|
||||
Invalid base URL: invalid url scheme: http
|
||||
```
|
||||
@@ -546,6 +594,25 @@ URL バリデーションまたはレスポンスヘッダーフィルタリン
|
||||
- TLS のみのアウトバウンドトラフィックを強制
|
||||
- プロキシで機密性の高い上流レスポンスヘッダーを除去
|
||||
|
||||
#### ⚠️ 重要:管理者アカウントの作成
|
||||
|
||||
初期管理者アカウントは**セットアップウィザード経由でのみ作成**されます(初回起動時に `http://<host>:8080` にアクセス)。`config.yaml` の `default.admin_email` / `default.admin_password` フィールドは**管理者作成には使われません**。テンプレートに残っているのは歴史的経緯によるものです。
|
||||
|
||||
上記ステップ 5 で事前に `config.yaml` を作成しているため、**初回起動時にセットアップウィザードはスキップされます**。サーバーは既存の config を検出して通常モードで直接起動し、この時点では `users` テーブルが空のため、初回ログインは `invalid email or password` を返します。
|
||||
|
||||
**管理者アカウントを作成する 2 つの方法:**
|
||||
|
||||
1. **推奨 — ウィザードに `config.yaml` を自動生成させる:** 上記ステップ 5 をスキップします(`cp` を実行しない)。`./sub2api` を直接起動し、`http://localhost:8080` にアクセスすると、セットアップウィザードがデータベース・Redis・管理者アカウントの設定を案内し、`config.yaml` を自動生成します。
|
||||
|
||||
2. **すでに `config.yaml` を作成してしまった場合:** 初回起動前に一時的に退避してウィザードを発生させ、完了後に戻します:
|
||||
```bash
|
||||
mv config.yaml config.yaml.bak
|
||||
./sub2api # ウィザードが http://localhost:8080 で起動し、新しい config.yaml を生成します
|
||||
# ウィザード完了後、Ctrl+C でサーバーを停止し、設定を復元します:
|
||||
mv config.yaml.bak config.yaml
|
||||
./sub2api # 通常モードで再起動し、作成した管理者でログインします
|
||||
```
|
||||
|
||||
```bash
|
||||
# 6. アプリケーションを実行
|
||||
./sub2api
|
||||
@@ -609,12 +676,6 @@ Antigravity アカウントはオプションの**ハイブリッドスケジュ
|
||||
|
||||
> **⚠️ 警告**: Anthropic Claude と Antigravity Claude は**同じ会話コンテキスト内で混在させることはできません**。グループを使用して適切に分離してください。
|
||||
|
||||
### 既知の問題
|
||||
|
||||
Claude Code では、Plan Mode を自動的に終了できません。(通常、ネイティブの Claude API を使用する場合、計画が完了すると Claude Code はユーザーに計画を承認または拒否するオプションをポップアップ表示します。)
|
||||
|
||||
**回避策**: `Shift + Tab` を押して手動で Plan Mode を終了し、計画を承認または拒否するためのレスポンスを入力してください。
|
||||
|
||||
---
|
||||
|
||||
## プロジェクト構成
|
||||
@@ -645,16 +706,6 @@ sub2api/
|
||||
└── install.sh # ワンクリックインストールスクリプト
|
||||
```
|
||||
|
||||
## 免責事項
|
||||
|
||||
> **本プロジェクトをご利用の前に、以下をよくお読みください:**
|
||||
>
|
||||
> :rotating_light: **利用規約違反のリスク**: 本プロジェクトの使用は Anthropic の利用規約に違反する可能性があります。使用前に Anthropic のユーザー契約をよくお読みください。本プロジェクトの使用に起因するすべてのリスクは、ユーザー自身が負うものとします。
|
||||
>
|
||||
> :book: **免責事項**: 本プロジェクトは技術的な学習および研究目的のみで提供されています。作者は、本プロジェクトの使用によるアカウント停止、サービス中断、その他の損失について一切の責任を負いません。
|
||||
|
||||
---
|
||||
|
||||
## スター履歴
|
||||
|
||||
<a href="https://star-history.com/#Wei-Shaw/sub2api&Date">
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 94 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 7.4 KiB |
+3
-2
@@ -1,4 +1,4 @@
|
||||
FROM golang:1.26.4-alpine
|
||||
FROM golang:1.26.5-alpine
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
@@ -15,7 +15,8 @@ RUN go mod download
|
||||
COPY . .
|
||||
|
||||
# 构建应用
|
||||
RUN go build -o main ./cmd/server/
|
||||
RUN VERSION_VALUE="$(./scripts/resolve-version.sh)" && \
|
||||
go build -ldflags="-s -w -X main.Version=${VERSION_VALUE}" -o main ./cmd/server/
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 8080
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
.PHONY: build generate test test-unit test-integration test-e2e
|
||||
|
||||
VERSION ?= $(shell tr -d '\r\n' < ./cmd/server/VERSION)
|
||||
VERSION ?= $(shell ./scripts/resolve-version.sh)
|
||||
LDFLAGS ?= -s -w -X main.Version=$(VERSION)
|
||||
|
||||
build:
|
||||
|
||||
@@ -1 +1 @@
|
||||
0.1.138
|
||||
0.1.153
|
||||
|
||||
@@ -85,6 +85,8 @@ func provideCleanup(
|
||||
subscriptionExpiry *service.SubscriptionExpiryService,
|
||||
usageCleanup *service.UsageCleanupService,
|
||||
idempotencyCleanup *service.IdempotencyCleanupService,
|
||||
batchImageCleanup *service.BatchImageCleanupService,
|
||||
batchImageWorker *service.BatchImageWorkerRuntime,
|
||||
pricing *service.PricingService,
|
||||
emailQueue *service.EmailQueueService,
|
||||
billingCache *service.BillingCacheService,
|
||||
@@ -167,6 +169,18 @@ func provideCleanup(
|
||||
}
|
||||
return nil
|
||||
}},
|
||||
{"BatchImageCleanupService", func() error {
|
||||
if batchImageCleanup != nil {
|
||||
batchImageCleanup.Stop()
|
||||
}
|
||||
return nil
|
||||
}},
|
||||
{"BatchImageWorkerRuntime", func() error {
|
||||
if batchImageWorker != nil {
|
||||
batchImageWorker.Stop()
|
||||
}
|
||||
return nil
|
||||
}},
|
||||
{"TokenRefreshService", func() error {
|
||||
tokenRefresh.Stop()
|
||||
return nil
|
||||
|
||||
@@ -67,7 +67,11 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
|
||||
serviceUserPlatformQuotaRepository := repository.NewUserPlatformQuotaServiceAdapter(userPlatformQuotaRepository)
|
||||
billingCacheService := service.ProvideBillingCacheService(billingCache, userRepository, userSubscriptionRepository, apiKeyRepository, userRPMCache, userGroupRateRepository, configConfig, serviceUserPlatformQuotaRepository)
|
||||
apiKeyCache := repository.NewAPIKeyCache(redisClient)
|
||||
apiKeyService := service.ProvideAPIKeyService(apiKeyRepository, userRepository, groupRepository, userSubscriptionRepository, userGroupRateRepository, apiKeyCache, configConfig, billingCacheService)
|
||||
concurrencyCache := repository.ProvideConcurrencyCache(redisClient, configConfig)
|
||||
schedulerCache := repository.ProvideSchedulerCache(redisClient, configConfig)
|
||||
accountRepository := repository.NewAccountRepository(client, db, schedulerCache)
|
||||
concurrencyService := service.ProvideConcurrencyService(concurrencyCache, accountRepository, configConfig)
|
||||
apiKeyService := service.ProvideAPIKeyService(apiKeyRepository, userRepository, groupRepository, userSubscriptionRepository, userGroupRateRepository, apiKeyCache, configConfig, billingCacheService, concurrencyService)
|
||||
apiKeyAuthCacheInvalidator := service.ProvideAPIKeyAuthCacheInvalidator(apiKeyService)
|
||||
promoService := service.NewPromoService(promoCodeRepository, userRepository, billingCacheService, client, apiKeyAuthCacheInvalidator)
|
||||
subscriptionService := service.NewSubscriptionService(groupRepository, userSubscriptionRepository, billingCacheService, client, configConfig)
|
||||
@@ -92,10 +96,9 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
|
||||
usageLogRepository := repository.NewUsageLogRepository(client, db)
|
||||
usageService := service.NewUsageService(usageLogRepository, userRepository, client, apiKeyAuthCacheInvalidator)
|
||||
opsRepository := repository.NewOpsRepository(db)
|
||||
schedulerCache := repository.ProvideSchedulerCache(redisClient, configConfig)
|
||||
accountRepository := repository.NewAccountRepository(client, db, schedulerCache)
|
||||
concurrencyCache := repository.ProvideConcurrencyCache(redisClient, configConfig)
|
||||
concurrencyService := service.ProvideConcurrencyService(concurrencyCache, accountRepository, configConfig)
|
||||
batchImageRepository := repository.NewBatchImageRepository(db)
|
||||
batchImageQueue := repository.NewBatchImageQueue(redisClient, configConfig)
|
||||
batchImageDownloadLimiter := repository.NewBatchImageDownloadLimiter(redisClient, configConfig)
|
||||
usageBillingRepository := repository.NewUsageBillingRepository(client, db)
|
||||
gatewayCache := repository.NewGatewayCache(redisClient)
|
||||
schedulerOutboxRepository := repository.NewSchedulerOutboxRepository(db)
|
||||
@@ -134,6 +137,11 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
|
||||
channelRepository := repository.NewChannelRepository(db)
|
||||
channelService := service.NewChannelService(channelRepository, groupRepository, apiKeyAuthCacheInvalidator, pricingService)
|
||||
modelPricingResolver := service.NewModelPricingResolver(channelService, billingService)
|
||||
batchImageModelPricingResolver := service.ProvideBatchImageModelPricingResolver(modelPricingResolver)
|
||||
batchImagePublicService := service.NewBatchImagePublicService(batchImageRepository, accountRepository, groupRepository, userGroupRateRepository, batchImageQueue, batchImageModelPricingResolver, usageBillingRepository, apiKeyAuthCacheInvalidator, configConfig)
|
||||
batchImageDownloadService := service.NewBatchImageDownloadService(batchImageRepository, accountRepository, batchImageDownloadLimiter, configConfig)
|
||||
batchImageCleanupService := service.ProvideBatchImageCleanupService(batchImageRepository, accountRepository, configConfig)
|
||||
batchImageWorkerRuntime := service.ProvideBatchImageWorkerRuntime(batchImageRepository, accountRepository, batchImageQueue, usageBillingRepository, usageLogRepository, batchImageModelPricingResolver, apiKeyAuthCacheInvalidator, configConfig)
|
||||
notificationEmailService := service.NewNotificationEmailService(settingRepository, emailService)
|
||||
balanceNotifyService := service.ProvideBalanceNotifyService(emailService, settingRepository, accountRepository, notificationEmailService)
|
||||
gatewayService := service.NewGatewayService(accountRepository, groupRepository, usageLogRepository, usageBillingRepository, userRepository, userSubscriptionRepository, userGroupRateRepository, gatewayCache, configConfig, schedulerSnapshotService, concurrencyService, billingService, rateLimitService, billingCacheService, identityService, httpUpstream, deferredService, claudeTokenProvider, sessionLimitCache, rpmCache, digestSessionStore, settingService, tlsFingerprintProfileService, channelService, modelPricingResolver, balanceNotifyService, serviceUserPlatformQuotaRepository)
|
||||
@@ -182,11 +190,13 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
|
||||
claudeUsageFetcher := repository.NewClaudeUsageFetcher(httpUpstream)
|
||||
antigravityQuotaFetcher := service.NewAntigravityQuotaFetcher(proxyRepository)
|
||||
grokQuotaFetcher := service.NewGrokQuotaFetcher()
|
||||
grokQuotaService := service.ProvideGrokQuotaService(accountRepository, proxyRepository, grokTokenProvider, httpUpstream, usageLogRepository)
|
||||
openAIQuotaService := service.ProvideOpenAIQuotaService(accountRepository, proxyRepository, openAITokenProvider, privacyClientFactory)
|
||||
usageCache := service.NewUsageCache()
|
||||
accountUsageService := service.NewAccountUsageService(accountRepository, usageLogRepository, claudeUsageFetcher, geminiQuotaService, antigravityQuotaFetcher, grokQuotaFetcher, usageCache, identityCache, tlsFingerprintProfileService)
|
||||
accountTestService := service.NewAccountTestService(accountRepository, geminiTokenProvider, claudeTokenProvider, antigravityGatewayService, httpUpstream, configConfig, tlsFingerprintProfileService)
|
||||
accountUsageService := service.NewAccountUsageService(accountRepository, usageLogRepository, claudeUsageFetcher, geminiQuotaService, antigravityQuotaFetcher, grokQuotaFetcher, grokQuotaService, openAIQuotaService, usageCache, identityCache, tlsFingerprintProfileService)
|
||||
accountTestService := service.NewAccountTestService(accountRepository, geminiTokenProvider, claudeTokenProvider, grokTokenProvider, antigravityGatewayService, httpUpstream, configConfig, tlsFingerprintProfileService)
|
||||
crsSyncService := service.NewCRSSyncService(accountRepository, proxyRepository, oAuthService, openAIOAuthService, geminiOAuthService, configConfig)
|
||||
accountHandler := admin.NewAccountHandler(adminService, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService, rateLimitService, accountUsageService, accountTestService, concurrencyService, crsSyncService, sessionLimitCache, rpmCache, compositeTokenCacheInvalidator)
|
||||
accountHandler := admin.ProvideAccountHandler(adminService, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService, rateLimitService, accountUsageService, accountTestService, concurrencyService, crsSyncService, sessionLimitCache, rpmCache, compositeTokenCacheInvalidator, grokQuotaService)
|
||||
adminAnnouncementHandler := admin.NewAnnouncementHandler(announcementService)
|
||||
dataManagementService := service.NewDataManagementService()
|
||||
dataManagementHandler := admin.NewDataManagementHandler(dataManagementService)
|
||||
@@ -195,11 +205,9 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
|
||||
backupService := service.ProvideBackupService(settingRepository, configConfig, secretEncryptor, backupObjectStoreFactory, dbDumper)
|
||||
backupHandler := admin.NewBackupHandler(backupService, userService)
|
||||
oAuthHandler := admin.NewOAuthHandler(oAuthService)
|
||||
openAIQuotaService := service.ProvideOpenAIQuotaService(accountRepository, proxyRepository, openAITokenProvider, privacyClientFactory)
|
||||
openAIOAuthHandler := admin.NewOpenAIOAuthHandler(openAIOAuthService, adminService, openAIQuotaService)
|
||||
geminiOAuthHandler := admin.NewGeminiOAuthHandler(geminiOAuthService)
|
||||
antigravityOAuthHandler := admin.NewAntigravityOAuthHandler(antigravityOAuthService)
|
||||
grokQuotaService := service.ProvideGrokQuotaService(accountRepository, proxyRepository, grokTokenProvider, httpUpstream)
|
||||
grokOAuthHandler := admin.NewGrokOAuthHandler(grokOAuthService, adminService, grokQuotaService)
|
||||
proxyHandler := admin.NewProxyHandler(adminService)
|
||||
adminRedeemHandler := admin.NewRedeemHandler(adminService, redeemService)
|
||||
@@ -256,12 +264,13 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
|
||||
openAIGatewayHandler := handler.NewOpenAIGatewayHandler(openAIGatewayService, concurrencyService, billingCacheService, apiKeyService, usageRecordWorkerPool, errorPassthroughService, contentModerationService, opsService, configConfig)
|
||||
handlerSettingHandler := handler.ProvideSettingHandler(settingService, buildInfo, notificationEmailService)
|
||||
totpHandler := handler.NewTotpHandler(totpService)
|
||||
handlerPaymentHandler := handler.NewPaymentHandler(paymentService, paymentConfigService, channelService)
|
||||
handlerPaymentHandler := handler.NewPaymentHandler(paymentService, paymentConfigService)
|
||||
paymentWebhookHandler := handler.NewPaymentWebhookHandler(paymentService, registry)
|
||||
availableChannelHandler := handler.NewAvailableChannelHandler(channelService, apiKeyService, settingService)
|
||||
batchImageHandler := handler.NewBatchImageHandler(batchImagePublicService, batchImageDownloadService, batchImageCleanupService)
|
||||
idempotencyCoordinator := service.ProvideIdempotencyCoordinator(idempotencyRepository, configConfig)
|
||||
idempotencyCleanupService := service.ProvideIdempotencyCleanupService(idempotencyRepository, configConfig)
|
||||
handlers := handler.ProvideHandlers(authHandler, userHandler, apiKeyHandler, usageHandler, redeemHandler, subscriptionHandler, announcementHandler, channelMonitorUserHandler, adminHandlers, gatewayHandler, openAIGatewayHandler, handlerSettingHandler, totpHandler, handlerPaymentHandler, paymentWebhookHandler, availableChannelHandler, idempotencyCoordinator, idempotencyCleanupService)
|
||||
handlers := handler.ProvideHandlers(authHandler, userHandler, apiKeyHandler, usageHandler, redeemHandler, subscriptionHandler, announcementHandler, channelMonitorUserHandler, adminHandlers, gatewayHandler, openAIGatewayHandler, handlerSettingHandler, totpHandler, handlerPaymentHandler, paymentWebhookHandler, availableChannelHandler, batchImageHandler, idempotencyCoordinator, idempotencyCleanupService)
|
||||
jwtAuthMiddleware := middleware.NewJWTAuthMiddleware(authService, userService)
|
||||
adminAuthMiddleware := middleware.NewAdminAuthMiddleware(authService, userService, settingService)
|
||||
apiKeyAuthMiddleware := middleware.NewAPIKeyAuthMiddleware(apiKeyService, subscriptionService, configConfig)
|
||||
@@ -280,7 +289,7 @@ func initializeApplication(buildInfo handler.BuildInfo) (*Application, error) {
|
||||
paymentOrderExpiryService := service.ProvidePaymentOrderExpiryService(paymentService, leaderLockCache, db)
|
||||
channelMonitorRunner := service.ProvideChannelMonitorRunner(channelMonitorService, settingService)
|
||||
userPlatformQuotaUsageFlusher := service.ProvideUserPlatformQuotaUsageFlusher(configConfig, billingCache, serviceUserPlatformQuotaRepository, timingWheelService)
|
||||
v := provideCleanup(client, redisClient, opsMetricsCollector, opsAggregationService, opsAlertEvaluatorService, opsCleanupService, opsScheduledReportService, opsSystemLogSink, schedulerSnapshotService, tokenRefreshService, accountExpiryService, proxyExpiryService, subscriptionExpiryService, usageCleanupService, idempotencyCleanupService, pricingService, emailQueueService, billingCacheService, usageRecordWorkerPool, subscriptionService, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService, grokOAuthService, openAIGatewayService, scheduledTestRunnerService, backupService, paymentOrderExpiryService, channelMonitorRunner, userPlatformQuotaUsageFlusher)
|
||||
v := provideCleanup(client, redisClient, opsMetricsCollector, opsAggregationService, opsAlertEvaluatorService, opsCleanupService, opsScheduledReportService, opsSystemLogSink, schedulerSnapshotService, tokenRefreshService, accountExpiryService, proxyExpiryService, subscriptionExpiryService, usageCleanupService, idempotencyCleanupService, batchImageCleanupService, batchImageWorkerRuntime, pricingService, emailQueueService, billingCacheService, usageRecordWorkerPool, subscriptionService, oAuthService, openAIOAuthService, geminiOAuthService, antigravityOAuthService, grokOAuthService, openAIGatewayService, scheduledTestRunnerService, backupService, paymentOrderExpiryService, channelMonitorRunner, userPlatformQuotaUsageFlusher)
|
||||
application := &Application{
|
||||
Server: httpServer,
|
||||
Cleanup: v,
|
||||
@@ -322,6 +331,8 @@ func provideCleanup(
|
||||
subscriptionExpiry *service.SubscriptionExpiryService,
|
||||
usageCleanup *service.UsageCleanupService,
|
||||
idempotencyCleanup *service.IdempotencyCleanupService,
|
||||
batchImageCleanup *service.BatchImageCleanupService,
|
||||
batchImageWorker *service.BatchImageWorkerRuntime,
|
||||
pricing *service.PricingService,
|
||||
emailQueue *service.EmailQueueService,
|
||||
billingCache *service.BillingCacheService,
|
||||
@@ -403,6 +414,18 @@ func provideCleanup(
|
||||
}
|
||||
return nil
|
||||
}},
|
||||
{"BatchImageCleanupService", func() error {
|
||||
if batchImageCleanup != nil {
|
||||
batchImageCleanup.Stop()
|
||||
}
|
||||
return nil
|
||||
}},
|
||||
{"BatchImageWorkerRuntime", func() error {
|
||||
if batchImageWorker != nil {
|
||||
batchImageWorker.Stop()
|
||||
}
|
||||
return nil
|
||||
}},
|
||||
{"TokenRefreshService", func() error {
|
||||
tokenRefresh.Stop()
|
||||
return nil
|
||||
|
||||
@@ -65,6 +65,8 @@ func TestProvideCleanup_WithMinimalDependencies_NoPanic(t *testing.T) {
|
||||
subscriptionExpirySvc,
|
||||
&service.UsageCleanupService{},
|
||||
idempotencyCleanupSvc,
|
||||
&service.BatchImageCleanupService{},
|
||||
nil, // batchImageWorker
|
||||
pricingSvc,
|
||||
emailQueueSvc,
|
||||
billingCacheSvc,
|
||||
|
||||
+64
-5
@@ -77,6 +77,10 @@ type Account struct {
|
||||
SessionWindowEnd *time.Time `json:"session_window_end,omitempty"`
|
||||
// SessionWindowStatus holds the value of the "session_window_status" field.
|
||||
SessionWindowStatus *string `json:"session_window_status,omitempty"`
|
||||
// Parent account id for a linked spark shadow (NULL = normal).
|
||||
ParentAccountID *int64 `json:"parent_account_id,omitempty"`
|
||||
// 'global' (default) or 'spark' (shadow reads codex_bengalfox).
|
||||
QuotaDimension account.QuotaDimension `json:"quota_dimension,omitempty"`
|
||||
// Edges holds the relations/edges for other nodes in the graph.
|
||||
// The values are being populated by the AccountQuery when eager-loading is set.
|
||||
Edges AccountEdges `json:"edges"`
|
||||
@@ -89,13 +93,17 @@ type AccountEdges struct {
|
||||
Groups []*Group `json:"groups,omitempty"`
|
||||
// Proxy holds the value of the proxy edge.
|
||||
Proxy *Proxy `json:"proxy,omitempty"`
|
||||
// Parent holds the value of the parent edge.
|
||||
Parent *Account `json:"parent,omitempty"`
|
||||
// Children holds the value of the children edge.
|
||||
Children []*Account `json:"children,omitempty"`
|
||||
// UsageLogs holds the value of the usage_logs edge.
|
||||
UsageLogs []*UsageLog `json:"usage_logs,omitempty"`
|
||||
// AccountGroups holds the value of the account_groups edge.
|
||||
AccountGroups []*AccountGroup `json:"account_groups,omitempty"`
|
||||
// loadedTypes holds the information for reporting if a
|
||||
// type was loaded (or requested) in eager-loading or not.
|
||||
loadedTypes [4]bool
|
||||
loadedTypes [6]bool
|
||||
}
|
||||
|
||||
// GroupsOrErr returns the Groups value or an error if the edge
|
||||
@@ -118,10 +126,30 @@ func (e AccountEdges) ProxyOrErr() (*Proxy, error) {
|
||||
return nil, &NotLoadedError{edge: "proxy"}
|
||||
}
|
||||
|
||||
// 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 AccountEdges) ParentOrErr() (*Account, error) {
|
||||
if e.Parent != nil {
|
||||
return e.Parent, nil
|
||||
} else if e.loadedTypes[2] {
|
||||
return nil, &NotFoundError{label: account.Label}
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "parent"}
|
||||
}
|
||||
|
||||
// ChildrenOrErr returns the Children value or an error if the edge
|
||||
// was not loaded in eager-loading.
|
||||
func (e AccountEdges) ChildrenOrErr() ([]*Account, error) {
|
||||
if e.loadedTypes[3] {
|
||||
return e.Children, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "children"}
|
||||
}
|
||||
|
||||
// UsageLogsOrErr returns the UsageLogs value or an error if the edge
|
||||
// was not loaded in eager-loading.
|
||||
func (e AccountEdges) UsageLogsOrErr() ([]*UsageLog, error) {
|
||||
if e.loadedTypes[2] {
|
||||
if e.loadedTypes[4] {
|
||||
return e.UsageLogs, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "usage_logs"}
|
||||
@@ -130,7 +158,7 @@ func (e AccountEdges) UsageLogsOrErr() ([]*UsageLog, error) {
|
||||
// AccountGroupsOrErr returns the AccountGroups value or an error if the edge
|
||||
// was not loaded in eager-loading.
|
||||
func (e AccountEdges) AccountGroupsOrErr() ([]*AccountGroup, error) {
|
||||
if e.loadedTypes[3] {
|
||||
if e.loadedTypes[5] {
|
||||
return e.AccountGroups, nil
|
||||
}
|
||||
return nil, &NotLoadedError{edge: "account_groups"}
|
||||
@@ -147,9 +175,9 @@ func (*Account) scanValues(columns []string) ([]any, error) {
|
||||
values[i] = new(sql.NullBool)
|
||||
case account.FieldRateMultiplier:
|
||||
values[i] = new(sql.NullFloat64)
|
||||
case account.FieldID, account.FieldProxyID, account.FieldProxyFallbackOriginID, account.FieldConcurrency, account.FieldLoadFactor, account.FieldPriority:
|
||||
case account.FieldID, account.FieldProxyID, account.FieldProxyFallbackOriginID, account.FieldConcurrency, account.FieldLoadFactor, account.FieldPriority, account.FieldParentAccountID:
|
||||
values[i] = new(sql.NullInt64)
|
||||
case account.FieldName, account.FieldNotes, account.FieldPlatform, account.FieldType, account.FieldStatus, account.FieldErrorMessage, account.FieldTempUnschedulableReason, account.FieldSessionWindowStatus:
|
||||
case account.FieldName, account.FieldNotes, account.FieldPlatform, account.FieldType, account.FieldStatus, account.FieldErrorMessage, account.FieldTempUnschedulableReason, account.FieldSessionWindowStatus, account.FieldQuotaDimension:
|
||||
values[i] = new(sql.NullString)
|
||||
case account.FieldCreatedAt, account.FieldUpdatedAt, account.FieldDeletedAt, account.FieldLastUsedAt, account.FieldExpiresAt, account.FieldRateLimitedAt, account.FieldRateLimitResetAt, account.FieldOverloadUntil, account.FieldTempUnschedulableUntil, account.FieldSessionWindowStart, account.FieldSessionWindowEnd:
|
||||
values[i] = new(sql.NullTime)
|
||||
@@ -368,6 +396,19 @@ func (_m *Account) assignValues(columns []string, values []any) error {
|
||||
_m.SessionWindowStatus = new(string)
|
||||
*_m.SessionWindowStatus = value.String
|
||||
}
|
||||
case account.FieldParentAccountID:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field parent_account_id", values[i])
|
||||
} else if value.Valid {
|
||||
_m.ParentAccountID = new(int64)
|
||||
*_m.ParentAccountID = value.Int64
|
||||
}
|
||||
case account.FieldQuotaDimension:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field quota_dimension", values[i])
|
||||
} else if value.Valid {
|
||||
_m.QuotaDimension = account.QuotaDimension(value.String)
|
||||
}
|
||||
default:
|
||||
_m.selectValues.Set(columns[i], values[i])
|
||||
}
|
||||
@@ -391,6 +432,16 @@ func (_m *Account) QueryProxy() *ProxyQuery {
|
||||
return NewAccountClient(_m.config).QueryProxy(_m)
|
||||
}
|
||||
|
||||
// QueryParent queries the "parent" edge of the Account entity.
|
||||
func (_m *Account) QueryParent() *AccountQuery {
|
||||
return NewAccountClient(_m.config).QueryParent(_m)
|
||||
}
|
||||
|
||||
// QueryChildren queries the "children" edge of the Account entity.
|
||||
func (_m *Account) QueryChildren() *AccountQuery {
|
||||
return NewAccountClient(_m.config).QueryChildren(_m)
|
||||
}
|
||||
|
||||
// QueryUsageLogs queries the "usage_logs" edge of the Account entity.
|
||||
func (_m *Account) QueryUsageLogs() *UsageLogQuery {
|
||||
return NewAccountClient(_m.config).QueryUsageLogs(_m)
|
||||
@@ -542,6 +593,14 @@ func (_m *Account) String() string {
|
||||
builder.WriteString("session_window_status=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.ParentAccountID; v != nil {
|
||||
builder.WriteString("parent_account_id=")
|
||||
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("quota_dimension=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.QuotaDimension))
|
||||
builder.WriteByte(')')
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
package account
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"entgo.io/ent"
|
||||
@@ -73,10 +74,18 @@ const (
|
||||
FieldSessionWindowEnd = "session_window_end"
|
||||
// FieldSessionWindowStatus holds the string denoting the session_window_status field in the database.
|
||||
FieldSessionWindowStatus = "session_window_status"
|
||||
// FieldParentAccountID holds the string denoting the parent_account_id field in the database.
|
||||
FieldParentAccountID = "parent_account_id"
|
||||
// FieldQuotaDimension holds the string denoting the quota_dimension field in the database.
|
||||
FieldQuotaDimension = "quota_dimension"
|
||||
// EdgeGroups holds the string denoting the groups edge name in mutations.
|
||||
EdgeGroups = "groups"
|
||||
// EdgeProxy holds the string denoting the proxy edge name in mutations.
|
||||
EdgeProxy = "proxy"
|
||||
// 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"
|
||||
// EdgeUsageLogs holds the string denoting the usage_logs edge name in mutations.
|
||||
EdgeUsageLogs = "usage_logs"
|
||||
// EdgeAccountGroups holds the string denoting the account_groups edge name in mutations.
|
||||
@@ -95,6 +104,14 @@ const (
|
||||
ProxyInverseTable = "proxies"
|
||||
// ProxyColumn is the table column denoting the proxy relation/edge.
|
||||
ProxyColumn = "proxy_id"
|
||||
// ParentTable is the table that holds the parent relation/edge.
|
||||
ParentTable = "accounts"
|
||||
// ParentColumn is the table column denoting the parent relation/edge.
|
||||
ParentColumn = "parent_account_id"
|
||||
// ChildrenTable is the table that holds the children relation/edge.
|
||||
ChildrenTable = "accounts"
|
||||
// ChildrenColumn is the table column denoting the children relation/edge.
|
||||
ChildrenColumn = "parent_account_id"
|
||||
// UsageLogsTable is the table that holds the usage_logs relation/edge.
|
||||
UsageLogsTable = "usage_logs"
|
||||
// UsageLogsInverseTable is the table name for the UsageLog entity.
|
||||
@@ -143,6 +160,8 @@ var Columns = []string{
|
||||
FieldSessionWindowStart,
|
||||
FieldSessionWindowEnd,
|
||||
FieldSessionWindowStatus,
|
||||
FieldParentAccountID,
|
||||
FieldQuotaDimension,
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -203,6 +222,32 @@ var (
|
||||
SessionWindowStatusValidator func(string) error
|
||||
)
|
||||
|
||||
// QuotaDimension defines the type for the "quota_dimension" enum field.
|
||||
type QuotaDimension string
|
||||
|
||||
// QuotaDimensionGlobal is the default value of the QuotaDimension enum.
|
||||
const DefaultQuotaDimension = QuotaDimensionGlobal
|
||||
|
||||
// QuotaDimension values.
|
||||
const (
|
||||
QuotaDimensionGlobal QuotaDimension = "global"
|
||||
QuotaDimensionSpark QuotaDimension = "spark"
|
||||
)
|
||||
|
||||
func (qd QuotaDimension) String() string {
|
||||
return string(qd)
|
||||
}
|
||||
|
||||
// QuotaDimensionValidator is a validator for the "quota_dimension" field enum values. It is called by the builders before save.
|
||||
func QuotaDimensionValidator(qd QuotaDimension) error {
|
||||
switch qd {
|
||||
case QuotaDimensionGlobal, QuotaDimensionSpark:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("account: invalid enum value for quota_dimension field: %q", qd)
|
||||
}
|
||||
}
|
||||
|
||||
// OrderOption defines the ordering options for the Account queries.
|
||||
type OrderOption func(*sql.Selector)
|
||||
|
||||
@@ -346,6 +391,16 @@ func BySessionWindowStatus(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldSessionWindowStatus, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByParentAccountID orders the results by the parent_account_id field.
|
||||
func ByParentAccountID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldParentAccountID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByQuotaDimension orders the results by the quota_dimension field.
|
||||
func ByQuotaDimension(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldQuotaDimension, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByGroupsCount orders the results by groups count.
|
||||
func ByGroupsCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
@@ -367,6 +422,27 @@ func ByProxyField(field string, opts ...sql.OrderTermOption) OrderOption {
|
||||
}
|
||||
}
|
||||
|
||||
// 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...)...)
|
||||
}
|
||||
}
|
||||
|
||||
// ByUsageLogsCount orders the results by usage_logs count.
|
||||
func ByUsageLogsCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return func(s *sql.Selector) {
|
||||
@@ -408,6 +484,20 @@ func newProxyStep() *sqlgraph.Step {
|
||||
sqlgraph.Edge(sqlgraph.M2O, false, ProxyTable, ProxyColumn),
|
||||
)
|
||||
}
|
||||
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 newUsageLogsStep() *sqlgraph.Step {
|
||||
return sqlgraph.NewStep(
|
||||
sqlgraph.From(Table, FieldID),
|
||||
|
||||
@@ -190,6 +190,11 @@ func SessionWindowStatus(v string) predicate.Account {
|
||||
return predicate.Account(sql.FieldEQ(FieldSessionWindowStatus, v))
|
||||
}
|
||||
|
||||
// ParentAccountID applies equality check predicate on the "parent_account_id" field. It's identical to ParentAccountIDEQ.
|
||||
func ParentAccountID(v int64) predicate.Account {
|
||||
return predicate.Account(sql.FieldEQ(FieldParentAccountID, v))
|
||||
}
|
||||
|
||||
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
|
||||
func CreatedAtEQ(v time.Time) predicate.Account {
|
||||
return predicate.Account(sql.FieldEQ(FieldCreatedAt, v))
|
||||
@@ -1550,6 +1555,56 @@ func SessionWindowStatusContainsFold(v string) predicate.Account {
|
||||
return predicate.Account(sql.FieldContainsFold(FieldSessionWindowStatus, v))
|
||||
}
|
||||
|
||||
// ParentAccountIDEQ applies the EQ predicate on the "parent_account_id" field.
|
||||
func ParentAccountIDEQ(v int64) predicate.Account {
|
||||
return predicate.Account(sql.FieldEQ(FieldParentAccountID, v))
|
||||
}
|
||||
|
||||
// ParentAccountIDNEQ applies the NEQ predicate on the "parent_account_id" field.
|
||||
func ParentAccountIDNEQ(v int64) predicate.Account {
|
||||
return predicate.Account(sql.FieldNEQ(FieldParentAccountID, v))
|
||||
}
|
||||
|
||||
// ParentAccountIDIn applies the In predicate on the "parent_account_id" field.
|
||||
func ParentAccountIDIn(vs ...int64) predicate.Account {
|
||||
return predicate.Account(sql.FieldIn(FieldParentAccountID, vs...))
|
||||
}
|
||||
|
||||
// ParentAccountIDNotIn applies the NotIn predicate on the "parent_account_id" field.
|
||||
func ParentAccountIDNotIn(vs ...int64) predicate.Account {
|
||||
return predicate.Account(sql.FieldNotIn(FieldParentAccountID, vs...))
|
||||
}
|
||||
|
||||
// ParentAccountIDIsNil applies the IsNil predicate on the "parent_account_id" field.
|
||||
func ParentAccountIDIsNil() predicate.Account {
|
||||
return predicate.Account(sql.FieldIsNull(FieldParentAccountID))
|
||||
}
|
||||
|
||||
// ParentAccountIDNotNil applies the NotNil predicate on the "parent_account_id" field.
|
||||
func ParentAccountIDNotNil() predicate.Account {
|
||||
return predicate.Account(sql.FieldNotNull(FieldParentAccountID))
|
||||
}
|
||||
|
||||
// QuotaDimensionEQ applies the EQ predicate on the "quota_dimension" field.
|
||||
func QuotaDimensionEQ(v QuotaDimension) predicate.Account {
|
||||
return predicate.Account(sql.FieldEQ(FieldQuotaDimension, v))
|
||||
}
|
||||
|
||||
// QuotaDimensionNEQ applies the NEQ predicate on the "quota_dimension" field.
|
||||
func QuotaDimensionNEQ(v QuotaDimension) predicate.Account {
|
||||
return predicate.Account(sql.FieldNEQ(FieldQuotaDimension, v))
|
||||
}
|
||||
|
||||
// QuotaDimensionIn applies the In predicate on the "quota_dimension" field.
|
||||
func QuotaDimensionIn(vs ...QuotaDimension) predicate.Account {
|
||||
return predicate.Account(sql.FieldIn(FieldQuotaDimension, vs...))
|
||||
}
|
||||
|
||||
// QuotaDimensionNotIn applies the NotIn predicate on the "quota_dimension" field.
|
||||
func QuotaDimensionNotIn(vs ...QuotaDimension) predicate.Account {
|
||||
return predicate.Account(sql.FieldNotIn(FieldQuotaDimension, vs...))
|
||||
}
|
||||
|
||||
// HasGroups applies the HasEdge predicate on the "groups" edge.
|
||||
func HasGroups() predicate.Account {
|
||||
return predicate.Account(func(s *sql.Selector) {
|
||||
@@ -1596,6 +1651,52 @@ func HasProxyWith(preds ...predicate.Proxy) predicate.Account {
|
||||
})
|
||||
}
|
||||
|
||||
// HasParent applies the HasEdge predicate on the "parent" edge.
|
||||
func HasParent() predicate.Account {
|
||||
return predicate.Account(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.Account) predicate.Account {
|
||||
return predicate.Account(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.Account {
|
||||
return predicate.Account(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.Account) predicate.Account {
|
||||
return predicate.Account(func(s *sql.Selector) {
|
||||
step := newChildrenStep()
|
||||
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
|
||||
for _, p := range preds {
|
||||
p(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// HasUsageLogs applies the HasEdge predicate on the "usage_logs" edge.
|
||||
func HasUsageLogs() predicate.Account {
|
||||
return predicate.Account(func(s *sql.Selector) {
|
||||
|
||||
@@ -391,6 +391,34 @@ func (_c *AccountCreate) SetNillableSessionWindowStatus(v *string) *AccountCreat
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetParentAccountID sets the "parent_account_id" field.
|
||||
func (_c *AccountCreate) SetParentAccountID(v int64) *AccountCreate {
|
||||
_c.mutation.SetParentAccountID(v)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetNillableParentAccountID sets the "parent_account_id" field if the given value is not nil.
|
||||
func (_c *AccountCreate) SetNillableParentAccountID(v *int64) *AccountCreate {
|
||||
if v != nil {
|
||||
_c.SetParentAccountID(*v)
|
||||
}
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetQuotaDimension sets the "quota_dimension" field.
|
||||
func (_c *AccountCreate) SetQuotaDimension(v account.QuotaDimension) *AccountCreate {
|
||||
_c.mutation.SetQuotaDimension(v)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetNillableQuotaDimension sets the "quota_dimension" field if the given value is not nil.
|
||||
func (_c *AccountCreate) SetNillableQuotaDimension(v *account.QuotaDimension) *AccountCreate {
|
||||
if v != nil {
|
||||
_c.SetQuotaDimension(*v)
|
||||
}
|
||||
return _c
|
||||
}
|
||||
|
||||
// AddGroupIDs adds the "groups" edge to the Group entity by IDs.
|
||||
func (_c *AccountCreate) AddGroupIDs(ids ...int64) *AccountCreate {
|
||||
_c.mutation.AddGroupIDs(ids...)
|
||||
@@ -411,6 +439,40 @@ func (_c *AccountCreate) SetProxy(v *Proxy) *AccountCreate {
|
||||
return _c.SetProxyID(v.ID)
|
||||
}
|
||||
|
||||
// SetParentID sets the "parent" edge to the Account entity by ID.
|
||||
func (_c *AccountCreate) SetParentID(id int64) *AccountCreate {
|
||||
_c.mutation.SetParentID(id)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetNillableParentID sets the "parent" edge to the Account entity by ID if the given value is not nil.
|
||||
func (_c *AccountCreate) SetNillableParentID(id *int64) *AccountCreate {
|
||||
if id != nil {
|
||||
_c = _c.SetParentID(*id)
|
||||
}
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetParent sets the "parent" edge to the Account entity.
|
||||
func (_c *AccountCreate) SetParent(v *Account) *AccountCreate {
|
||||
return _c.SetParentID(v.ID)
|
||||
}
|
||||
|
||||
// AddChildIDs adds the "children" edge to the Account entity by IDs.
|
||||
func (_c *AccountCreate) AddChildIDs(ids ...int64) *AccountCreate {
|
||||
_c.mutation.AddChildIDs(ids...)
|
||||
return _c
|
||||
}
|
||||
|
||||
// AddChildren adds the "children" edges to the Account entity.
|
||||
func (_c *AccountCreate) AddChildren(v ...*Account) *AccountCreate {
|
||||
ids := make([]int64, len(v))
|
||||
for i := range v {
|
||||
ids[i] = v[i].ID
|
||||
}
|
||||
return _c.AddChildIDs(ids...)
|
||||
}
|
||||
|
||||
// AddUsageLogIDs adds the "usage_logs" edge to the UsageLog entity by IDs.
|
||||
func (_c *AccountCreate) AddUsageLogIDs(ids ...int64) *AccountCreate {
|
||||
_c.mutation.AddUsageLogIDs(ids...)
|
||||
@@ -515,6 +577,10 @@ func (_c *AccountCreate) defaults() error {
|
||||
v := account.DefaultSchedulable
|
||||
_c.mutation.SetSchedulable(v)
|
||||
}
|
||||
if _, ok := _c.mutation.QuotaDimension(); !ok {
|
||||
v := account.DefaultQuotaDimension
|
||||
_c.mutation.SetQuotaDimension(v)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -584,6 +650,14 @@ func (_c *AccountCreate) check() error {
|
||||
return &ValidationError{Name: "session_window_status", err: fmt.Errorf(`ent: validator failed for field "Account.session_window_status": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := _c.mutation.QuotaDimension(); !ok {
|
||||
return &ValidationError{Name: "quota_dimension", err: errors.New(`ent: missing required field "Account.quota_dimension"`)}
|
||||
}
|
||||
if v, ok := _c.mutation.QuotaDimension(); ok {
|
||||
if err := account.QuotaDimensionValidator(v); err != nil {
|
||||
return &ValidationError{Name: "quota_dimension", err: fmt.Errorf(`ent: validator failed for field "Account.quota_dimension": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -723,6 +797,10 @@ func (_c *AccountCreate) createSpec() (*Account, *sqlgraph.CreateSpec) {
|
||||
_spec.SetField(account.FieldSessionWindowStatus, field.TypeString, value)
|
||||
_node.SessionWindowStatus = &value
|
||||
}
|
||||
if value, ok := _c.mutation.QuotaDimension(); ok {
|
||||
_spec.SetField(account.FieldQuotaDimension, field.TypeEnum, value)
|
||||
_node.QuotaDimension = value
|
||||
}
|
||||
if nodes := _c.mutation.GroupsIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2M,
|
||||
@@ -760,6 +838,39 @@ func (_c *AccountCreate) createSpec() (*Account, *sqlgraph.CreateSpec) {
|
||||
_node.ProxyID = &nodes[0]
|
||||
_spec.Edges = append(_spec.Edges, edge)
|
||||
}
|
||||
if nodes := _c.mutation.ParentIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: account.ParentTable,
|
||||
Columns: []string{account.ParentColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(account.FieldID, field.TypeInt64),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_node.ParentAccountID = &nodes[0]
|
||||
_spec.Edges = append(_spec.Edges, edge)
|
||||
}
|
||||
if nodes := _c.mutation.ChildrenIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: account.ChildrenTable,
|
||||
Columns: []string{account.ChildrenColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(account.FieldID, field.TypeInt64),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges = append(_spec.Edges, edge)
|
||||
}
|
||||
if nodes := _c.mutation.UsageLogsIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
@@ -1290,6 +1401,36 @@ func (u *AccountUpsert) ClearSessionWindowStatus() *AccountUpsert {
|
||||
return u
|
||||
}
|
||||
|
||||
// SetParentAccountID sets the "parent_account_id" field.
|
||||
func (u *AccountUpsert) SetParentAccountID(v int64) *AccountUpsert {
|
||||
u.Set(account.FieldParentAccountID, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateParentAccountID sets the "parent_account_id" field to the value that was provided on create.
|
||||
func (u *AccountUpsert) UpdateParentAccountID() *AccountUpsert {
|
||||
u.SetExcluded(account.FieldParentAccountID)
|
||||
return u
|
||||
}
|
||||
|
||||
// ClearParentAccountID clears the value of the "parent_account_id" field.
|
||||
func (u *AccountUpsert) ClearParentAccountID() *AccountUpsert {
|
||||
u.SetNull(account.FieldParentAccountID)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetQuotaDimension sets the "quota_dimension" field.
|
||||
func (u *AccountUpsert) SetQuotaDimension(v account.QuotaDimension) *AccountUpsert {
|
||||
u.Set(account.FieldQuotaDimension, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateQuotaDimension sets the "quota_dimension" field to the value that was provided on create.
|
||||
func (u *AccountUpsert) UpdateQuotaDimension() *AccountUpsert {
|
||||
u.SetExcluded(account.FieldQuotaDimension)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateNewValues updates the mutable fields using the new values that were set on create.
|
||||
// Using this option is equivalent to using:
|
||||
//
|
||||
@@ -1874,6 +2015,41 @@ func (u *AccountUpsertOne) ClearSessionWindowStatus() *AccountUpsertOne {
|
||||
})
|
||||
}
|
||||
|
||||
// SetParentAccountID sets the "parent_account_id" field.
|
||||
func (u *AccountUpsertOne) SetParentAccountID(v int64) *AccountUpsertOne {
|
||||
return u.Update(func(s *AccountUpsert) {
|
||||
s.SetParentAccountID(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateParentAccountID sets the "parent_account_id" field to the value that was provided on create.
|
||||
func (u *AccountUpsertOne) UpdateParentAccountID() *AccountUpsertOne {
|
||||
return u.Update(func(s *AccountUpsert) {
|
||||
s.UpdateParentAccountID()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearParentAccountID clears the value of the "parent_account_id" field.
|
||||
func (u *AccountUpsertOne) ClearParentAccountID() *AccountUpsertOne {
|
||||
return u.Update(func(s *AccountUpsert) {
|
||||
s.ClearParentAccountID()
|
||||
})
|
||||
}
|
||||
|
||||
// SetQuotaDimension sets the "quota_dimension" field.
|
||||
func (u *AccountUpsertOne) SetQuotaDimension(v account.QuotaDimension) *AccountUpsertOne {
|
||||
return u.Update(func(s *AccountUpsert) {
|
||||
s.SetQuotaDimension(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateQuotaDimension sets the "quota_dimension" field to the value that was provided on create.
|
||||
func (u *AccountUpsertOne) UpdateQuotaDimension() *AccountUpsertOne {
|
||||
return u.Update(func(s *AccountUpsert) {
|
||||
s.UpdateQuotaDimension()
|
||||
})
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (u *AccountUpsertOne) Exec(ctx context.Context) error {
|
||||
if len(u.create.conflict) == 0 {
|
||||
@@ -2624,6 +2800,41 @@ func (u *AccountUpsertBulk) ClearSessionWindowStatus() *AccountUpsertBulk {
|
||||
})
|
||||
}
|
||||
|
||||
// SetParentAccountID sets the "parent_account_id" field.
|
||||
func (u *AccountUpsertBulk) SetParentAccountID(v int64) *AccountUpsertBulk {
|
||||
return u.Update(func(s *AccountUpsert) {
|
||||
s.SetParentAccountID(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateParentAccountID sets the "parent_account_id" field to the value that was provided on create.
|
||||
func (u *AccountUpsertBulk) UpdateParentAccountID() *AccountUpsertBulk {
|
||||
return u.Update(func(s *AccountUpsert) {
|
||||
s.UpdateParentAccountID()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearParentAccountID clears the value of the "parent_account_id" field.
|
||||
func (u *AccountUpsertBulk) ClearParentAccountID() *AccountUpsertBulk {
|
||||
return u.Update(func(s *AccountUpsert) {
|
||||
s.ClearParentAccountID()
|
||||
})
|
||||
}
|
||||
|
||||
// SetQuotaDimension sets the "quota_dimension" field.
|
||||
func (u *AccountUpsertBulk) SetQuotaDimension(v account.QuotaDimension) *AccountUpsertBulk {
|
||||
return u.Update(func(s *AccountUpsert) {
|
||||
s.SetQuotaDimension(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateQuotaDimension sets the "quota_dimension" field to the value that was provided on create.
|
||||
func (u *AccountUpsertBulk) UpdateQuotaDimension() *AccountUpsertBulk {
|
||||
return u.Update(func(s *AccountUpsert) {
|
||||
s.UpdateQuotaDimension()
|
||||
})
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (u *AccountUpsertBulk) Exec(ctx context.Context) error {
|
||||
if u.create.err != nil {
|
||||
|
||||
@@ -30,6 +30,8 @@ type AccountQuery struct {
|
||||
predicates []predicate.Account
|
||||
withGroups *GroupQuery
|
||||
withProxy *ProxyQuery
|
||||
withParent *AccountQuery
|
||||
withChildren *AccountQuery
|
||||
withUsageLogs *UsageLogQuery
|
||||
withAccountGroups *AccountGroupQuery
|
||||
modifiers []func(*sql.Selector)
|
||||
@@ -113,6 +115,50 @@ func (_q *AccountQuery) QueryProxy() *ProxyQuery {
|
||||
return query
|
||||
}
|
||||
|
||||
// QueryParent chains the current query on the "parent" edge.
|
||||
func (_q *AccountQuery) QueryParent() *AccountQuery {
|
||||
query := (&AccountClient{config: _q.config}).Query()
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := _q.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector := _q.sqlQuery(ctx)
|
||||
if err := selector.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(account.Table, account.FieldID, selector),
|
||||
sqlgraph.To(account.Table, account.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, account.ParentTable, account.ParentColumn),
|
||||
)
|
||||
fromU = sqlgraph.SetNeighbors(_q.driver.Dialect(), step)
|
||||
return fromU, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// QueryChildren chains the current query on the "children" edge.
|
||||
func (_q *AccountQuery) QueryChildren() *AccountQuery {
|
||||
query := (&AccountClient{config: _q.config}).Query()
|
||||
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
|
||||
if err := _q.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
selector := _q.sqlQuery(ctx)
|
||||
if err := selector.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(account.Table, account.FieldID, selector),
|
||||
sqlgraph.To(account.Table, account.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, account.ChildrenTable, account.ChildrenColumn),
|
||||
)
|
||||
fromU = sqlgraph.SetNeighbors(_q.driver.Dialect(), step)
|
||||
return fromU, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// QueryUsageLogs chains the current query on the "usage_logs" edge.
|
||||
func (_q *AccountQuery) QueryUsageLogs() *UsageLogQuery {
|
||||
query := (&UsageLogClient{config: _q.config}).Query()
|
||||
@@ -351,6 +397,8 @@ func (_q *AccountQuery) Clone() *AccountQuery {
|
||||
predicates: append([]predicate.Account{}, _q.predicates...),
|
||||
withGroups: _q.withGroups.Clone(),
|
||||
withProxy: _q.withProxy.Clone(),
|
||||
withParent: _q.withParent.Clone(),
|
||||
withChildren: _q.withChildren.Clone(),
|
||||
withUsageLogs: _q.withUsageLogs.Clone(),
|
||||
withAccountGroups: _q.withAccountGroups.Clone(),
|
||||
// clone intermediate query.
|
||||
@@ -381,6 +429,28 @@ func (_q *AccountQuery) WithProxy(opts ...func(*ProxyQuery)) *AccountQuery {
|
||||
return _q
|
||||
}
|
||||
|
||||
// WithParent tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "parent" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (_q *AccountQuery) WithParent(opts ...func(*AccountQuery)) *AccountQuery {
|
||||
query := (&AccountClient{config: _q.config}).Query()
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
_q.withParent = query
|
||||
return _q
|
||||
}
|
||||
|
||||
// WithChildren tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "children" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (_q *AccountQuery) WithChildren(opts ...func(*AccountQuery)) *AccountQuery {
|
||||
query := (&AccountClient{config: _q.config}).Query()
|
||||
for _, opt := range opts {
|
||||
opt(query)
|
||||
}
|
||||
_q.withChildren = query
|
||||
return _q
|
||||
}
|
||||
|
||||
// WithUsageLogs tells the query-builder to eager-load the nodes that are connected to
|
||||
// the "usage_logs" edge. The optional arguments are used to configure the query builder of the edge.
|
||||
func (_q *AccountQuery) WithUsageLogs(opts ...func(*UsageLogQuery)) *AccountQuery {
|
||||
@@ -481,9 +551,11 @@ func (_q *AccountQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Acco
|
||||
var (
|
||||
nodes = []*Account{}
|
||||
_spec = _q.querySpec()
|
||||
loadedTypes = [4]bool{
|
||||
loadedTypes = [6]bool{
|
||||
_q.withGroups != nil,
|
||||
_q.withProxy != nil,
|
||||
_q.withParent != nil,
|
||||
_q.withChildren != nil,
|
||||
_q.withUsageLogs != nil,
|
||||
_q.withAccountGroups != nil,
|
||||
}
|
||||
@@ -522,6 +594,19 @@ func (_q *AccountQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*Acco
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if query := _q.withParent; query != nil {
|
||||
if err := _q.loadParent(ctx, query, nodes, nil,
|
||||
func(n *Account, e *Account) { n.Edges.Parent = e }); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if query := _q.withChildren; query != nil {
|
||||
if err := _q.loadChildren(ctx, query, nodes,
|
||||
func(n *Account) { n.Edges.Children = []*Account{} },
|
||||
func(n *Account, e *Account) { n.Edges.Children = append(n.Edges.Children, e) }); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if query := _q.withUsageLogs; query != nil {
|
||||
if err := _q.loadUsageLogs(ctx, query, nodes,
|
||||
func(n *Account) { n.Edges.UsageLogs = []*UsageLog{} },
|
||||
@@ -632,6 +717,71 @@ func (_q *AccountQuery) loadProxy(ctx context.Context, query *ProxyQuery, nodes
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (_q *AccountQuery) loadParent(ctx context.Context, query *AccountQuery, nodes []*Account, init func(*Account), assign func(*Account, *Account)) error {
|
||||
ids := make([]int64, 0, len(nodes))
|
||||
nodeids := make(map[int64][]*Account)
|
||||
for i := range nodes {
|
||||
if nodes[i].ParentAccountID == nil {
|
||||
continue
|
||||
}
|
||||
fk := *nodes[i].ParentAccountID
|
||||
if _, ok := nodeids[fk]; !ok {
|
||||
ids = append(ids, fk)
|
||||
}
|
||||
nodeids[fk] = append(nodeids[fk], nodes[i])
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
query.Where(account.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 "parent_account_id" returned %v`, n.ID)
|
||||
}
|
||||
for i := range nodes {
|
||||
assign(nodes[i], n)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (_q *AccountQuery) loadChildren(ctx context.Context, query *AccountQuery, nodes []*Account, init func(*Account), assign func(*Account, *Account)) error {
|
||||
fks := make([]driver.Value, 0, len(nodes))
|
||||
nodeids := make(map[int64]*Account)
|
||||
for i := range nodes {
|
||||
fks = append(fks, nodes[i].ID)
|
||||
nodeids[nodes[i].ID] = nodes[i]
|
||||
if init != nil {
|
||||
init(nodes[i])
|
||||
}
|
||||
}
|
||||
if len(query.ctx.Fields) > 0 {
|
||||
query.ctx.AppendFieldOnce(account.FieldParentAccountID)
|
||||
}
|
||||
query.Where(predicate.Account(func(s *sql.Selector) {
|
||||
s.Where(sql.InValues(s.C(account.ChildrenColumn), fks...))
|
||||
}))
|
||||
neighbors, err := query.All(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, n := range neighbors {
|
||||
fk := n.ParentAccountID
|
||||
if fk == nil {
|
||||
return fmt.Errorf(`foreign-key "parent_account_id" is nil for node %v`, n.ID)
|
||||
}
|
||||
node, ok := nodeids[*fk]
|
||||
if !ok {
|
||||
return fmt.Errorf(`unexpected referenced foreign-key "parent_account_id" returned %v for node %v`, *fk, n.ID)
|
||||
}
|
||||
assign(node, n)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (_q *AccountQuery) loadUsageLogs(ctx context.Context, query *UsageLogQuery, nodes []*Account, init func(*Account), assign func(*Account, *UsageLog)) error {
|
||||
fks := make([]driver.Value, 0, len(nodes))
|
||||
nodeids := make(map[int64]*Account)
|
||||
@@ -724,6 +874,9 @@ func (_q *AccountQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
if _q.withProxy != nil {
|
||||
_spec.Node.AddColumnOnce(account.FieldProxyID)
|
||||
}
|
||||
if _q.withParent != nil {
|
||||
_spec.Node.AddColumnOnce(account.FieldParentAccountID)
|
||||
}
|
||||
}
|
||||
if ps := _q.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
|
||||
@@ -530,6 +530,40 @@ func (_u *AccountUpdate) ClearSessionWindowStatus() *AccountUpdate {
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetParentAccountID sets the "parent_account_id" field.
|
||||
func (_u *AccountUpdate) SetParentAccountID(v int64) *AccountUpdate {
|
||||
_u.mutation.SetParentAccountID(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableParentAccountID sets the "parent_account_id" field if the given value is not nil.
|
||||
func (_u *AccountUpdate) SetNillableParentAccountID(v *int64) *AccountUpdate {
|
||||
if v != nil {
|
||||
_u.SetParentAccountID(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearParentAccountID clears the value of the "parent_account_id" field.
|
||||
func (_u *AccountUpdate) ClearParentAccountID() *AccountUpdate {
|
||||
_u.mutation.ClearParentAccountID()
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetQuotaDimension sets the "quota_dimension" field.
|
||||
func (_u *AccountUpdate) SetQuotaDimension(v account.QuotaDimension) *AccountUpdate {
|
||||
_u.mutation.SetQuotaDimension(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableQuotaDimension sets the "quota_dimension" field if the given value is not nil.
|
||||
func (_u *AccountUpdate) SetNillableQuotaDimension(v *account.QuotaDimension) *AccountUpdate {
|
||||
if v != nil {
|
||||
_u.SetQuotaDimension(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddGroupIDs adds the "groups" edge to the Group entity by IDs.
|
||||
func (_u *AccountUpdate) AddGroupIDs(ids ...int64) *AccountUpdate {
|
||||
_u.mutation.AddGroupIDs(ids...)
|
||||
@@ -550,6 +584,40 @@ func (_u *AccountUpdate) SetProxy(v *Proxy) *AccountUpdate {
|
||||
return _u.SetProxyID(v.ID)
|
||||
}
|
||||
|
||||
// SetParentID sets the "parent" edge to the Account entity by ID.
|
||||
func (_u *AccountUpdate) SetParentID(id int64) *AccountUpdate {
|
||||
_u.mutation.SetParentID(id)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableParentID sets the "parent" edge to the Account entity by ID if the given value is not nil.
|
||||
func (_u *AccountUpdate) SetNillableParentID(id *int64) *AccountUpdate {
|
||||
if id != nil {
|
||||
_u = _u.SetParentID(*id)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetParent sets the "parent" edge to the Account entity.
|
||||
func (_u *AccountUpdate) SetParent(v *Account) *AccountUpdate {
|
||||
return _u.SetParentID(v.ID)
|
||||
}
|
||||
|
||||
// AddChildIDs adds the "children" edge to the Account entity by IDs.
|
||||
func (_u *AccountUpdate) AddChildIDs(ids ...int64) *AccountUpdate {
|
||||
_u.mutation.AddChildIDs(ids...)
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddChildren adds the "children" edges to the Account entity.
|
||||
func (_u *AccountUpdate) AddChildren(v ...*Account) *AccountUpdate {
|
||||
ids := make([]int64, len(v))
|
||||
for i := range v {
|
||||
ids[i] = v[i].ID
|
||||
}
|
||||
return _u.AddChildIDs(ids...)
|
||||
}
|
||||
|
||||
// AddUsageLogIDs adds the "usage_logs" edge to the UsageLog entity by IDs.
|
||||
func (_u *AccountUpdate) AddUsageLogIDs(ids ...int64) *AccountUpdate {
|
||||
_u.mutation.AddUsageLogIDs(ids...)
|
||||
@@ -597,6 +665,33 @@ func (_u *AccountUpdate) ClearProxy() *AccountUpdate {
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearParent clears the "parent" edge to the Account entity.
|
||||
func (_u *AccountUpdate) ClearParent() *AccountUpdate {
|
||||
_u.mutation.ClearParent()
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearChildren clears all "children" edges to the Account entity.
|
||||
func (_u *AccountUpdate) ClearChildren() *AccountUpdate {
|
||||
_u.mutation.ClearChildren()
|
||||
return _u
|
||||
}
|
||||
|
||||
// RemoveChildIDs removes the "children" edge to Account entities by IDs.
|
||||
func (_u *AccountUpdate) RemoveChildIDs(ids ...int64) *AccountUpdate {
|
||||
_u.mutation.RemoveChildIDs(ids...)
|
||||
return _u
|
||||
}
|
||||
|
||||
// RemoveChildren removes "children" edges to Account entities.
|
||||
func (_u *AccountUpdate) RemoveChildren(v ...*Account) *AccountUpdate {
|
||||
ids := make([]int64, len(v))
|
||||
for i := range v {
|
||||
ids[i] = v[i].ID
|
||||
}
|
||||
return _u.RemoveChildIDs(ids...)
|
||||
}
|
||||
|
||||
// ClearUsageLogs clears all "usage_logs" edges to the UsageLog entity.
|
||||
func (_u *AccountUpdate) ClearUsageLogs() *AccountUpdate {
|
||||
_u.mutation.ClearUsageLogs()
|
||||
@@ -687,6 +782,11 @@ func (_u *AccountUpdate) check() error {
|
||||
return &ValidationError{Name: "session_window_status", err: fmt.Errorf(`ent: validator failed for field "Account.session_window_status": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := _u.mutation.QuotaDimension(); ok {
|
||||
if err := account.QuotaDimensionValidator(v); err != nil {
|
||||
return &ValidationError{Name: "quota_dimension", err: fmt.Errorf(`ent: validator failed for field "Account.quota_dimension": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -843,6 +943,9 @@ func (_u *AccountUpdate) sqlSave(ctx context.Context) (_node int, err error) {
|
||||
if _u.mutation.SessionWindowStatusCleared() {
|
||||
_spec.ClearField(account.FieldSessionWindowStatus, field.TypeString)
|
||||
}
|
||||
if value, ok := _u.mutation.QuotaDimension(); ok {
|
||||
_spec.SetField(account.FieldQuotaDimension, field.TypeEnum, value)
|
||||
}
|
||||
if _u.mutation.GroupsCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2M,
|
||||
@@ -929,6 +1032,80 @@ func (_u *AccountUpdate) sqlSave(ctx context.Context) (_node int, err error) {
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if _u.mutation.ParentCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: account.ParentTable,
|
||||
Columns: []string{account.ParentColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(account.FieldID, field.TypeInt64),
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := _u.mutation.ParentIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: account.ParentTable,
|
||||
Columns: []string{account.ParentColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(account.FieldID, field.TypeInt64),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if _u.mutation.ChildrenCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: account.ChildrenTable,
|
||||
Columns: []string{account.ChildrenColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(account.FieldID, field.TypeInt64),
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := _u.mutation.RemovedChildrenIDs(); len(nodes) > 0 && !_u.mutation.ChildrenCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: account.ChildrenTable,
|
||||
Columns: []string{account.ChildrenColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(account.FieldID, field.TypeInt64),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := _u.mutation.ChildrenIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: account.ChildrenTable,
|
||||
Columns: []string{account.ChildrenColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(account.FieldID, field.TypeInt64),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if _u.mutation.UsageLogsCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
@@ -1493,6 +1670,40 @@ func (_u *AccountUpdateOne) ClearSessionWindowStatus() *AccountUpdateOne {
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetParentAccountID sets the "parent_account_id" field.
|
||||
func (_u *AccountUpdateOne) SetParentAccountID(v int64) *AccountUpdateOne {
|
||||
_u.mutation.SetParentAccountID(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableParentAccountID sets the "parent_account_id" field if the given value is not nil.
|
||||
func (_u *AccountUpdateOne) SetNillableParentAccountID(v *int64) *AccountUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetParentAccountID(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearParentAccountID clears the value of the "parent_account_id" field.
|
||||
func (_u *AccountUpdateOne) ClearParentAccountID() *AccountUpdateOne {
|
||||
_u.mutation.ClearParentAccountID()
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetQuotaDimension sets the "quota_dimension" field.
|
||||
func (_u *AccountUpdateOne) SetQuotaDimension(v account.QuotaDimension) *AccountUpdateOne {
|
||||
_u.mutation.SetQuotaDimension(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableQuotaDimension sets the "quota_dimension" field if the given value is not nil.
|
||||
func (_u *AccountUpdateOne) SetNillableQuotaDimension(v *account.QuotaDimension) *AccountUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetQuotaDimension(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddGroupIDs adds the "groups" edge to the Group entity by IDs.
|
||||
func (_u *AccountUpdateOne) AddGroupIDs(ids ...int64) *AccountUpdateOne {
|
||||
_u.mutation.AddGroupIDs(ids...)
|
||||
@@ -1513,6 +1724,40 @@ func (_u *AccountUpdateOne) SetProxy(v *Proxy) *AccountUpdateOne {
|
||||
return _u.SetProxyID(v.ID)
|
||||
}
|
||||
|
||||
// SetParentID sets the "parent" edge to the Account entity by ID.
|
||||
func (_u *AccountUpdateOne) SetParentID(id int64) *AccountUpdateOne {
|
||||
_u.mutation.SetParentID(id)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableParentID sets the "parent" edge to the Account entity by ID if the given value is not nil.
|
||||
func (_u *AccountUpdateOne) SetNillableParentID(id *int64) *AccountUpdateOne {
|
||||
if id != nil {
|
||||
_u = _u.SetParentID(*id)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetParent sets the "parent" edge to the Account entity.
|
||||
func (_u *AccountUpdateOne) SetParent(v *Account) *AccountUpdateOne {
|
||||
return _u.SetParentID(v.ID)
|
||||
}
|
||||
|
||||
// AddChildIDs adds the "children" edge to the Account entity by IDs.
|
||||
func (_u *AccountUpdateOne) AddChildIDs(ids ...int64) *AccountUpdateOne {
|
||||
_u.mutation.AddChildIDs(ids...)
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddChildren adds the "children" edges to the Account entity.
|
||||
func (_u *AccountUpdateOne) AddChildren(v ...*Account) *AccountUpdateOne {
|
||||
ids := make([]int64, len(v))
|
||||
for i := range v {
|
||||
ids[i] = v[i].ID
|
||||
}
|
||||
return _u.AddChildIDs(ids...)
|
||||
}
|
||||
|
||||
// AddUsageLogIDs adds the "usage_logs" edge to the UsageLog entity by IDs.
|
||||
func (_u *AccountUpdateOne) AddUsageLogIDs(ids ...int64) *AccountUpdateOne {
|
||||
_u.mutation.AddUsageLogIDs(ids...)
|
||||
@@ -1560,6 +1805,33 @@ func (_u *AccountUpdateOne) ClearProxy() *AccountUpdateOne {
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearParent clears the "parent" edge to the Account entity.
|
||||
func (_u *AccountUpdateOne) ClearParent() *AccountUpdateOne {
|
||||
_u.mutation.ClearParent()
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearChildren clears all "children" edges to the Account entity.
|
||||
func (_u *AccountUpdateOne) ClearChildren() *AccountUpdateOne {
|
||||
_u.mutation.ClearChildren()
|
||||
return _u
|
||||
}
|
||||
|
||||
// RemoveChildIDs removes the "children" edge to Account entities by IDs.
|
||||
func (_u *AccountUpdateOne) RemoveChildIDs(ids ...int64) *AccountUpdateOne {
|
||||
_u.mutation.RemoveChildIDs(ids...)
|
||||
return _u
|
||||
}
|
||||
|
||||
// RemoveChildren removes "children" edges to Account entities.
|
||||
func (_u *AccountUpdateOne) RemoveChildren(v ...*Account) *AccountUpdateOne {
|
||||
ids := make([]int64, len(v))
|
||||
for i := range v {
|
||||
ids[i] = v[i].ID
|
||||
}
|
||||
return _u.RemoveChildIDs(ids...)
|
||||
}
|
||||
|
||||
// ClearUsageLogs clears all "usage_logs" edges to the UsageLog entity.
|
||||
func (_u *AccountUpdateOne) ClearUsageLogs() *AccountUpdateOne {
|
||||
_u.mutation.ClearUsageLogs()
|
||||
@@ -1663,6 +1935,11 @@ func (_u *AccountUpdateOne) check() error {
|
||||
return &ValidationError{Name: "session_window_status", err: fmt.Errorf(`ent: validator failed for field "Account.session_window_status": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := _u.mutation.QuotaDimension(); ok {
|
||||
if err := account.QuotaDimensionValidator(v); err != nil {
|
||||
return &ValidationError{Name: "quota_dimension", err: fmt.Errorf(`ent: validator failed for field "Account.quota_dimension": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1836,6 +2113,9 @@ func (_u *AccountUpdateOne) sqlSave(ctx context.Context) (_node *Account, err er
|
||||
if _u.mutation.SessionWindowStatusCleared() {
|
||||
_spec.ClearField(account.FieldSessionWindowStatus, field.TypeString)
|
||||
}
|
||||
if value, ok := _u.mutation.QuotaDimension(); ok {
|
||||
_spec.SetField(account.FieldQuotaDimension, field.TypeEnum, value)
|
||||
}
|
||||
if _u.mutation.GroupsCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2M,
|
||||
@@ -1922,6 +2202,80 @@ func (_u *AccountUpdateOne) sqlSave(ctx context.Context) (_node *Account, err er
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if _u.mutation.ParentCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: account.ParentTable,
|
||||
Columns: []string{account.ParentColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(account.FieldID, field.TypeInt64),
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := _u.mutation.ParentIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.M2O,
|
||||
Inverse: true,
|
||||
Table: account.ParentTable,
|
||||
Columns: []string{account.ParentColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(account.FieldID, field.TypeInt64),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if _u.mutation.ChildrenCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: account.ChildrenTable,
|
||||
Columns: []string{account.ChildrenColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(account.FieldID, field.TypeInt64),
|
||||
},
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := _u.mutation.RemovedChildrenIDs(); len(nodes) > 0 && !_u.mutation.ChildrenCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: account.ChildrenTable,
|
||||
Columns: []string{account.ChildrenColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(account.FieldID, field.TypeInt64),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
|
||||
}
|
||||
if nodes := _u.mutation.ChildrenIDs(); len(nodes) > 0 {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
Inverse: false,
|
||||
Table: account.ChildrenTable,
|
||||
Columns: []string{account.ChildrenColumn},
|
||||
Bidi: false,
|
||||
Target: &sqlgraph.EdgeTarget{
|
||||
IDSpec: sqlgraph.NewFieldSpec(account.FieldID, field.TypeInt64),
|
||||
},
|
||||
}
|
||||
for _, k := range nodes {
|
||||
edge.Target.Nodes = append(edge.Target.Nodes, k)
|
||||
}
|
||||
_spec.Edges.Add = append(_spec.Edges.Add, edge)
|
||||
}
|
||||
if _u.mutation.UsageLogsCleared() {
|
||||
edge := &sqlgraph.EdgeSpec{
|
||||
Rel: sqlgraph.O2M,
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
// 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/Wei-Shaw/sub2api/ent/batchimageevent"
|
||||
)
|
||||
|
||||
// BatchImageEvent is the model entity for the BatchImageEvent schema.
|
||||
type BatchImageEvent struct {
|
||||
config `json:"-"`
|
||||
// ID of the ent.
|
||||
ID int64 `json:"id,omitempty"`
|
||||
// JobID holds the value of the "job_id" field.
|
||||
JobID string `json:"job_id,omitempty"`
|
||||
// EventType holds the value of the "event_type" field.
|
||||
EventType string `json:"event_type,omitempty"`
|
||||
// Payload holds the value of the "payload" field.
|
||||
Payload map[string]interface{} `json:"payload,omitempty"`
|
||||
// EventHash holds the value of the "event_hash" field.
|
||||
EventHash *string `json:"event_hash,omitempty"`
|
||||
// CreatedAt holds the value of the "created_at" field.
|
||||
CreatedAt time.Time `json:"created_at,omitempty"`
|
||||
selectValues sql.SelectValues
|
||||
}
|
||||
|
||||
// scanValues returns the types for scanning values from sql.Rows.
|
||||
func (*BatchImageEvent) scanValues(columns []string) ([]any, error) {
|
||||
values := make([]any, len(columns))
|
||||
for i := range columns {
|
||||
switch columns[i] {
|
||||
case batchimageevent.FieldPayload:
|
||||
values[i] = new([]byte)
|
||||
case batchimageevent.FieldID:
|
||||
values[i] = new(sql.NullInt64)
|
||||
case batchimageevent.FieldJobID, batchimageevent.FieldEventType, batchimageevent.FieldEventHash:
|
||||
values[i] = new(sql.NullString)
|
||||
case batchimageevent.FieldCreatedAt:
|
||||
values[i] = new(sql.NullTime)
|
||||
default:
|
||||
values[i] = new(sql.UnknownType)
|
||||
}
|
||||
}
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// assignValues assigns the values that were returned from sql.Rows (after scanning)
|
||||
// to the BatchImageEvent fields.
|
||||
func (_m *BatchImageEvent) 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 batchimageevent.FieldID:
|
||||
value, ok := values[i].(*sql.NullInt64)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field id", value)
|
||||
}
|
||||
_m.ID = int64(value.Int64)
|
||||
case batchimageevent.FieldJobID:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field job_id", values[i])
|
||||
} else if value.Valid {
|
||||
_m.JobID = value.String
|
||||
}
|
||||
case batchimageevent.FieldEventType:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field event_type", values[i])
|
||||
} else if value.Valid {
|
||||
_m.EventType = value.String
|
||||
}
|
||||
case batchimageevent.FieldPayload:
|
||||
if value, ok := values[i].(*[]byte); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field payload", values[i])
|
||||
} else if value != nil && len(*value) > 0 {
|
||||
if err := json.Unmarshal(*value, &_m.Payload); err != nil {
|
||||
return fmt.Errorf("unmarshal field payload: %w", err)
|
||||
}
|
||||
}
|
||||
case batchimageevent.FieldEventHash:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field event_hash", values[i])
|
||||
} else if value.Valid {
|
||||
_m.EventHash = new(string)
|
||||
*_m.EventHash = value.String
|
||||
}
|
||||
case batchimageevent.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 {
|
||||
_m.CreatedAt = value.Time
|
||||
}
|
||||
default:
|
||||
_m.selectValues.Set(columns[i], values[i])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value returns the ent.Value that was dynamically selected and assigned to the BatchImageEvent.
|
||||
// This includes values selected through modifiers, order, etc.
|
||||
func (_m *BatchImageEvent) Value(name string) (ent.Value, error) {
|
||||
return _m.selectValues.Get(name)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this BatchImageEvent.
|
||||
// Note that you need to call BatchImageEvent.Unwrap() before calling this method if this BatchImageEvent
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (_m *BatchImageEvent) Update() *BatchImageEventUpdateOne {
|
||||
return NewBatchImageEventClient(_m.config).UpdateOne(_m)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the BatchImageEvent entity that was returned from a transaction after it was closed,
|
||||
// so that all future queries will be executed through the driver which created the transaction.
|
||||
func (_m *BatchImageEvent) Unwrap() *BatchImageEvent {
|
||||
_tx, ok := _m.config.driver.(*txDriver)
|
||||
if !ok {
|
||||
panic("ent: BatchImageEvent is not a transactional entity")
|
||||
}
|
||||
_m.config.driver = _tx.drv
|
||||
return _m
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer.
|
||||
func (_m *BatchImageEvent) String() string {
|
||||
var builder strings.Builder
|
||||
builder.WriteString("BatchImageEvent(")
|
||||
builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID))
|
||||
builder.WriteString("job_id=")
|
||||
builder.WriteString(_m.JobID)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("event_type=")
|
||||
builder.WriteString(_m.EventType)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("payload=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.Payload))
|
||||
builder.WriteString(", ")
|
||||
if v := _m.EventHash; v != nil {
|
||||
builder.WriteString("event_hash=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("created_at=")
|
||||
builder.WriteString(_m.CreatedAt.Format(time.ANSIC))
|
||||
builder.WriteByte(')')
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
// BatchImageEvents is a parsable slice of BatchImageEvent.
|
||||
type BatchImageEvents []*BatchImageEvent
|
||||
@@ -0,0 +1,87 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package batchimageevent
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
)
|
||||
|
||||
const (
|
||||
// Label holds the string label denoting the batchimageevent type in the database.
|
||||
Label = "batch_image_event"
|
||||
// FieldID holds the string denoting the id field in the database.
|
||||
FieldID = "id"
|
||||
// FieldJobID holds the string denoting the job_id field in the database.
|
||||
FieldJobID = "job_id"
|
||||
// FieldEventType holds the string denoting the event_type field in the database.
|
||||
FieldEventType = "event_type"
|
||||
// FieldPayload holds the string denoting the payload field in the database.
|
||||
FieldPayload = "payload"
|
||||
// FieldEventHash holds the string denoting the event_hash field in the database.
|
||||
FieldEventHash = "event_hash"
|
||||
// FieldCreatedAt holds the string denoting the created_at field in the database.
|
||||
FieldCreatedAt = "created_at"
|
||||
// Table holds the table name of the batchimageevent in the database.
|
||||
Table = "batch_image_events"
|
||||
)
|
||||
|
||||
// Columns holds all SQL columns for batchimageevent fields.
|
||||
var Columns = []string{
|
||||
FieldID,
|
||||
FieldJobID,
|
||||
FieldEventType,
|
||||
FieldPayload,
|
||||
FieldEventHash,
|
||||
FieldCreatedAt,
|
||||
}
|
||||
|
||||
// ValidColumn reports if the column name is valid (part of the table columns).
|
||||
func ValidColumn(column string) bool {
|
||||
for i := range Columns {
|
||||
if column == Columns[i] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var (
|
||||
// JobIDValidator is a validator for the "job_id" field. It is called by the builders before save.
|
||||
JobIDValidator func(string) error
|
||||
// EventTypeValidator is a validator for the "event_type" field. It is called by the builders before save.
|
||||
EventTypeValidator func(string) error
|
||||
// EventHashValidator is a validator for the "event_hash" field. It is called by the builders before save.
|
||||
EventHashValidator func(string) error
|
||||
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
|
||||
DefaultCreatedAt func() time.Time
|
||||
)
|
||||
|
||||
// OrderOption defines the ordering options for the BatchImageEvent 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()
|
||||
}
|
||||
|
||||
// ByJobID orders the results by the job_id field.
|
||||
func ByJobID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldJobID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByEventType orders the results by the event_type field.
|
||||
func ByEventType(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldEventType, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByEventHash orders the results by the event_hash field.
|
||||
func ByEventHash(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldEventHash, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByCreatedAt orders the results by the created_at field.
|
||||
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
|
||||
}
|
||||
@@ -0,0 +1,345 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package batchimageevent
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"github.com/Wei-Shaw/sub2api/ent/predicate"
|
||||
)
|
||||
|
||||
// ID filters vertices based on their ID field.
|
||||
func ID(id int64) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDEQ applies the EQ predicate on the ID field.
|
||||
func IDEQ(id int64) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDNEQ applies the NEQ predicate on the ID field.
|
||||
func IDNEQ(id int64) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldNEQ(FieldID, id))
|
||||
}
|
||||
|
||||
// IDIn applies the In predicate on the ID field.
|
||||
func IDIn(ids ...int64) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDNotIn applies the NotIn predicate on the ID field.
|
||||
func IDNotIn(ids ...int64) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldNotIn(FieldID, ids...))
|
||||
}
|
||||
|
||||
// IDGT applies the GT predicate on the ID field.
|
||||
func IDGT(id int64) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldGT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDGTE applies the GTE predicate on the ID field.
|
||||
func IDGTE(id int64) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldGTE(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLT applies the LT predicate on the ID field.
|
||||
func IDLT(id int64) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldLT(FieldID, id))
|
||||
}
|
||||
|
||||
// IDLTE applies the LTE predicate on the ID field.
|
||||
func IDLTE(id int64) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldLTE(FieldID, id))
|
||||
}
|
||||
|
||||
// JobID applies equality check predicate on the "job_id" field. It's identical to JobIDEQ.
|
||||
func JobID(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldEQ(FieldJobID, v))
|
||||
}
|
||||
|
||||
// EventType applies equality check predicate on the "event_type" field. It's identical to EventTypeEQ.
|
||||
func EventType(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldEQ(FieldEventType, v))
|
||||
}
|
||||
|
||||
// EventHash applies equality check predicate on the "event_hash" field. It's identical to EventHashEQ.
|
||||
func EventHash(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldEQ(FieldEventHash, v))
|
||||
}
|
||||
|
||||
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
|
||||
func CreatedAt(v time.Time) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// JobIDEQ applies the EQ predicate on the "job_id" field.
|
||||
func JobIDEQ(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldEQ(FieldJobID, v))
|
||||
}
|
||||
|
||||
// JobIDNEQ applies the NEQ predicate on the "job_id" field.
|
||||
func JobIDNEQ(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldNEQ(FieldJobID, v))
|
||||
}
|
||||
|
||||
// JobIDIn applies the In predicate on the "job_id" field.
|
||||
func JobIDIn(vs ...string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldIn(FieldJobID, vs...))
|
||||
}
|
||||
|
||||
// JobIDNotIn applies the NotIn predicate on the "job_id" field.
|
||||
func JobIDNotIn(vs ...string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldNotIn(FieldJobID, vs...))
|
||||
}
|
||||
|
||||
// JobIDGT applies the GT predicate on the "job_id" field.
|
||||
func JobIDGT(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldGT(FieldJobID, v))
|
||||
}
|
||||
|
||||
// JobIDGTE applies the GTE predicate on the "job_id" field.
|
||||
func JobIDGTE(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldGTE(FieldJobID, v))
|
||||
}
|
||||
|
||||
// JobIDLT applies the LT predicate on the "job_id" field.
|
||||
func JobIDLT(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldLT(FieldJobID, v))
|
||||
}
|
||||
|
||||
// JobIDLTE applies the LTE predicate on the "job_id" field.
|
||||
func JobIDLTE(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldLTE(FieldJobID, v))
|
||||
}
|
||||
|
||||
// JobIDContains applies the Contains predicate on the "job_id" field.
|
||||
func JobIDContains(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldContains(FieldJobID, v))
|
||||
}
|
||||
|
||||
// JobIDHasPrefix applies the HasPrefix predicate on the "job_id" field.
|
||||
func JobIDHasPrefix(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldHasPrefix(FieldJobID, v))
|
||||
}
|
||||
|
||||
// JobIDHasSuffix applies the HasSuffix predicate on the "job_id" field.
|
||||
func JobIDHasSuffix(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldHasSuffix(FieldJobID, v))
|
||||
}
|
||||
|
||||
// JobIDEqualFold applies the EqualFold predicate on the "job_id" field.
|
||||
func JobIDEqualFold(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldEqualFold(FieldJobID, v))
|
||||
}
|
||||
|
||||
// JobIDContainsFold applies the ContainsFold predicate on the "job_id" field.
|
||||
func JobIDContainsFold(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldContainsFold(FieldJobID, v))
|
||||
}
|
||||
|
||||
// EventTypeEQ applies the EQ predicate on the "event_type" field.
|
||||
func EventTypeEQ(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldEQ(FieldEventType, v))
|
||||
}
|
||||
|
||||
// EventTypeNEQ applies the NEQ predicate on the "event_type" field.
|
||||
func EventTypeNEQ(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldNEQ(FieldEventType, v))
|
||||
}
|
||||
|
||||
// EventTypeIn applies the In predicate on the "event_type" field.
|
||||
func EventTypeIn(vs ...string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldIn(FieldEventType, vs...))
|
||||
}
|
||||
|
||||
// EventTypeNotIn applies the NotIn predicate on the "event_type" field.
|
||||
func EventTypeNotIn(vs ...string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldNotIn(FieldEventType, vs...))
|
||||
}
|
||||
|
||||
// EventTypeGT applies the GT predicate on the "event_type" field.
|
||||
func EventTypeGT(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldGT(FieldEventType, v))
|
||||
}
|
||||
|
||||
// EventTypeGTE applies the GTE predicate on the "event_type" field.
|
||||
func EventTypeGTE(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldGTE(FieldEventType, v))
|
||||
}
|
||||
|
||||
// EventTypeLT applies the LT predicate on the "event_type" field.
|
||||
func EventTypeLT(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldLT(FieldEventType, v))
|
||||
}
|
||||
|
||||
// EventTypeLTE applies the LTE predicate on the "event_type" field.
|
||||
func EventTypeLTE(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldLTE(FieldEventType, v))
|
||||
}
|
||||
|
||||
// EventTypeContains applies the Contains predicate on the "event_type" field.
|
||||
func EventTypeContains(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldContains(FieldEventType, v))
|
||||
}
|
||||
|
||||
// EventTypeHasPrefix applies the HasPrefix predicate on the "event_type" field.
|
||||
func EventTypeHasPrefix(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldHasPrefix(FieldEventType, v))
|
||||
}
|
||||
|
||||
// EventTypeHasSuffix applies the HasSuffix predicate on the "event_type" field.
|
||||
func EventTypeHasSuffix(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldHasSuffix(FieldEventType, v))
|
||||
}
|
||||
|
||||
// EventTypeEqualFold applies the EqualFold predicate on the "event_type" field.
|
||||
func EventTypeEqualFold(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldEqualFold(FieldEventType, v))
|
||||
}
|
||||
|
||||
// EventTypeContainsFold applies the ContainsFold predicate on the "event_type" field.
|
||||
func EventTypeContainsFold(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldContainsFold(FieldEventType, v))
|
||||
}
|
||||
|
||||
// PayloadIsNil applies the IsNil predicate on the "payload" field.
|
||||
func PayloadIsNil() predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldIsNull(FieldPayload))
|
||||
}
|
||||
|
||||
// PayloadNotNil applies the NotNil predicate on the "payload" field.
|
||||
func PayloadNotNil() predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldNotNull(FieldPayload))
|
||||
}
|
||||
|
||||
// EventHashEQ applies the EQ predicate on the "event_hash" field.
|
||||
func EventHashEQ(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldEQ(FieldEventHash, v))
|
||||
}
|
||||
|
||||
// EventHashNEQ applies the NEQ predicate on the "event_hash" field.
|
||||
func EventHashNEQ(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldNEQ(FieldEventHash, v))
|
||||
}
|
||||
|
||||
// EventHashIn applies the In predicate on the "event_hash" field.
|
||||
func EventHashIn(vs ...string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldIn(FieldEventHash, vs...))
|
||||
}
|
||||
|
||||
// EventHashNotIn applies the NotIn predicate on the "event_hash" field.
|
||||
func EventHashNotIn(vs ...string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldNotIn(FieldEventHash, vs...))
|
||||
}
|
||||
|
||||
// EventHashGT applies the GT predicate on the "event_hash" field.
|
||||
func EventHashGT(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldGT(FieldEventHash, v))
|
||||
}
|
||||
|
||||
// EventHashGTE applies the GTE predicate on the "event_hash" field.
|
||||
func EventHashGTE(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldGTE(FieldEventHash, v))
|
||||
}
|
||||
|
||||
// EventHashLT applies the LT predicate on the "event_hash" field.
|
||||
func EventHashLT(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldLT(FieldEventHash, v))
|
||||
}
|
||||
|
||||
// EventHashLTE applies the LTE predicate on the "event_hash" field.
|
||||
func EventHashLTE(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldLTE(FieldEventHash, v))
|
||||
}
|
||||
|
||||
// EventHashContains applies the Contains predicate on the "event_hash" field.
|
||||
func EventHashContains(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldContains(FieldEventHash, v))
|
||||
}
|
||||
|
||||
// EventHashHasPrefix applies the HasPrefix predicate on the "event_hash" field.
|
||||
func EventHashHasPrefix(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldHasPrefix(FieldEventHash, v))
|
||||
}
|
||||
|
||||
// EventHashHasSuffix applies the HasSuffix predicate on the "event_hash" field.
|
||||
func EventHashHasSuffix(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldHasSuffix(FieldEventHash, v))
|
||||
}
|
||||
|
||||
// EventHashIsNil applies the IsNil predicate on the "event_hash" field.
|
||||
func EventHashIsNil() predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldIsNull(FieldEventHash))
|
||||
}
|
||||
|
||||
// EventHashNotNil applies the NotNil predicate on the "event_hash" field.
|
||||
func EventHashNotNil() predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldNotNull(FieldEventHash))
|
||||
}
|
||||
|
||||
// EventHashEqualFold applies the EqualFold predicate on the "event_hash" field.
|
||||
func EventHashEqualFold(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldEqualFold(FieldEventHash, v))
|
||||
}
|
||||
|
||||
// EventHashContainsFold applies the ContainsFold predicate on the "event_hash" field.
|
||||
func EventHashContainsFold(v string) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldContainsFold(FieldEventHash, v))
|
||||
}
|
||||
|
||||
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
|
||||
func CreatedAtEQ(v time.Time) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
|
||||
func CreatedAtNEQ(v time.Time) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldNEQ(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtIn applies the In predicate on the "created_at" field.
|
||||
func CreatedAtIn(vs ...time.Time) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldIn(FieldCreatedAt, vs...))
|
||||
}
|
||||
|
||||
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
|
||||
func CreatedAtNotIn(vs ...time.Time) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldNotIn(FieldCreatedAt, vs...))
|
||||
}
|
||||
|
||||
// CreatedAtGT applies the GT predicate on the "created_at" field.
|
||||
func CreatedAtGT(v time.Time) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldGT(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
|
||||
func CreatedAtGTE(v time.Time) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldGTE(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtLT applies the LT predicate on the "created_at" field.
|
||||
func CreatedAtLT(v time.Time) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldLT(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
|
||||
func CreatedAtLTE(v time.Time) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.FieldLTE(FieldCreatedAt, v))
|
||||
}
|
||||
|
||||
// And groups predicates with the AND operator between them.
|
||||
func And(predicates ...predicate.BatchImageEvent) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.AndPredicates(predicates...))
|
||||
}
|
||||
|
||||
// Or groups predicates with the OR operator between them.
|
||||
func Or(predicates ...predicate.BatchImageEvent) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.OrPredicates(predicates...))
|
||||
}
|
||||
|
||||
// Not applies the not operator on the given predicate.
|
||||
func Not(p predicate.BatchImageEvent) predicate.BatchImageEvent {
|
||||
return predicate.BatchImageEvent(sql.NotPredicates(p))
|
||||
}
|
||||
@@ -0,0 +1,714 @@
|
||||
// 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/Wei-Shaw/sub2api/ent/batchimageevent"
|
||||
)
|
||||
|
||||
// BatchImageEventCreate is the builder for creating a BatchImageEvent entity.
|
||||
type BatchImageEventCreate struct {
|
||||
config
|
||||
mutation *BatchImageEventMutation
|
||||
hooks []Hook
|
||||
conflict []sql.ConflictOption
|
||||
}
|
||||
|
||||
// SetJobID sets the "job_id" field.
|
||||
func (_c *BatchImageEventCreate) SetJobID(v string) *BatchImageEventCreate {
|
||||
_c.mutation.SetJobID(v)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetEventType sets the "event_type" field.
|
||||
func (_c *BatchImageEventCreate) SetEventType(v string) *BatchImageEventCreate {
|
||||
_c.mutation.SetEventType(v)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetPayload sets the "payload" field.
|
||||
func (_c *BatchImageEventCreate) SetPayload(v map[string]interface{}) *BatchImageEventCreate {
|
||||
_c.mutation.SetPayload(v)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetEventHash sets the "event_hash" field.
|
||||
func (_c *BatchImageEventCreate) SetEventHash(v string) *BatchImageEventCreate {
|
||||
_c.mutation.SetEventHash(v)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetNillableEventHash sets the "event_hash" field if the given value is not nil.
|
||||
func (_c *BatchImageEventCreate) SetNillableEventHash(v *string) *BatchImageEventCreate {
|
||||
if v != nil {
|
||||
_c.SetEventHash(*v)
|
||||
}
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetCreatedAt sets the "created_at" field.
|
||||
func (_c *BatchImageEventCreate) SetCreatedAt(v time.Time) *BatchImageEventCreate {
|
||||
_c.mutation.SetCreatedAt(v)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
|
||||
func (_c *BatchImageEventCreate) SetNillableCreatedAt(v *time.Time) *BatchImageEventCreate {
|
||||
if v != nil {
|
||||
_c.SetCreatedAt(*v)
|
||||
}
|
||||
return _c
|
||||
}
|
||||
|
||||
// Mutation returns the BatchImageEventMutation object of the builder.
|
||||
func (_c *BatchImageEventCreate) Mutation() *BatchImageEventMutation {
|
||||
return _c.mutation
|
||||
}
|
||||
|
||||
// Save creates the BatchImageEvent in the database.
|
||||
func (_c *BatchImageEventCreate) Save(ctx context.Context) (*BatchImageEvent, error) {
|
||||
_c.defaults()
|
||||
return withHooks(ctx, _c.sqlSave, _c.mutation, _c.hooks)
|
||||
}
|
||||
|
||||
// SaveX calls Save and panics if Save returns an error.
|
||||
func (_c *BatchImageEventCreate) SaveX(ctx context.Context) *BatchImageEvent {
|
||||
v, err := _c.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (_c *BatchImageEventCreate) Exec(ctx context.Context) error {
|
||||
_, err := _c.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (_c *BatchImageEventCreate) ExecX(ctx context.Context) {
|
||||
if err := _c.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// defaults sets the default values of the builder before save.
|
||||
func (_c *BatchImageEventCreate) defaults() {
|
||||
if _, ok := _c.mutation.CreatedAt(); !ok {
|
||||
v := batchimageevent.DefaultCreatedAt()
|
||||
_c.mutation.SetCreatedAt(v)
|
||||
}
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (_c *BatchImageEventCreate) check() error {
|
||||
if _, ok := _c.mutation.JobID(); !ok {
|
||||
return &ValidationError{Name: "job_id", err: errors.New(`ent: missing required field "BatchImageEvent.job_id"`)}
|
||||
}
|
||||
if v, ok := _c.mutation.JobID(); ok {
|
||||
if err := batchimageevent.JobIDValidator(v); err != nil {
|
||||
return &ValidationError{Name: "job_id", err: fmt.Errorf(`ent: validator failed for field "BatchImageEvent.job_id": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := _c.mutation.EventType(); !ok {
|
||||
return &ValidationError{Name: "event_type", err: errors.New(`ent: missing required field "BatchImageEvent.event_type"`)}
|
||||
}
|
||||
if v, ok := _c.mutation.EventType(); ok {
|
||||
if err := batchimageevent.EventTypeValidator(v); err != nil {
|
||||
return &ValidationError{Name: "event_type", err: fmt.Errorf(`ent: validator failed for field "BatchImageEvent.event_type": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := _c.mutation.EventHash(); ok {
|
||||
if err := batchimageevent.EventHashValidator(v); err != nil {
|
||||
return &ValidationError{Name: "event_hash", err: fmt.Errorf(`ent: validator failed for field "BatchImageEvent.event_hash": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := _c.mutation.CreatedAt(); !ok {
|
||||
return &ValidationError{Name: "created_at", err: errors.New(`ent: missing required field "BatchImageEvent.created_at"`)}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_c *BatchImageEventCreate) sqlSave(ctx context.Context) (*BatchImageEvent, error) {
|
||||
if err := _c.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_node, _spec := _c.createSpec()
|
||||
if err := sqlgraph.CreateNode(ctx, _c.driver, _spec); err != nil {
|
||||
if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
id := _spec.ID.Value.(int64)
|
||||
_node.ID = int64(id)
|
||||
_c.mutation.id = &_node.ID
|
||||
_c.mutation.done = true
|
||||
return _node, nil
|
||||
}
|
||||
|
||||
func (_c *BatchImageEventCreate) createSpec() (*BatchImageEvent, *sqlgraph.CreateSpec) {
|
||||
var (
|
||||
_node = &BatchImageEvent{config: _c.config}
|
||||
_spec = sqlgraph.NewCreateSpec(batchimageevent.Table, sqlgraph.NewFieldSpec(batchimageevent.FieldID, field.TypeInt64))
|
||||
)
|
||||
_spec.OnConflict = _c.conflict
|
||||
if value, ok := _c.mutation.JobID(); ok {
|
||||
_spec.SetField(batchimageevent.FieldJobID, field.TypeString, value)
|
||||
_node.JobID = value
|
||||
}
|
||||
if value, ok := _c.mutation.EventType(); ok {
|
||||
_spec.SetField(batchimageevent.FieldEventType, field.TypeString, value)
|
||||
_node.EventType = value
|
||||
}
|
||||
if value, ok := _c.mutation.Payload(); ok {
|
||||
_spec.SetField(batchimageevent.FieldPayload, field.TypeJSON, value)
|
||||
_node.Payload = value
|
||||
}
|
||||
if value, ok := _c.mutation.EventHash(); ok {
|
||||
_spec.SetField(batchimageevent.FieldEventHash, field.TypeString, value)
|
||||
_node.EventHash = &value
|
||||
}
|
||||
if value, ok := _c.mutation.CreatedAt(); ok {
|
||||
_spec.SetField(batchimageevent.FieldCreatedAt, field.TypeTime, value)
|
||||
_node.CreatedAt = value
|
||||
}
|
||||
return _node, _spec
|
||||
}
|
||||
|
||||
// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
|
||||
// of the `INSERT` statement. For example:
|
||||
//
|
||||
// client.BatchImageEvent.Create().
|
||||
// SetJobID(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.BatchImageEventUpsert) {
|
||||
// SetJobID(v+v).
|
||||
// }).
|
||||
// Exec(ctx)
|
||||
func (_c *BatchImageEventCreate) OnConflict(opts ...sql.ConflictOption) *BatchImageEventUpsertOne {
|
||||
_c.conflict = opts
|
||||
return &BatchImageEventUpsertOne{
|
||||
create: _c,
|
||||
}
|
||||
}
|
||||
|
||||
// OnConflictColumns calls `OnConflict` and configures the columns
|
||||
// as conflict target. Using this option is equivalent to using:
|
||||
//
|
||||
// client.BatchImageEvent.Create().
|
||||
// OnConflict(sql.ConflictColumns(columns...)).
|
||||
// Exec(ctx)
|
||||
func (_c *BatchImageEventCreate) OnConflictColumns(columns ...string) *BatchImageEventUpsertOne {
|
||||
_c.conflict = append(_c.conflict, sql.ConflictColumns(columns...))
|
||||
return &BatchImageEventUpsertOne{
|
||||
create: _c,
|
||||
}
|
||||
}
|
||||
|
||||
type (
|
||||
// BatchImageEventUpsertOne is the builder for "upsert"-ing
|
||||
// one BatchImageEvent node.
|
||||
BatchImageEventUpsertOne struct {
|
||||
create *BatchImageEventCreate
|
||||
}
|
||||
|
||||
// BatchImageEventUpsert is the "OnConflict" setter.
|
||||
BatchImageEventUpsert struct {
|
||||
*sql.UpdateSet
|
||||
}
|
||||
)
|
||||
|
||||
// SetJobID sets the "job_id" field.
|
||||
func (u *BatchImageEventUpsert) SetJobID(v string) *BatchImageEventUpsert {
|
||||
u.Set(batchimageevent.FieldJobID, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateJobID sets the "job_id" field to the value that was provided on create.
|
||||
func (u *BatchImageEventUpsert) UpdateJobID() *BatchImageEventUpsert {
|
||||
u.SetExcluded(batchimageevent.FieldJobID)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetEventType sets the "event_type" field.
|
||||
func (u *BatchImageEventUpsert) SetEventType(v string) *BatchImageEventUpsert {
|
||||
u.Set(batchimageevent.FieldEventType, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateEventType sets the "event_type" field to the value that was provided on create.
|
||||
func (u *BatchImageEventUpsert) UpdateEventType() *BatchImageEventUpsert {
|
||||
u.SetExcluded(batchimageevent.FieldEventType)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetPayload sets the "payload" field.
|
||||
func (u *BatchImageEventUpsert) SetPayload(v map[string]interface{}) *BatchImageEventUpsert {
|
||||
u.Set(batchimageevent.FieldPayload, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdatePayload sets the "payload" field to the value that was provided on create.
|
||||
func (u *BatchImageEventUpsert) UpdatePayload() *BatchImageEventUpsert {
|
||||
u.SetExcluded(batchimageevent.FieldPayload)
|
||||
return u
|
||||
}
|
||||
|
||||
// ClearPayload clears the value of the "payload" field.
|
||||
func (u *BatchImageEventUpsert) ClearPayload() *BatchImageEventUpsert {
|
||||
u.SetNull(batchimageevent.FieldPayload)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetEventHash sets the "event_hash" field.
|
||||
func (u *BatchImageEventUpsert) SetEventHash(v string) *BatchImageEventUpsert {
|
||||
u.Set(batchimageevent.FieldEventHash, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateEventHash sets the "event_hash" field to the value that was provided on create.
|
||||
func (u *BatchImageEventUpsert) UpdateEventHash() *BatchImageEventUpsert {
|
||||
u.SetExcluded(batchimageevent.FieldEventHash)
|
||||
return u
|
||||
}
|
||||
|
||||
// ClearEventHash clears the value of the "event_hash" field.
|
||||
func (u *BatchImageEventUpsert) ClearEventHash() *BatchImageEventUpsert {
|
||||
u.SetNull(batchimageevent.FieldEventHash)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateNewValues updates the mutable fields using the new values that were set on create.
|
||||
// Using this option is equivalent to using:
|
||||
//
|
||||
// client.BatchImageEvent.Create().
|
||||
// OnConflict(
|
||||
// sql.ResolveWithNewValues(),
|
||||
// ).
|
||||
// Exec(ctx)
|
||||
func (u *BatchImageEventUpsertOne) UpdateNewValues() *BatchImageEventUpsertOne {
|
||||
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(batchimageevent.FieldCreatedAt)
|
||||
}
|
||||
}))
|
||||
return u
|
||||
}
|
||||
|
||||
// Ignore sets each column to itself in case of conflict.
|
||||
// Using this option is equivalent to using:
|
||||
//
|
||||
// client.BatchImageEvent.Create().
|
||||
// OnConflict(sql.ResolveWithIgnore()).
|
||||
// Exec(ctx)
|
||||
func (u *BatchImageEventUpsertOne) Ignore() *BatchImageEventUpsertOne {
|
||||
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 *BatchImageEventUpsertOne) DoNothing() *BatchImageEventUpsertOne {
|
||||
u.create.conflict = append(u.create.conflict, sql.DoNothing())
|
||||
return u
|
||||
}
|
||||
|
||||
// Update allows overriding fields `UPDATE` values. See the BatchImageEventCreate.OnConflict
|
||||
// documentation for more info.
|
||||
func (u *BatchImageEventUpsertOne) Update(set func(*BatchImageEventUpsert)) *BatchImageEventUpsertOne {
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
|
||||
set(&BatchImageEventUpsert{UpdateSet: update})
|
||||
}))
|
||||
return u
|
||||
}
|
||||
|
||||
// SetJobID sets the "job_id" field.
|
||||
func (u *BatchImageEventUpsertOne) SetJobID(v string) *BatchImageEventUpsertOne {
|
||||
return u.Update(func(s *BatchImageEventUpsert) {
|
||||
s.SetJobID(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateJobID sets the "job_id" field to the value that was provided on create.
|
||||
func (u *BatchImageEventUpsertOne) UpdateJobID() *BatchImageEventUpsertOne {
|
||||
return u.Update(func(s *BatchImageEventUpsert) {
|
||||
s.UpdateJobID()
|
||||
})
|
||||
}
|
||||
|
||||
// SetEventType sets the "event_type" field.
|
||||
func (u *BatchImageEventUpsertOne) SetEventType(v string) *BatchImageEventUpsertOne {
|
||||
return u.Update(func(s *BatchImageEventUpsert) {
|
||||
s.SetEventType(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateEventType sets the "event_type" field to the value that was provided on create.
|
||||
func (u *BatchImageEventUpsertOne) UpdateEventType() *BatchImageEventUpsertOne {
|
||||
return u.Update(func(s *BatchImageEventUpsert) {
|
||||
s.UpdateEventType()
|
||||
})
|
||||
}
|
||||
|
||||
// SetPayload sets the "payload" field.
|
||||
func (u *BatchImageEventUpsertOne) SetPayload(v map[string]interface{}) *BatchImageEventUpsertOne {
|
||||
return u.Update(func(s *BatchImageEventUpsert) {
|
||||
s.SetPayload(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdatePayload sets the "payload" field to the value that was provided on create.
|
||||
func (u *BatchImageEventUpsertOne) UpdatePayload() *BatchImageEventUpsertOne {
|
||||
return u.Update(func(s *BatchImageEventUpsert) {
|
||||
s.UpdatePayload()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearPayload clears the value of the "payload" field.
|
||||
func (u *BatchImageEventUpsertOne) ClearPayload() *BatchImageEventUpsertOne {
|
||||
return u.Update(func(s *BatchImageEventUpsert) {
|
||||
s.ClearPayload()
|
||||
})
|
||||
}
|
||||
|
||||
// SetEventHash sets the "event_hash" field.
|
||||
func (u *BatchImageEventUpsertOne) SetEventHash(v string) *BatchImageEventUpsertOne {
|
||||
return u.Update(func(s *BatchImageEventUpsert) {
|
||||
s.SetEventHash(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateEventHash sets the "event_hash" field to the value that was provided on create.
|
||||
func (u *BatchImageEventUpsertOne) UpdateEventHash() *BatchImageEventUpsertOne {
|
||||
return u.Update(func(s *BatchImageEventUpsert) {
|
||||
s.UpdateEventHash()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearEventHash clears the value of the "event_hash" field.
|
||||
func (u *BatchImageEventUpsertOne) ClearEventHash() *BatchImageEventUpsertOne {
|
||||
return u.Update(func(s *BatchImageEventUpsert) {
|
||||
s.ClearEventHash()
|
||||
})
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (u *BatchImageEventUpsertOne) Exec(ctx context.Context) error {
|
||||
if len(u.create.conflict) == 0 {
|
||||
return errors.New("ent: missing options for BatchImageEventCreate.OnConflict")
|
||||
}
|
||||
return u.create.Exec(ctx)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (u *BatchImageEventUpsertOne) 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 *BatchImageEventUpsertOne) ID(ctx context.Context) (id int64, 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 *BatchImageEventUpsertOne) IDX(ctx context.Context) int64 {
|
||||
id, err := u.ID(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// BatchImageEventCreateBulk is the builder for creating many BatchImageEvent entities in bulk.
|
||||
type BatchImageEventCreateBulk struct {
|
||||
config
|
||||
err error
|
||||
builders []*BatchImageEventCreate
|
||||
conflict []sql.ConflictOption
|
||||
}
|
||||
|
||||
// Save creates the BatchImageEvent entities in the database.
|
||||
func (_c *BatchImageEventCreateBulk) Save(ctx context.Context) ([]*BatchImageEvent, error) {
|
||||
if _c.err != nil {
|
||||
return nil, _c.err
|
||||
}
|
||||
specs := make([]*sqlgraph.CreateSpec, len(_c.builders))
|
||||
nodes := make([]*BatchImageEvent, len(_c.builders))
|
||||
mutators := make([]Mutator, len(_c.builders))
|
||||
for i := range _c.builders {
|
||||
func(i int, root context.Context) {
|
||||
builder := _c.builders[i]
|
||||
builder.defaults()
|
||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||
mutation, ok := m.(*BatchImageEventMutation)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unexpected mutation type %T", m)
|
||||
}
|
||||
if err := builder.check(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
builder.mutation = mutation
|
||||
var err error
|
||||
nodes[i], specs[i] = builder.createSpec()
|
||||
if i < len(mutators)-1 {
|
||||
_, err = mutators[i+1].Mutate(root, _c.builders[i+1].mutation)
|
||||
} else {
|
||||
spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
|
||||
spec.OnConflict = _c.conflict
|
||||
// Invoke the actual operation on the latest mutation in the chain.
|
||||
if err = sqlgraph.BatchCreate(ctx, _c.driver, spec); err != nil {
|
||||
if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mutation.id = &nodes[i].ID
|
||||
if specs[i].ID.Value != nil {
|
||||
id := specs[i].ID.Value.(int64)
|
||||
nodes[i].ID = int64(id)
|
||||
}
|
||||
mutation.done = true
|
||||
return nodes[i], nil
|
||||
})
|
||||
for i := len(builder.hooks) - 1; i >= 0; i-- {
|
||||
mut = builder.hooks[i](mut)
|
||||
}
|
||||
mutators[i] = mut
|
||||
}(i, ctx)
|
||||
}
|
||||
if len(mutators) > 0 {
|
||||
if _, err := mutators[0].Mutate(ctx, _c.builders[0].mutation); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (_c *BatchImageEventCreateBulk) SaveX(ctx context.Context) []*BatchImageEvent {
|
||||
v, err := _c.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (_c *BatchImageEventCreateBulk) Exec(ctx context.Context) error {
|
||||
_, err := _c.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (_c *BatchImageEventCreateBulk) ExecX(ctx context.Context) {
|
||||
if err := _c.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// OnConflict allows configuring the `ON CONFLICT` / `ON DUPLICATE KEY` clause
|
||||
// of the `INSERT` statement. For example:
|
||||
//
|
||||
// client.BatchImageEvent.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.BatchImageEventUpsert) {
|
||||
// SetJobID(v+v).
|
||||
// }).
|
||||
// Exec(ctx)
|
||||
func (_c *BatchImageEventCreateBulk) OnConflict(opts ...sql.ConflictOption) *BatchImageEventUpsertBulk {
|
||||
_c.conflict = opts
|
||||
return &BatchImageEventUpsertBulk{
|
||||
create: _c,
|
||||
}
|
||||
}
|
||||
|
||||
// OnConflictColumns calls `OnConflict` and configures the columns
|
||||
// as conflict target. Using this option is equivalent to using:
|
||||
//
|
||||
// client.BatchImageEvent.Create().
|
||||
// OnConflict(sql.ConflictColumns(columns...)).
|
||||
// Exec(ctx)
|
||||
func (_c *BatchImageEventCreateBulk) OnConflictColumns(columns ...string) *BatchImageEventUpsertBulk {
|
||||
_c.conflict = append(_c.conflict, sql.ConflictColumns(columns...))
|
||||
return &BatchImageEventUpsertBulk{
|
||||
create: _c,
|
||||
}
|
||||
}
|
||||
|
||||
// BatchImageEventUpsertBulk is the builder for "upsert"-ing
|
||||
// a bulk of BatchImageEvent nodes.
|
||||
type BatchImageEventUpsertBulk struct {
|
||||
create *BatchImageEventCreateBulk
|
||||
}
|
||||
|
||||
// UpdateNewValues updates the mutable fields using the new values that
|
||||
// were set on create. Using this option is equivalent to using:
|
||||
//
|
||||
// client.BatchImageEvent.Create().
|
||||
// OnConflict(
|
||||
// sql.ResolveWithNewValues(),
|
||||
// ).
|
||||
// Exec(ctx)
|
||||
func (u *BatchImageEventUpsertBulk) UpdateNewValues() *BatchImageEventUpsertBulk {
|
||||
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(batchimageevent.FieldCreatedAt)
|
||||
}
|
||||
}
|
||||
}))
|
||||
return u
|
||||
}
|
||||
|
||||
// Ignore sets each column to itself in case of conflict.
|
||||
// Using this option is equivalent to using:
|
||||
//
|
||||
// client.BatchImageEvent.Create().
|
||||
// OnConflict(sql.ResolveWithIgnore()).
|
||||
// Exec(ctx)
|
||||
func (u *BatchImageEventUpsertBulk) Ignore() *BatchImageEventUpsertBulk {
|
||||
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 *BatchImageEventUpsertBulk) DoNothing() *BatchImageEventUpsertBulk {
|
||||
u.create.conflict = append(u.create.conflict, sql.DoNothing())
|
||||
return u
|
||||
}
|
||||
|
||||
// Update allows overriding fields `UPDATE` values. See the BatchImageEventCreateBulk.OnConflict
|
||||
// documentation for more info.
|
||||
func (u *BatchImageEventUpsertBulk) Update(set func(*BatchImageEventUpsert)) *BatchImageEventUpsertBulk {
|
||||
u.create.conflict = append(u.create.conflict, sql.ResolveWith(func(update *sql.UpdateSet) {
|
||||
set(&BatchImageEventUpsert{UpdateSet: update})
|
||||
}))
|
||||
return u
|
||||
}
|
||||
|
||||
// SetJobID sets the "job_id" field.
|
||||
func (u *BatchImageEventUpsertBulk) SetJobID(v string) *BatchImageEventUpsertBulk {
|
||||
return u.Update(func(s *BatchImageEventUpsert) {
|
||||
s.SetJobID(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateJobID sets the "job_id" field to the value that was provided on create.
|
||||
func (u *BatchImageEventUpsertBulk) UpdateJobID() *BatchImageEventUpsertBulk {
|
||||
return u.Update(func(s *BatchImageEventUpsert) {
|
||||
s.UpdateJobID()
|
||||
})
|
||||
}
|
||||
|
||||
// SetEventType sets the "event_type" field.
|
||||
func (u *BatchImageEventUpsertBulk) SetEventType(v string) *BatchImageEventUpsertBulk {
|
||||
return u.Update(func(s *BatchImageEventUpsert) {
|
||||
s.SetEventType(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateEventType sets the "event_type" field to the value that was provided on create.
|
||||
func (u *BatchImageEventUpsertBulk) UpdateEventType() *BatchImageEventUpsertBulk {
|
||||
return u.Update(func(s *BatchImageEventUpsert) {
|
||||
s.UpdateEventType()
|
||||
})
|
||||
}
|
||||
|
||||
// SetPayload sets the "payload" field.
|
||||
func (u *BatchImageEventUpsertBulk) SetPayload(v map[string]interface{}) *BatchImageEventUpsertBulk {
|
||||
return u.Update(func(s *BatchImageEventUpsert) {
|
||||
s.SetPayload(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdatePayload sets the "payload" field to the value that was provided on create.
|
||||
func (u *BatchImageEventUpsertBulk) UpdatePayload() *BatchImageEventUpsertBulk {
|
||||
return u.Update(func(s *BatchImageEventUpsert) {
|
||||
s.UpdatePayload()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearPayload clears the value of the "payload" field.
|
||||
func (u *BatchImageEventUpsertBulk) ClearPayload() *BatchImageEventUpsertBulk {
|
||||
return u.Update(func(s *BatchImageEventUpsert) {
|
||||
s.ClearPayload()
|
||||
})
|
||||
}
|
||||
|
||||
// SetEventHash sets the "event_hash" field.
|
||||
func (u *BatchImageEventUpsertBulk) SetEventHash(v string) *BatchImageEventUpsertBulk {
|
||||
return u.Update(func(s *BatchImageEventUpsert) {
|
||||
s.SetEventHash(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateEventHash sets the "event_hash" field to the value that was provided on create.
|
||||
func (u *BatchImageEventUpsertBulk) UpdateEventHash() *BatchImageEventUpsertBulk {
|
||||
return u.Update(func(s *BatchImageEventUpsert) {
|
||||
s.UpdateEventHash()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearEventHash clears the value of the "event_hash" field.
|
||||
func (u *BatchImageEventUpsertBulk) ClearEventHash() *BatchImageEventUpsertBulk {
|
||||
return u.Update(func(s *BatchImageEventUpsert) {
|
||||
s.ClearEventHash()
|
||||
})
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (u *BatchImageEventUpsertBulk) 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 BatchImageEventCreateBulk instead", i)
|
||||
}
|
||||
}
|
||||
if len(u.create.conflict) == 0 {
|
||||
return errors.New("ent: missing options for BatchImageEventCreateBulk.OnConflict")
|
||||
}
|
||||
return u.create.Exec(ctx)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (u *BatchImageEventUpsertBulk) ExecX(ctx context.Context) {
|
||||
if err := u.create.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -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/Wei-Shaw/sub2api/ent/batchimageevent"
|
||||
"github.com/Wei-Shaw/sub2api/ent/predicate"
|
||||
)
|
||||
|
||||
// BatchImageEventDelete is the builder for deleting a BatchImageEvent entity.
|
||||
type BatchImageEventDelete struct {
|
||||
config
|
||||
hooks []Hook
|
||||
mutation *BatchImageEventMutation
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the BatchImageEventDelete builder.
|
||||
func (_d *BatchImageEventDelete) Where(ps ...predicate.BatchImageEvent) *BatchImageEventDelete {
|
||||
_d.mutation.Where(ps...)
|
||||
return _d
|
||||
}
|
||||
|
||||
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||
func (_d *BatchImageEventDelete) Exec(ctx context.Context) (int, error) {
|
||||
return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (_d *BatchImageEventDelete) ExecX(ctx context.Context) int {
|
||||
n, err := _d.Exec(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (_d *BatchImageEventDelete) sqlExec(ctx context.Context) (int, error) {
|
||||
_spec := sqlgraph.NewDeleteSpec(batchimageevent.Table, sqlgraph.NewFieldSpec(batchimageevent.FieldID, field.TypeInt64))
|
||||
if ps := _d.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec)
|
||||
if err != nil && sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
_d.mutation.done = true
|
||||
return affected, err
|
||||
}
|
||||
|
||||
// BatchImageEventDeleteOne is the builder for deleting a single BatchImageEvent entity.
|
||||
type BatchImageEventDeleteOne struct {
|
||||
_d *BatchImageEventDelete
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the BatchImageEventDelete builder.
|
||||
func (_d *BatchImageEventDeleteOne) Where(ps ...predicate.BatchImageEvent) *BatchImageEventDeleteOne {
|
||||
_d._d.mutation.Where(ps...)
|
||||
return _d
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (_d *BatchImageEventDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := _d._d.Exec(ctx)
|
||||
switch {
|
||||
case err != nil:
|
||||
return err
|
||||
case n == 0:
|
||||
return &NotFoundError{batchimageevent.Label}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (_d *BatchImageEventDeleteOne) ExecX(ctx context.Context) {
|
||||
if err := _d.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,564 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/Wei-Shaw/sub2api/ent/batchimageevent"
|
||||
"github.com/Wei-Shaw/sub2api/ent/predicate"
|
||||
)
|
||||
|
||||
// BatchImageEventQuery is the builder for querying BatchImageEvent entities.
|
||||
type BatchImageEventQuery struct {
|
||||
config
|
||||
ctx *QueryContext
|
||||
order []batchimageevent.OrderOption
|
||||
inters []Interceptor
|
||||
predicates []predicate.BatchImageEvent
|
||||
modifiers []func(*sql.Selector)
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the BatchImageEventQuery builder.
|
||||
func (_q *BatchImageEventQuery) Where(ps ...predicate.BatchImageEvent) *BatchImageEventQuery {
|
||||
_q.predicates = append(_q.predicates, ps...)
|
||||
return _q
|
||||
}
|
||||
|
||||
// Limit the number of records to be returned by this query.
|
||||
func (_q *BatchImageEventQuery) Limit(limit int) *BatchImageEventQuery {
|
||||
_q.ctx.Limit = &limit
|
||||
return _q
|
||||
}
|
||||
|
||||
// Offset to start from.
|
||||
func (_q *BatchImageEventQuery) Offset(offset int) *BatchImageEventQuery {
|
||||
_q.ctx.Offset = &offset
|
||||
return _q
|
||||
}
|
||||
|
||||
// Unique configures the query builder to filter duplicate records on query.
|
||||
// By default, unique is set to true, and can be disabled using this method.
|
||||
func (_q *BatchImageEventQuery) Unique(unique bool) *BatchImageEventQuery {
|
||||
_q.ctx.Unique = &unique
|
||||
return _q
|
||||
}
|
||||
|
||||
// Order specifies how the records should be ordered.
|
||||
func (_q *BatchImageEventQuery) Order(o ...batchimageevent.OrderOption) *BatchImageEventQuery {
|
||||
_q.order = append(_q.order, o...)
|
||||
return _q
|
||||
}
|
||||
|
||||
// First returns the first BatchImageEvent entity from the query.
|
||||
// Returns a *NotFoundError when no BatchImageEvent was found.
|
||||
func (_q *BatchImageEventQuery) First(ctx context.Context) (*BatchImageEvent, error) {
|
||||
nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nil, &NotFoundError{batchimageevent.Label}
|
||||
}
|
||||
return nodes[0], nil
|
||||
}
|
||||
|
||||
// FirstX is like First, but panics if an error occurs.
|
||||
func (_q *BatchImageEventQuery) FirstX(ctx context.Context) *BatchImageEvent {
|
||||
node, err := _q.First(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// FirstID returns the first BatchImageEvent ID from the query.
|
||||
// Returns a *NotFoundError when no BatchImageEvent ID was found.
|
||||
func (_q *BatchImageEventQuery) FirstID(ctx context.Context) (id int64, err error) {
|
||||
var ids []int64
|
||||
if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
err = &NotFoundError{batchimageevent.Label}
|
||||
return
|
||||
}
|
||||
return ids[0], nil
|
||||
}
|
||||
|
||||
// FirstIDX is like FirstID, but panics if an error occurs.
|
||||
func (_q *BatchImageEventQuery) FirstIDX(ctx context.Context) int64 {
|
||||
id, err := _q.FirstID(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// Only returns a single BatchImageEvent entity found by the query, ensuring it only returns one.
|
||||
// Returns a *NotSingularError when more than one BatchImageEvent entity is found.
|
||||
// Returns a *NotFoundError when no BatchImageEvent entities are found.
|
||||
func (_q *BatchImageEventQuery) Only(ctx context.Context) (*BatchImageEvent, error) {
|
||||
nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch len(nodes) {
|
||||
case 1:
|
||||
return nodes[0], nil
|
||||
case 0:
|
||||
return nil, &NotFoundError{batchimageevent.Label}
|
||||
default:
|
||||
return nil, &NotSingularError{batchimageevent.Label}
|
||||
}
|
||||
}
|
||||
|
||||
// OnlyX is like Only, but panics if an error occurs.
|
||||
func (_q *BatchImageEventQuery) OnlyX(ctx context.Context) *BatchImageEvent {
|
||||
node, err := _q.Only(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// OnlyID is like Only, but returns the only BatchImageEvent ID in the query.
|
||||
// Returns a *NotSingularError when more than one BatchImageEvent ID is found.
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (_q *BatchImageEventQuery) OnlyID(ctx context.Context) (id int64, err error) {
|
||||
var ids []int64
|
||||
if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
case 1:
|
||||
id = ids[0]
|
||||
case 0:
|
||||
err = &NotFoundError{batchimageevent.Label}
|
||||
default:
|
||||
err = &NotSingularError{batchimageevent.Label}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// OnlyIDX is like OnlyID, but panics if an error occurs.
|
||||
func (_q *BatchImageEventQuery) OnlyIDX(ctx context.Context) int64 {
|
||||
id, err := _q.OnlyID(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// All executes the query and returns a list of BatchImageEvents.
|
||||
func (_q *BatchImageEventQuery) All(ctx context.Context) ([]*BatchImageEvent, error) {
|
||||
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll)
|
||||
if err := _q.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
qr := querierAll[[]*BatchImageEvent, *BatchImageEventQuery]()
|
||||
return withInterceptors[[]*BatchImageEvent](ctx, _q, qr, _q.inters)
|
||||
}
|
||||
|
||||
// AllX is like All, but panics if an error occurs.
|
||||
func (_q *BatchImageEventQuery) AllX(ctx context.Context) []*BatchImageEvent {
|
||||
nodes, err := _q.All(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
// IDs executes the query and returns a list of BatchImageEvent IDs.
|
||||
func (_q *BatchImageEventQuery) IDs(ctx context.Context) (ids []int64, err error) {
|
||||
if _q.ctx.Unique == nil && _q.path != nil {
|
||||
_q.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs)
|
||||
if err = _q.Select(batchimageevent.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
// IDsX is like IDs, but panics if an error occurs.
|
||||
func (_q *BatchImageEventQuery) IDsX(ctx context.Context) []int64 {
|
||||
ids, err := _q.IDs(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (_q *BatchImageEventQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount)
|
||||
if err := _q.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return withInterceptors[int](ctx, _q, querierCount[*BatchImageEventQuery](), _q.inters)
|
||||
}
|
||||
|
||||
// CountX is like Count, but panics if an error occurs.
|
||||
func (_q *BatchImageEventQuery) CountX(ctx context.Context) int {
|
||||
count, err := _q.Count(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (_q *BatchImageEventQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist)
|
||||
switch _, err := _q.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
case err != nil:
|
||||
return false, fmt.Errorf("ent: check existence: %w", err)
|
||||
default:
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
// ExistX is like Exist, but panics if an error occurs.
|
||||
func (_q *BatchImageEventQuery) ExistX(ctx context.Context) bool {
|
||||
exist, err := _q.Exist(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return exist
|
||||
}
|
||||
|
||||
// Clone returns a duplicate of the BatchImageEventQuery builder, including all associated steps. It can be
|
||||
// used to prepare common query builders and use them differently after the clone is made.
|
||||
func (_q *BatchImageEventQuery) Clone() *BatchImageEventQuery {
|
||||
if _q == nil {
|
||||
return nil
|
||||
}
|
||||
return &BatchImageEventQuery{
|
||||
config: _q.config,
|
||||
ctx: _q.ctx.Clone(),
|
||||
order: append([]batchimageevent.OrderOption{}, _q.order...),
|
||||
inters: append([]Interceptor{}, _q.inters...),
|
||||
predicates: append([]predicate.BatchImageEvent{}, _q.predicates...),
|
||||
// clone intermediate query.
|
||||
sql: _q.sql.Clone(),
|
||||
path: _q.path,
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// JobID string `json:"job_id,omitempty"`
|
||||
// Count int `json:"count,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.BatchImageEvent.Query().
|
||||
// GroupBy(batchimageevent.FieldJobID).
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (_q *BatchImageEventQuery) GroupBy(field string, fields ...string) *BatchImageEventGroupBy {
|
||||
_q.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &BatchImageEventGroupBy{build: _q}
|
||||
grbuild.flds = &_q.ctx.Fields
|
||||
grbuild.label = batchimageevent.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 {
|
||||
// JobID string `json:"job_id,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.BatchImageEvent.Query().
|
||||
// Select(batchimageevent.FieldJobID).
|
||||
// Scan(ctx, &v)
|
||||
func (_q *BatchImageEventQuery) Select(fields ...string) *BatchImageEventSelect {
|
||||
_q.ctx.Fields = append(_q.ctx.Fields, fields...)
|
||||
sbuild := &BatchImageEventSelect{BatchImageEventQuery: _q}
|
||||
sbuild.label = batchimageevent.Label
|
||||
sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
// Aggregate returns a BatchImageEventSelect configured with the given aggregations.
|
||||
func (_q *BatchImageEventQuery) Aggregate(fns ...AggregateFunc) *BatchImageEventSelect {
|
||||
return _q.Select().Aggregate(fns...)
|
||||
}
|
||||
|
||||
func (_q *BatchImageEventQuery) prepareQuery(ctx context.Context) error {
|
||||
for _, inter := range _q.inters {
|
||||
if inter == nil {
|
||||
return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
|
||||
}
|
||||
if trv, ok := inter.(Traverser); ok {
|
||||
if err := trv.Traverse(ctx, _q); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range _q.ctx.Fields {
|
||||
if !batchimageevent.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
}
|
||||
if _q.path != nil {
|
||||
prev, err := _q.path(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_q.sql = prev
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_q *BatchImageEventQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*BatchImageEvent, error) {
|
||||
var (
|
||||
nodes = []*BatchImageEvent{}
|
||||
_spec = _q.querySpec()
|
||||
)
|
||||
_spec.ScanValues = func(columns []string) ([]any, error) {
|
||||
return (*BatchImageEvent).scanValues(nil, columns)
|
||||
}
|
||||
_spec.Assign = func(columns []string, values []any) error {
|
||||
node := &BatchImageEvent{config: _q.config}
|
||||
nodes = append(nodes, node)
|
||||
return node.assignValues(columns, values)
|
||||
}
|
||||
if len(_q.modifiers) > 0 {
|
||||
_spec.Modifiers = _q.modifiers
|
||||
}
|
||||
for i := range hooks {
|
||||
hooks[i](ctx, _spec)
|
||||
}
|
||||
if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nodes, nil
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
func (_q *BatchImageEventQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := _q.querySpec()
|
||||
if len(_q.modifiers) > 0 {
|
||||
_spec.Modifiers = _q.modifiers
|
||||
}
|
||||
_spec.Node.Columns = _q.ctx.Fields
|
||||
if len(_q.ctx.Fields) > 0 {
|
||||
_spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, _q.driver, _spec)
|
||||
}
|
||||
|
||||
func (_q *BatchImageEventQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
_spec := sqlgraph.NewQuerySpec(batchimageevent.Table, batchimageevent.Columns, sqlgraph.NewFieldSpec(batchimageevent.FieldID, field.TypeInt64))
|
||||
_spec.From = _q.sql
|
||||
if unique := _q.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
} else if _q.path != nil {
|
||||
_spec.Unique = true
|
||||
}
|
||||
if fields := _q.ctx.Fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, batchimageevent.FieldID)
|
||||
for i := range fields {
|
||||
if fields[i] != batchimageevent.FieldID {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
if ps := _q.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := _q.ctx.Limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := _q.ctx.Offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := _q.order; len(ps) > 0 {
|
||||
_spec.Order = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
return _spec
|
||||
}
|
||||
|
||||
func (_q *BatchImageEventQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(_q.driver.Dialect())
|
||||
t1 := builder.Table(batchimageevent.Table)
|
||||
columns := _q.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = batchimageevent.Columns
|
||||
}
|
||||
selector := builder.Select(t1.Columns(columns...)...).From(t1)
|
||||
if _q.sql != nil {
|
||||
selector = _q.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if _q.ctx.Unique != nil && *_q.ctx.Unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, m := range _q.modifiers {
|
||||
m(selector)
|
||||
}
|
||||
for _, p := range _q.predicates {
|
||||
p(selector)
|
||||
}
|
||||
for _, p := range _q.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := _q.ctx.Offset; offset != nil {
|
||||
// limit is mandatory for offset clause. We start
|
||||
// with default value, and override it below if needed.
|
||||
selector.Offset(*offset).Limit(math.MaxInt32)
|
||||
}
|
||||
if limit := _q.ctx.Limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
}
|
||||
|
||||
// ForUpdate locks the selected rows against concurrent updates, and prevent them from being
|
||||
// updated, deleted or "selected ... for update" by other sessions, until the transaction is
|
||||
// either committed or rolled-back.
|
||||
func (_q *BatchImageEventQuery) ForUpdate(opts ...sql.LockOption) *BatchImageEventQuery {
|
||||
if _q.driver.Dialect() == dialect.Postgres {
|
||||
_q.Unique(false)
|
||||
}
|
||||
_q.modifiers = append(_q.modifiers, func(s *sql.Selector) {
|
||||
s.ForUpdate(opts...)
|
||||
})
|
||||
return _q
|
||||
}
|
||||
|
||||
// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock
|
||||
// on any rows that are read. Other sessions can read the rows, but cannot modify them
|
||||
// until your transaction commits.
|
||||
func (_q *BatchImageEventQuery) ForShare(opts ...sql.LockOption) *BatchImageEventQuery {
|
||||
if _q.driver.Dialect() == dialect.Postgres {
|
||||
_q.Unique(false)
|
||||
}
|
||||
_q.modifiers = append(_q.modifiers, func(s *sql.Selector) {
|
||||
s.ForShare(opts...)
|
||||
})
|
||||
return _q
|
||||
}
|
||||
|
||||
// BatchImageEventGroupBy is the group-by builder for BatchImageEvent entities.
|
||||
type BatchImageEventGroupBy struct {
|
||||
selector
|
||||
build *BatchImageEventQuery
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the group-by query.
|
||||
func (_g *BatchImageEventGroupBy) Aggregate(fns ...AggregateFunc) *BatchImageEventGroupBy {
|
||||
_g.fns = append(_g.fns, fns...)
|
||||
return _g
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (_g *BatchImageEventGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy)
|
||||
if err := _g.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return scanWithInterceptors[*BatchImageEventQuery, *BatchImageEventGroupBy](ctx, _g.build, _g, _g.build.inters, v)
|
||||
}
|
||||
|
||||
func (_g *BatchImageEventGroupBy) sqlScan(ctx context.Context, root *BatchImageEventQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx).Select()
|
||||
aggregation := make([]string, 0, len(_g.fns))
|
||||
for _, fn := range _g.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
if len(selector.SelectedColumns()) == 0 {
|
||||
columns := make([]string, 0, len(*_g.flds)+len(_g.fns))
|
||||
for _, f := range *_g.flds {
|
||||
columns = append(columns, selector.C(f))
|
||||
}
|
||||
columns = append(columns, aggregation...)
|
||||
selector.Select(columns...)
|
||||
}
|
||||
selector.GroupBy(selector.Columns(*_g.flds...)...)
|
||||
if err := selector.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := _g.build.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
// BatchImageEventSelect is the builder for selecting fields of BatchImageEvent entities.
|
||||
type BatchImageEventSelect struct {
|
||||
*BatchImageEventQuery
|
||||
selector
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the selector query.
|
||||
func (_s *BatchImageEventSelect) Aggregate(fns ...AggregateFunc) *BatchImageEventSelect {
|
||||
_s.fns = append(_s.fns, fns...)
|
||||
return _s
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (_s *BatchImageEventSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect)
|
||||
if err := _s.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return scanWithInterceptors[*BatchImageEventQuery, *BatchImageEventSelect](ctx, _s.BatchImageEventQuery, _s, _s.inters, v)
|
||||
}
|
||||
|
||||
func (_s *BatchImageEventSelect) sqlScan(ctx context.Context, root *BatchImageEventQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx)
|
||||
aggregation := make([]string, 0, len(_s.fns))
|
||||
for _, fn := range _s.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
switch n := len(*_s.selector.flds); {
|
||||
case n == 0 && len(aggregation) > 0:
|
||||
selector.Select(aggregation...)
|
||||
case n != 0 && len(aggregation) > 0:
|
||||
selector.AppendSelect(aggregation...)
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := _s.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
@@ -0,0 +1,377 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/Wei-Shaw/sub2api/ent/batchimageevent"
|
||||
"github.com/Wei-Shaw/sub2api/ent/predicate"
|
||||
)
|
||||
|
||||
// BatchImageEventUpdate is the builder for updating BatchImageEvent entities.
|
||||
type BatchImageEventUpdate struct {
|
||||
config
|
||||
hooks []Hook
|
||||
mutation *BatchImageEventMutation
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the BatchImageEventUpdate builder.
|
||||
func (_u *BatchImageEventUpdate) Where(ps ...predicate.BatchImageEvent) *BatchImageEventUpdate {
|
||||
_u.mutation.Where(ps...)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetJobID sets the "job_id" field.
|
||||
func (_u *BatchImageEventUpdate) SetJobID(v string) *BatchImageEventUpdate {
|
||||
_u.mutation.SetJobID(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableJobID sets the "job_id" field if the given value is not nil.
|
||||
func (_u *BatchImageEventUpdate) SetNillableJobID(v *string) *BatchImageEventUpdate {
|
||||
if v != nil {
|
||||
_u.SetJobID(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetEventType sets the "event_type" field.
|
||||
func (_u *BatchImageEventUpdate) SetEventType(v string) *BatchImageEventUpdate {
|
||||
_u.mutation.SetEventType(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableEventType sets the "event_type" field if the given value is not nil.
|
||||
func (_u *BatchImageEventUpdate) SetNillableEventType(v *string) *BatchImageEventUpdate {
|
||||
if v != nil {
|
||||
_u.SetEventType(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetPayload sets the "payload" field.
|
||||
func (_u *BatchImageEventUpdate) SetPayload(v map[string]interface{}) *BatchImageEventUpdate {
|
||||
_u.mutation.SetPayload(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearPayload clears the value of the "payload" field.
|
||||
func (_u *BatchImageEventUpdate) ClearPayload() *BatchImageEventUpdate {
|
||||
_u.mutation.ClearPayload()
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetEventHash sets the "event_hash" field.
|
||||
func (_u *BatchImageEventUpdate) SetEventHash(v string) *BatchImageEventUpdate {
|
||||
_u.mutation.SetEventHash(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableEventHash sets the "event_hash" field if the given value is not nil.
|
||||
func (_u *BatchImageEventUpdate) SetNillableEventHash(v *string) *BatchImageEventUpdate {
|
||||
if v != nil {
|
||||
_u.SetEventHash(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearEventHash clears the value of the "event_hash" field.
|
||||
func (_u *BatchImageEventUpdate) ClearEventHash() *BatchImageEventUpdate {
|
||||
_u.mutation.ClearEventHash()
|
||||
return _u
|
||||
}
|
||||
|
||||
// Mutation returns the BatchImageEventMutation object of the builder.
|
||||
func (_u *BatchImageEventUpdate) Mutation() *BatchImageEventMutation {
|
||||
return _u.mutation
|
||||
}
|
||||
|
||||
// Save executes the query and returns the number of nodes affected by the update operation.
|
||||
func (_u *BatchImageEventUpdate) Save(ctx context.Context) (int, error) {
|
||||
return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks)
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (_u *BatchImageEventUpdate) SaveX(ctx context.Context) int {
|
||||
affected, err := _u.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return affected
|
||||
}
|
||||
|
||||
// Exec executes the query.
|
||||
func (_u *BatchImageEventUpdate) Exec(ctx context.Context) error {
|
||||
_, err := _u.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (_u *BatchImageEventUpdate) ExecX(ctx context.Context) {
|
||||
if err := _u.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (_u *BatchImageEventUpdate) check() error {
|
||||
if v, ok := _u.mutation.JobID(); ok {
|
||||
if err := batchimageevent.JobIDValidator(v); err != nil {
|
||||
return &ValidationError{Name: "job_id", err: fmt.Errorf(`ent: validator failed for field "BatchImageEvent.job_id": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := _u.mutation.EventType(); ok {
|
||||
if err := batchimageevent.EventTypeValidator(v); err != nil {
|
||||
return &ValidationError{Name: "event_type", err: fmt.Errorf(`ent: validator failed for field "BatchImageEvent.event_type": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := _u.mutation.EventHash(); ok {
|
||||
if err := batchimageevent.EventHashValidator(v); err != nil {
|
||||
return &ValidationError{Name: "event_hash", err: fmt.Errorf(`ent: validator failed for field "BatchImageEvent.event_hash": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_u *BatchImageEventUpdate) sqlSave(ctx context.Context) (_node int, err error) {
|
||||
if err := _u.check(); err != nil {
|
||||
return _node, err
|
||||
}
|
||||
_spec := sqlgraph.NewUpdateSpec(batchimageevent.Table, batchimageevent.Columns, sqlgraph.NewFieldSpec(batchimageevent.FieldID, field.TypeInt64))
|
||||
if ps := _u.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if value, ok := _u.mutation.JobID(); ok {
|
||||
_spec.SetField(batchimageevent.FieldJobID, field.TypeString, value)
|
||||
}
|
||||
if value, ok := _u.mutation.EventType(); ok {
|
||||
_spec.SetField(batchimageevent.FieldEventType, field.TypeString, value)
|
||||
}
|
||||
if value, ok := _u.mutation.Payload(); ok {
|
||||
_spec.SetField(batchimageevent.FieldPayload, field.TypeJSON, value)
|
||||
}
|
||||
if _u.mutation.PayloadCleared() {
|
||||
_spec.ClearField(batchimageevent.FieldPayload, field.TypeJSON)
|
||||
}
|
||||
if value, ok := _u.mutation.EventHash(); ok {
|
||||
_spec.SetField(batchimageevent.FieldEventHash, field.TypeString, value)
|
||||
}
|
||||
if _u.mutation.EventHashCleared() {
|
||||
_spec.ClearField(batchimageevent.FieldEventHash, field.TypeString)
|
||||
}
|
||||
if _node, err = sqlgraph.UpdateNodes(ctx, _u.driver, _spec); err != nil {
|
||||
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||
err = &NotFoundError{batchimageevent.Label}
|
||||
} else if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
_u.mutation.done = true
|
||||
return _node, nil
|
||||
}
|
||||
|
||||
// BatchImageEventUpdateOne is the builder for updating a single BatchImageEvent entity.
|
||||
type BatchImageEventUpdateOne struct {
|
||||
config
|
||||
fields []string
|
||||
hooks []Hook
|
||||
mutation *BatchImageEventMutation
|
||||
}
|
||||
|
||||
// SetJobID sets the "job_id" field.
|
||||
func (_u *BatchImageEventUpdateOne) SetJobID(v string) *BatchImageEventUpdateOne {
|
||||
_u.mutation.SetJobID(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableJobID sets the "job_id" field if the given value is not nil.
|
||||
func (_u *BatchImageEventUpdateOne) SetNillableJobID(v *string) *BatchImageEventUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetJobID(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetEventType sets the "event_type" field.
|
||||
func (_u *BatchImageEventUpdateOne) SetEventType(v string) *BatchImageEventUpdateOne {
|
||||
_u.mutation.SetEventType(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableEventType sets the "event_type" field if the given value is not nil.
|
||||
func (_u *BatchImageEventUpdateOne) SetNillableEventType(v *string) *BatchImageEventUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetEventType(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetPayload sets the "payload" field.
|
||||
func (_u *BatchImageEventUpdateOne) SetPayload(v map[string]interface{}) *BatchImageEventUpdateOne {
|
||||
_u.mutation.SetPayload(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearPayload clears the value of the "payload" field.
|
||||
func (_u *BatchImageEventUpdateOne) ClearPayload() *BatchImageEventUpdateOne {
|
||||
_u.mutation.ClearPayload()
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetEventHash sets the "event_hash" field.
|
||||
func (_u *BatchImageEventUpdateOne) SetEventHash(v string) *BatchImageEventUpdateOne {
|
||||
_u.mutation.SetEventHash(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableEventHash sets the "event_hash" field if the given value is not nil.
|
||||
func (_u *BatchImageEventUpdateOne) SetNillableEventHash(v *string) *BatchImageEventUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetEventHash(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearEventHash clears the value of the "event_hash" field.
|
||||
func (_u *BatchImageEventUpdateOne) ClearEventHash() *BatchImageEventUpdateOne {
|
||||
_u.mutation.ClearEventHash()
|
||||
return _u
|
||||
}
|
||||
|
||||
// Mutation returns the BatchImageEventMutation object of the builder.
|
||||
func (_u *BatchImageEventUpdateOne) Mutation() *BatchImageEventMutation {
|
||||
return _u.mutation
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the BatchImageEventUpdate builder.
|
||||
func (_u *BatchImageEventUpdateOne) Where(ps ...predicate.BatchImageEvent) *BatchImageEventUpdateOne {
|
||||
_u.mutation.Where(ps...)
|
||||
return _u
|
||||
}
|
||||
|
||||
// Select allows selecting one or more fields (columns) of the returned entity.
|
||||
// The default is selecting all fields defined in the entity schema.
|
||||
func (_u *BatchImageEventUpdateOne) Select(field string, fields ...string) *BatchImageEventUpdateOne {
|
||||
_u.fields = append([]string{field}, fields...)
|
||||
return _u
|
||||
}
|
||||
|
||||
// Save executes the query and returns the updated BatchImageEvent entity.
|
||||
func (_u *BatchImageEventUpdateOne) Save(ctx context.Context) (*BatchImageEvent, error) {
|
||||
return withHooks(ctx, _u.sqlSave, _u.mutation, _u.hooks)
|
||||
}
|
||||
|
||||
// SaveX is like Save, but panics if an error occurs.
|
||||
func (_u *BatchImageEventUpdateOne) SaveX(ctx context.Context) *BatchImageEvent {
|
||||
node, err := _u.Save(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// Exec executes the query on the entity.
|
||||
func (_u *BatchImageEventUpdateOne) Exec(ctx context.Context) error {
|
||||
_, err := _u.Save(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (_u *BatchImageEventUpdateOne) ExecX(ctx context.Context) {
|
||||
if err := _u.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// check runs all checks and user-defined validators on the builder.
|
||||
func (_u *BatchImageEventUpdateOne) check() error {
|
||||
if v, ok := _u.mutation.JobID(); ok {
|
||||
if err := batchimageevent.JobIDValidator(v); err != nil {
|
||||
return &ValidationError{Name: "job_id", err: fmt.Errorf(`ent: validator failed for field "BatchImageEvent.job_id": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := _u.mutation.EventType(); ok {
|
||||
if err := batchimageevent.EventTypeValidator(v); err != nil {
|
||||
return &ValidationError{Name: "event_type", err: fmt.Errorf(`ent: validator failed for field "BatchImageEvent.event_type": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := _u.mutation.EventHash(); ok {
|
||||
if err := batchimageevent.EventHashValidator(v); err != nil {
|
||||
return &ValidationError{Name: "event_hash", err: fmt.Errorf(`ent: validator failed for field "BatchImageEvent.event_hash": %w`, err)}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_u *BatchImageEventUpdateOne) sqlSave(ctx context.Context) (_node *BatchImageEvent, err error) {
|
||||
if err := _u.check(); err != nil {
|
||||
return _node, err
|
||||
}
|
||||
_spec := sqlgraph.NewUpdateSpec(batchimageevent.Table, batchimageevent.Columns, sqlgraph.NewFieldSpec(batchimageevent.FieldID, field.TypeInt64))
|
||||
id, ok := _u.mutation.ID()
|
||||
if !ok {
|
||||
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "BatchImageEvent.id" for update`)}
|
||||
}
|
||||
_spec.Node.ID.Value = id
|
||||
if fields := _u.fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, batchimageevent.FieldID)
|
||||
for _, f := range fields {
|
||||
if !batchimageevent.ValidColumn(f) {
|
||||
return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
if f != batchimageevent.FieldID {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
if ps := _u.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if value, ok := _u.mutation.JobID(); ok {
|
||||
_spec.SetField(batchimageevent.FieldJobID, field.TypeString, value)
|
||||
}
|
||||
if value, ok := _u.mutation.EventType(); ok {
|
||||
_spec.SetField(batchimageevent.FieldEventType, field.TypeString, value)
|
||||
}
|
||||
if value, ok := _u.mutation.Payload(); ok {
|
||||
_spec.SetField(batchimageevent.FieldPayload, field.TypeJSON, value)
|
||||
}
|
||||
if _u.mutation.PayloadCleared() {
|
||||
_spec.ClearField(batchimageevent.FieldPayload, field.TypeJSON)
|
||||
}
|
||||
if value, ok := _u.mutation.EventHash(); ok {
|
||||
_spec.SetField(batchimageevent.FieldEventHash, field.TypeString, value)
|
||||
}
|
||||
if _u.mutation.EventHashCleared() {
|
||||
_spec.ClearField(batchimageevent.FieldEventHash, field.TypeString)
|
||||
}
|
||||
_node = &BatchImageEvent{config: _u.config}
|
||||
_spec.Assign = _node.assignValues
|
||||
_spec.ScanValues = _node.scanValues
|
||||
if err = sqlgraph.UpdateNode(ctx, _u.driver, _spec); err != nil {
|
||||
if _, ok := err.(*sqlgraph.NotFoundError); ok {
|
||||
err = &NotFoundError{batchimageevent.Label}
|
||||
} else if sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
_u.mutation.done = true
|
||||
return _node, nil
|
||||
}
|
||||
@@ -0,0 +1,320 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"github.com/Wei-Shaw/sub2api/ent/batchimageitem"
|
||||
)
|
||||
|
||||
// BatchImageItem is the model entity for the BatchImageItem schema.
|
||||
type BatchImageItem struct {
|
||||
config `json:"-"`
|
||||
// ID of the ent.
|
||||
ID int64 `json:"id,omitempty"`
|
||||
// JobID holds the value of the "job_id" field.
|
||||
JobID string `json:"job_id,omitempty"`
|
||||
// CustomID holds the value of the "custom_id" field.
|
||||
CustomID string `json:"custom_id,omitempty"`
|
||||
// Status holds the value of the "status" field.
|
||||
Status string `json:"status,omitempty"`
|
||||
// RequestHash holds the value of the "request_hash" field.
|
||||
RequestHash *string `json:"request_hash,omitempty"`
|
||||
// PromptPreview holds the value of the "prompt_preview" field.
|
||||
PromptPreview *string `json:"prompt_preview,omitempty"`
|
||||
// ProviderSourceObject holds the value of the "provider_source_object" field.
|
||||
ProviderSourceObject *string `json:"provider_source_object,omitempty"`
|
||||
// SourceLineNumber holds the value of the "source_line_number" field.
|
||||
SourceLineNumber *int `json:"source_line_number,omitempty"`
|
||||
// SourceByteOffset holds the value of the "source_byte_offset" field.
|
||||
SourceByteOffset *int64 `json:"source_byte_offset,omitempty"`
|
||||
// SourceByteLength holds the value of the "source_byte_length" field.
|
||||
SourceByteLength *int64 `json:"source_byte_length,omitempty"`
|
||||
// MimeType holds the value of the "mime_type" field.
|
||||
MimeType *string `json:"mime_type,omitempty"`
|
||||
// FileExtension holds the value of the "file_extension" field.
|
||||
FileExtension *string `json:"file_extension,omitempty"`
|
||||
// ImageCount holds the value of the "image_count" field.
|
||||
ImageCount int `json:"image_count,omitempty"`
|
||||
// ErrorCode holds the value of the "error_code" field.
|
||||
ErrorCode *string `json:"error_code,omitempty"`
|
||||
// ErrorMessage holds the value of the "error_message" field.
|
||||
ErrorMessage *string `json:"error_message,omitempty"`
|
||||
// BilledAmount holds the value of the "billed_amount" field.
|
||||
BilledAmount *float64 `json:"billed_amount,omitempty"`
|
||||
// CreatedAt holds the value of the "created_at" field.
|
||||
CreatedAt time.Time `json:"created_at,omitempty"`
|
||||
// IndexedAt holds the value of the "indexed_at" field.
|
||||
IndexedAt *time.Time `json:"indexed_at,omitempty"`
|
||||
selectValues sql.SelectValues
|
||||
}
|
||||
|
||||
// scanValues returns the types for scanning values from sql.Rows.
|
||||
func (*BatchImageItem) scanValues(columns []string) ([]any, error) {
|
||||
values := make([]any, len(columns))
|
||||
for i := range columns {
|
||||
switch columns[i] {
|
||||
case batchimageitem.FieldBilledAmount:
|
||||
values[i] = new(sql.NullFloat64)
|
||||
case batchimageitem.FieldID, batchimageitem.FieldSourceLineNumber, batchimageitem.FieldSourceByteOffset, batchimageitem.FieldSourceByteLength, batchimageitem.FieldImageCount:
|
||||
values[i] = new(sql.NullInt64)
|
||||
case batchimageitem.FieldJobID, batchimageitem.FieldCustomID, batchimageitem.FieldStatus, batchimageitem.FieldRequestHash, batchimageitem.FieldPromptPreview, batchimageitem.FieldProviderSourceObject, batchimageitem.FieldMimeType, batchimageitem.FieldFileExtension, batchimageitem.FieldErrorCode, batchimageitem.FieldErrorMessage:
|
||||
values[i] = new(sql.NullString)
|
||||
case batchimageitem.FieldCreatedAt, batchimageitem.FieldIndexedAt:
|
||||
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 BatchImageItem fields.
|
||||
func (_m *BatchImageItem) 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 batchimageitem.FieldID:
|
||||
value, ok := values[i].(*sql.NullInt64)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field id", value)
|
||||
}
|
||||
_m.ID = int64(value.Int64)
|
||||
case batchimageitem.FieldJobID:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field job_id", values[i])
|
||||
} else if value.Valid {
|
||||
_m.JobID = value.String
|
||||
}
|
||||
case batchimageitem.FieldCustomID:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field custom_id", values[i])
|
||||
} else if value.Valid {
|
||||
_m.CustomID = value.String
|
||||
}
|
||||
case batchimageitem.FieldStatus:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field status", values[i])
|
||||
} else if value.Valid {
|
||||
_m.Status = value.String
|
||||
}
|
||||
case batchimageitem.FieldRequestHash:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field request_hash", values[i])
|
||||
} else if value.Valid {
|
||||
_m.RequestHash = new(string)
|
||||
*_m.RequestHash = value.String
|
||||
}
|
||||
case batchimageitem.FieldPromptPreview:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field prompt_preview", values[i])
|
||||
} else if value.Valid {
|
||||
_m.PromptPreview = new(string)
|
||||
*_m.PromptPreview = value.String
|
||||
}
|
||||
case batchimageitem.FieldProviderSourceObject:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field provider_source_object", values[i])
|
||||
} else if value.Valid {
|
||||
_m.ProviderSourceObject = new(string)
|
||||
*_m.ProviderSourceObject = value.String
|
||||
}
|
||||
case batchimageitem.FieldSourceLineNumber:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field source_line_number", values[i])
|
||||
} else if value.Valid {
|
||||
_m.SourceLineNumber = new(int)
|
||||
*_m.SourceLineNumber = int(value.Int64)
|
||||
}
|
||||
case batchimageitem.FieldSourceByteOffset:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field source_byte_offset", values[i])
|
||||
} else if value.Valid {
|
||||
_m.SourceByteOffset = new(int64)
|
||||
*_m.SourceByteOffset = value.Int64
|
||||
}
|
||||
case batchimageitem.FieldSourceByteLength:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field source_byte_length", values[i])
|
||||
} else if value.Valid {
|
||||
_m.SourceByteLength = new(int64)
|
||||
*_m.SourceByteLength = value.Int64
|
||||
}
|
||||
case batchimageitem.FieldMimeType:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field mime_type", values[i])
|
||||
} else if value.Valid {
|
||||
_m.MimeType = new(string)
|
||||
*_m.MimeType = value.String
|
||||
}
|
||||
case batchimageitem.FieldFileExtension:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field file_extension", values[i])
|
||||
} else if value.Valid {
|
||||
_m.FileExtension = new(string)
|
||||
*_m.FileExtension = value.String
|
||||
}
|
||||
case batchimageitem.FieldImageCount:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field image_count", values[i])
|
||||
} else if value.Valid {
|
||||
_m.ImageCount = int(value.Int64)
|
||||
}
|
||||
case batchimageitem.FieldErrorCode:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field error_code", values[i])
|
||||
} else if value.Valid {
|
||||
_m.ErrorCode = new(string)
|
||||
*_m.ErrorCode = value.String
|
||||
}
|
||||
case batchimageitem.FieldErrorMessage:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field error_message", values[i])
|
||||
} else if value.Valid {
|
||||
_m.ErrorMessage = new(string)
|
||||
*_m.ErrorMessage = value.String
|
||||
}
|
||||
case batchimageitem.FieldBilledAmount:
|
||||
if value, ok := values[i].(*sql.NullFloat64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field billed_amount", values[i])
|
||||
} else if value.Valid {
|
||||
_m.BilledAmount = new(float64)
|
||||
*_m.BilledAmount = value.Float64
|
||||
}
|
||||
case batchimageitem.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 {
|
||||
_m.CreatedAt = value.Time
|
||||
}
|
||||
case batchimageitem.FieldIndexedAt:
|
||||
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field indexed_at", values[i])
|
||||
} else if value.Valid {
|
||||
_m.IndexedAt = new(time.Time)
|
||||
*_m.IndexedAt = value.Time
|
||||
}
|
||||
default:
|
||||
_m.selectValues.Set(columns[i], values[i])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value returns the ent.Value that was dynamically selected and assigned to the BatchImageItem.
|
||||
// This includes values selected through modifiers, order, etc.
|
||||
func (_m *BatchImageItem) Value(name string) (ent.Value, error) {
|
||||
return _m.selectValues.Get(name)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this BatchImageItem.
|
||||
// Note that you need to call BatchImageItem.Unwrap() before calling this method if this BatchImageItem
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (_m *BatchImageItem) Update() *BatchImageItemUpdateOne {
|
||||
return NewBatchImageItemClient(_m.config).UpdateOne(_m)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the BatchImageItem entity that was returned from a transaction after it was closed,
|
||||
// so that all future queries will be executed through the driver which created the transaction.
|
||||
func (_m *BatchImageItem) Unwrap() *BatchImageItem {
|
||||
_tx, ok := _m.config.driver.(*txDriver)
|
||||
if !ok {
|
||||
panic("ent: BatchImageItem is not a transactional entity")
|
||||
}
|
||||
_m.config.driver = _tx.drv
|
||||
return _m
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer.
|
||||
func (_m *BatchImageItem) String() string {
|
||||
var builder strings.Builder
|
||||
builder.WriteString("BatchImageItem(")
|
||||
builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID))
|
||||
builder.WriteString("job_id=")
|
||||
builder.WriteString(_m.JobID)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("custom_id=")
|
||||
builder.WriteString(_m.CustomID)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("status=")
|
||||
builder.WriteString(_m.Status)
|
||||
builder.WriteString(", ")
|
||||
if v := _m.RequestHash; v != nil {
|
||||
builder.WriteString("request_hash=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.PromptPreview; v != nil {
|
||||
builder.WriteString("prompt_preview=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.ProviderSourceObject; v != nil {
|
||||
builder.WriteString("provider_source_object=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.SourceLineNumber; v != nil {
|
||||
builder.WriteString("source_line_number=")
|
||||
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.SourceByteOffset; v != nil {
|
||||
builder.WriteString("source_byte_offset=")
|
||||
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.SourceByteLength; v != nil {
|
||||
builder.WriteString("source_byte_length=")
|
||||
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.MimeType; v != nil {
|
||||
builder.WriteString("mime_type=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.FileExtension; v != nil {
|
||||
builder.WriteString("file_extension=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("image_count=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.ImageCount))
|
||||
builder.WriteString(", ")
|
||||
if v := _m.ErrorCode; v != nil {
|
||||
builder.WriteString("error_code=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.ErrorMessage; v != nil {
|
||||
builder.WriteString("error_message=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.BilledAmount; v != nil {
|
||||
builder.WriteString("billed_amount=")
|
||||
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("created_at=")
|
||||
builder.WriteString(_m.CreatedAt.Format(time.ANSIC))
|
||||
builder.WriteString(", ")
|
||||
if v := _m.IndexedAt; v != nil {
|
||||
builder.WriteString("indexed_at=")
|
||||
builder.WriteString(v.Format(time.ANSIC))
|
||||
}
|
||||
builder.WriteByte(')')
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
// BatchImageItems is a parsable slice of BatchImageItem.
|
||||
type BatchImageItems []*BatchImageItem
|
||||
@@ -0,0 +1,200 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package batchimageitem
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
)
|
||||
|
||||
const (
|
||||
// Label holds the string label denoting the batchimageitem type in the database.
|
||||
Label = "batch_image_item"
|
||||
// FieldID holds the string denoting the id field in the database.
|
||||
FieldID = "id"
|
||||
// FieldJobID holds the string denoting the job_id field in the database.
|
||||
FieldJobID = "job_id"
|
||||
// FieldCustomID holds the string denoting the custom_id field in the database.
|
||||
FieldCustomID = "custom_id"
|
||||
// FieldStatus holds the string denoting the status field in the database.
|
||||
FieldStatus = "status"
|
||||
// FieldRequestHash holds the string denoting the request_hash field in the database.
|
||||
FieldRequestHash = "request_hash"
|
||||
// FieldPromptPreview holds the string denoting the prompt_preview field in the database.
|
||||
FieldPromptPreview = "prompt_preview"
|
||||
// FieldProviderSourceObject holds the string denoting the provider_source_object field in the database.
|
||||
FieldProviderSourceObject = "provider_source_object"
|
||||
// FieldSourceLineNumber holds the string denoting the source_line_number field in the database.
|
||||
FieldSourceLineNumber = "source_line_number"
|
||||
// FieldSourceByteOffset holds the string denoting the source_byte_offset field in the database.
|
||||
FieldSourceByteOffset = "source_byte_offset"
|
||||
// FieldSourceByteLength holds the string denoting the source_byte_length field in the database.
|
||||
FieldSourceByteLength = "source_byte_length"
|
||||
// FieldMimeType holds the string denoting the mime_type field in the database.
|
||||
FieldMimeType = "mime_type"
|
||||
// FieldFileExtension holds the string denoting the file_extension field in the database.
|
||||
FieldFileExtension = "file_extension"
|
||||
// FieldImageCount holds the string denoting the image_count field in the database.
|
||||
FieldImageCount = "image_count"
|
||||
// FieldErrorCode holds the string denoting the error_code field in the database.
|
||||
FieldErrorCode = "error_code"
|
||||
// FieldErrorMessage holds the string denoting the error_message field in the database.
|
||||
FieldErrorMessage = "error_message"
|
||||
// FieldBilledAmount holds the string denoting the billed_amount field in the database.
|
||||
FieldBilledAmount = "billed_amount"
|
||||
// FieldCreatedAt holds the string denoting the created_at field in the database.
|
||||
FieldCreatedAt = "created_at"
|
||||
// FieldIndexedAt holds the string denoting the indexed_at field in the database.
|
||||
FieldIndexedAt = "indexed_at"
|
||||
// Table holds the table name of the batchimageitem in the database.
|
||||
Table = "batch_image_items"
|
||||
)
|
||||
|
||||
// Columns holds all SQL columns for batchimageitem fields.
|
||||
var Columns = []string{
|
||||
FieldID,
|
||||
FieldJobID,
|
||||
FieldCustomID,
|
||||
FieldStatus,
|
||||
FieldRequestHash,
|
||||
FieldPromptPreview,
|
||||
FieldProviderSourceObject,
|
||||
FieldSourceLineNumber,
|
||||
FieldSourceByteOffset,
|
||||
FieldSourceByteLength,
|
||||
FieldMimeType,
|
||||
FieldFileExtension,
|
||||
FieldImageCount,
|
||||
FieldErrorCode,
|
||||
FieldErrorMessage,
|
||||
FieldBilledAmount,
|
||||
FieldCreatedAt,
|
||||
FieldIndexedAt,
|
||||
}
|
||||
|
||||
// ValidColumn reports if the column name is valid (part of the table columns).
|
||||
func ValidColumn(column string) bool {
|
||||
for i := range Columns {
|
||||
if column == Columns[i] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var (
|
||||
// JobIDValidator is a validator for the "job_id" field. It is called by the builders before save.
|
||||
JobIDValidator func(string) error
|
||||
// CustomIDValidator is a validator for the "custom_id" field. It is called by the builders before save.
|
||||
CustomIDValidator func(string) error
|
||||
// StatusValidator is a validator for the "status" field. It is called by the builders before save.
|
||||
StatusValidator func(string) error
|
||||
// RequestHashValidator is a validator for the "request_hash" field. It is called by the builders before save.
|
||||
RequestHashValidator func(string) error
|
||||
// ProviderSourceObjectValidator is a validator for the "provider_source_object" field. It is called by the builders before save.
|
||||
ProviderSourceObjectValidator func(string) error
|
||||
// MimeTypeValidator is a validator for the "mime_type" field. It is called by the builders before save.
|
||||
MimeTypeValidator func(string) error
|
||||
// FileExtensionValidator is a validator for the "file_extension" field. It is called by the builders before save.
|
||||
FileExtensionValidator func(string) error
|
||||
// DefaultImageCount holds the default value on creation for the "image_count" field.
|
||||
DefaultImageCount int
|
||||
// ErrorCodeValidator is a validator for the "error_code" field. It is called by the builders before save.
|
||||
ErrorCodeValidator func(string) error
|
||||
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
|
||||
DefaultCreatedAt func() time.Time
|
||||
)
|
||||
|
||||
// OrderOption defines the ordering options for the BatchImageItem 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()
|
||||
}
|
||||
|
||||
// ByJobID orders the results by the job_id field.
|
||||
func ByJobID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldJobID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByCustomID orders the results by the custom_id field.
|
||||
func ByCustomID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldCustomID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByStatus orders the results by the status field.
|
||||
func ByStatus(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldStatus, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByRequestHash orders the results by the request_hash field.
|
||||
func ByRequestHash(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldRequestHash, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByPromptPreview orders the results by the prompt_preview field.
|
||||
func ByPromptPreview(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldPromptPreview, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByProviderSourceObject orders the results by the provider_source_object field.
|
||||
func ByProviderSourceObject(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldProviderSourceObject, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// BySourceLineNumber orders the results by the source_line_number field.
|
||||
func BySourceLineNumber(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldSourceLineNumber, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// BySourceByteOffset orders the results by the source_byte_offset field.
|
||||
func BySourceByteOffset(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldSourceByteOffset, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// BySourceByteLength orders the results by the source_byte_length field.
|
||||
func BySourceByteLength(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldSourceByteLength, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByMimeType orders the results by the mime_type field.
|
||||
func ByMimeType(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldMimeType, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByFileExtension orders the results by the file_extension field.
|
||||
func ByFileExtension(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldFileExtension, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByImageCount orders the results by the image_count field.
|
||||
func ByImageCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldImageCount, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByErrorCode orders the results by the error_code field.
|
||||
func ByErrorCode(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldErrorCode, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByErrorMessage orders the results by the error_message field.
|
||||
func ByErrorMessage(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldErrorMessage, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByBilledAmount orders the results by the billed_amount field.
|
||||
func ByBilledAmount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldBilledAmount, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByCreatedAt orders the results by the created_at field.
|
||||
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByIndexedAt orders the results by the indexed_at field.
|
||||
func ByIndexedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldIndexedAt, opts...).ToFunc()
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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/Wei-Shaw/sub2api/ent/batchimageitem"
|
||||
"github.com/Wei-Shaw/sub2api/ent/predicate"
|
||||
)
|
||||
|
||||
// BatchImageItemDelete is the builder for deleting a BatchImageItem entity.
|
||||
type BatchImageItemDelete struct {
|
||||
config
|
||||
hooks []Hook
|
||||
mutation *BatchImageItemMutation
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the BatchImageItemDelete builder.
|
||||
func (_d *BatchImageItemDelete) Where(ps ...predicate.BatchImageItem) *BatchImageItemDelete {
|
||||
_d.mutation.Where(ps...)
|
||||
return _d
|
||||
}
|
||||
|
||||
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||
func (_d *BatchImageItemDelete) Exec(ctx context.Context) (int, error) {
|
||||
return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (_d *BatchImageItemDelete) ExecX(ctx context.Context) int {
|
||||
n, err := _d.Exec(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (_d *BatchImageItemDelete) sqlExec(ctx context.Context) (int, error) {
|
||||
_spec := sqlgraph.NewDeleteSpec(batchimageitem.Table, sqlgraph.NewFieldSpec(batchimageitem.FieldID, field.TypeInt64))
|
||||
if ps := _d.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec)
|
||||
if err != nil && sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
_d.mutation.done = true
|
||||
return affected, err
|
||||
}
|
||||
|
||||
// BatchImageItemDeleteOne is the builder for deleting a single BatchImageItem entity.
|
||||
type BatchImageItemDeleteOne struct {
|
||||
_d *BatchImageItemDelete
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the BatchImageItemDelete builder.
|
||||
func (_d *BatchImageItemDeleteOne) Where(ps ...predicate.BatchImageItem) *BatchImageItemDeleteOne {
|
||||
_d._d.mutation.Where(ps...)
|
||||
return _d
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (_d *BatchImageItemDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := _d._d.Exec(ctx)
|
||||
switch {
|
||||
case err != nil:
|
||||
return err
|
||||
case n == 0:
|
||||
return &NotFoundError{batchimageitem.Label}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (_d *BatchImageItemDeleteOne) ExecX(ctx context.Context) {
|
||||
if err := _d.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,564 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/Wei-Shaw/sub2api/ent/batchimageitem"
|
||||
"github.com/Wei-Shaw/sub2api/ent/predicate"
|
||||
)
|
||||
|
||||
// BatchImageItemQuery is the builder for querying BatchImageItem entities.
|
||||
type BatchImageItemQuery struct {
|
||||
config
|
||||
ctx *QueryContext
|
||||
order []batchimageitem.OrderOption
|
||||
inters []Interceptor
|
||||
predicates []predicate.BatchImageItem
|
||||
modifiers []func(*sql.Selector)
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the BatchImageItemQuery builder.
|
||||
func (_q *BatchImageItemQuery) Where(ps ...predicate.BatchImageItem) *BatchImageItemQuery {
|
||||
_q.predicates = append(_q.predicates, ps...)
|
||||
return _q
|
||||
}
|
||||
|
||||
// Limit the number of records to be returned by this query.
|
||||
func (_q *BatchImageItemQuery) Limit(limit int) *BatchImageItemQuery {
|
||||
_q.ctx.Limit = &limit
|
||||
return _q
|
||||
}
|
||||
|
||||
// Offset to start from.
|
||||
func (_q *BatchImageItemQuery) Offset(offset int) *BatchImageItemQuery {
|
||||
_q.ctx.Offset = &offset
|
||||
return _q
|
||||
}
|
||||
|
||||
// Unique configures the query builder to filter duplicate records on query.
|
||||
// By default, unique is set to true, and can be disabled using this method.
|
||||
func (_q *BatchImageItemQuery) Unique(unique bool) *BatchImageItemQuery {
|
||||
_q.ctx.Unique = &unique
|
||||
return _q
|
||||
}
|
||||
|
||||
// Order specifies how the records should be ordered.
|
||||
func (_q *BatchImageItemQuery) Order(o ...batchimageitem.OrderOption) *BatchImageItemQuery {
|
||||
_q.order = append(_q.order, o...)
|
||||
return _q
|
||||
}
|
||||
|
||||
// First returns the first BatchImageItem entity from the query.
|
||||
// Returns a *NotFoundError when no BatchImageItem was found.
|
||||
func (_q *BatchImageItemQuery) First(ctx context.Context) (*BatchImageItem, error) {
|
||||
nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nil, &NotFoundError{batchimageitem.Label}
|
||||
}
|
||||
return nodes[0], nil
|
||||
}
|
||||
|
||||
// FirstX is like First, but panics if an error occurs.
|
||||
func (_q *BatchImageItemQuery) FirstX(ctx context.Context) *BatchImageItem {
|
||||
node, err := _q.First(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// FirstID returns the first BatchImageItem ID from the query.
|
||||
// Returns a *NotFoundError when no BatchImageItem ID was found.
|
||||
func (_q *BatchImageItemQuery) FirstID(ctx context.Context) (id int64, err error) {
|
||||
var ids []int64
|
||||
if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
err = &NotFoundError{batchimageitem.Label}
|
||||
return
|
||||
}
|
||||
return ids[0], nil
|
||||
}
|
||||
|
||||
// FirstIDX is like FirstID, but panics if an error occurs.
|
||||
func (_q *BatchImageItemQuery) FirstIDX(ctx context.Context) int64 {
|
||||
id, err := _q.FirstID(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// Only returns a single BatchImageItem entity found by the query, ensuring it only returns one.
|
||||
// Returns a *NotSingularError when more than one BatchImageItem entity is found.
|
||||
// Returns a *NotFoundError when no BatchImageItem entities are found.
|
||||
func (_q *BatchImageItemQuery) Only(ctx context.Context) (*BatchImageItem, error) {
|
||||
nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch len(nodes) {
|
||||
case 1:
|
||||
return nodes[0], nil
|
||||
case 0:
|
||||
return nil, &NotFoundError{batchimageitem.Label}
|
||||
default:
|
||||
return nil, &NotSingularError{batchimageitem.Label}
|
||||
}
|
||||
}
|
||||
|
||||
// OnlyX is like Only, but panics if an error occurs.
|
||||
func (_q *BatchImageItemQuery) OnlyX(ctx context.Context) *BatchImageItem {
|
||||
node, err := _q.Only(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// OnlyID is like Only, but returns the only BatchImageItem ID in the query.
|
||||
// Returns a *NotSingularError when more than one BatchImageItem ID is found.
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (_q *BatchImageItemQuery) OnlyID(ctx context.Context) (id int64, err error) {
|
||||
var ids []int64
|
||||
if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
case 1:
|
||||
id = ids[0]
|
||||
case 0:
|
||||
err = &NotFoundError{batchimageitem.Label}
|
||||
default:
|
||||
err = &NotSingularError{batchimageitem.Label}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// OnlyIDX is like OnlyID, but panics if an error occurs.
|
||||
func (_q *BatchImageItemQuery) OnlyIDX(ctx context.Context) int64 {
|
||||
id, err := _q.OnlyID(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// All executes the query and returns a list of BatchImageItems.
|
||||
func (_q *BatchImageItemQuery) All(ctx context.Context) ([]*BatchImageItem, error) {
|
||||
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll)
|
||||
if err := _q.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
qr := querierAll[[]*BatchImageItem, *BatchImageItemQuery]()
|
||||
return withInterceptors[[]*BatchImageItem](ctx, _q, qr, _q.inters)
|
||||
}
|
||||
|
||||
// AllX is like All, but panics if an error occurs.
|
||||
func (_q *BatchImageItemQuery) AllX(ctx context.Context) []*BatchImageItem {
|
||||
nodes, err := _q.All(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
// IDs executes the query and returns a list of BatchImageItem IDs.
|
||||
func (_q *BatchImageItemQuery) IDs(ctx context.Context) (ids []int64, err error) {
|
||||
if _q.ctx.Unique == nil && _q.path != nil {
|
||||
_q.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs)
|
||||
if err = _q.Select(batchimageitem.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
// IDsX is like IDs, but panics if an error occurs.
|
||||
func (_q *BatchImageItemQuery) IDsX(ctx context.Context) []int64 {
|
||||
ids, err := _q.IDs(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (_q *BatchImageItemQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount)
|
||||
if err := _q.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return withInterceptors[int](ctx, _q, querierCount[*BatchImageItemQuery](), _q.inters)
|
||||
}
|
||||
|
||||
// CountX is like Count, but panics if an error occurs.
|
||||
func (_q *BatchImageItemQuery) CountX(ctx context.Context) int {
|
||||
count, err := _q.Count(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (_q *BatchImageItemQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist)
|
||||
switch _, err := _q.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
case err != nil:
|
||||
return false, fmt.Errorf("ent: check existence: %w", err)
|
||||
default:
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
// ExistX is like Exist, but panics if an error occurs.
|
||||
func (_q *BatchImageItemQuery) ExistX(ctx context.Context) bool {
|
||||
exist, err := _q.Exist(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return exist
|
||||
}
|
||||
|
||||
// Clone returns a duplicate of the BatchImageItemQuery builder, including all associated steps. It can be
|
||||
// used to prepare common query builders and use them differently after the clone is made.
|
||||
func (_q *BatchImageItemQuery) Clone() *BatchImageItemQuery {
|
||||
if _q == nil {
|
||||
return nil
|
||||
}
|
||||
return &BatchImageItemQuery{
|
||||
config: _q.config,
|
||||
ctx: _q.ctx.Clone(),
|
||||
order: append([]batchimageitem.OrderOption{}, _q.order...),
|
||||
inters: append([]Interceptor{}, _q.inters...),
|
||||
predicates: append([]predicate.BatchImageItem{}, _q.predicates...),
|
||||
// clone intermediate query.
|
||||
sql: _q.sql.Clone(),
|
||||
path: _q.path,
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// JobID string `json:"job_id,omitempty"`
|
||||
// Count int `json:"count,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.BatchImageItem.Query().
|
||||
// GroupBy(batchimageitem.FieldJobID).
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (_q *BatchImageItemQuery) GroupBy(field string, fields ...string) *BatchImageItemGroupBy {
|
||||
_q.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &BatchImageItemGroupBy{build: _q}
|
||||
grbuild.flds = &_q.ctx.Fields
|
||||
grbuild.label = batchimageitem.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 {
|
||||
// JobID string `json:"job_id,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.BatchImageItem.Query().
|
||||
// Select(batchimageitem.FieldJobID).
|
||||
// Scan(ctx, &v)
|
||||
func (_q *BatchImageItemQuery) Select(fields ...string) *BatchImageItemSelect {
|
||||
_q.ctx.Fields = append(_q.ctx.Fields, fields...)
|
||||
sbuild := &BatchImageItemSelect{BatchImageItemQuery: _q}
|
||||
sbuild.label = batchimageitem.Label
|
||||
sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
// Aggregate returns a BatchImageItemSelect configured with the given aggregations.
|
||||
func (_q *BatchImageItemQuery) Aggregate(fns ...AggregateFunc) *BatchImageItemSelect {
|
||||
return _q.Select().Aggregate(fns...)
|
||||
}
|
||||
|
||||
func (_q *BatchImageItemQuery) prepareQuery(ctx context.Context) error {
|
||||
for _, inter := range _q.inters {
|
||||
if inter == nil {
|
||||
return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
|
||||
}
|
||||
if trv, ok := inter.(Traverser); ok {
|
||||
if err := trv.Traverse(ctx, _q); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range _q.ctx.Fields {
|
||||
if !batchimageitem.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
}
|
||||
if _q.path != nil {
|
||||
prev, err := _q.path(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_q.sql = prev
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_q *BatchImageItemQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*BatchImageItem, error) {
|
||||
var (
|
||||
nodes = []*BatchImageItem{}
|
||||
_spec = _q.querySpec()
|
||||
)
|
||||
_spec.ScanValues = func(columns []string) ([]any, error) {
|
||||
return (*BatchImageItem).scanValues(nil, columns)
|
||||
}
|
||||
_spec.Assign = func(columns []string, values []any) error {
|
||||
node := &BatchImageItem{config: _q.config}
|
||||
nodes = append(nodes, node)
|
||||
return node.assignValues(columns, values)
|
||||
}
|
||||
if len(_q.modifiers) > 0 {
|
||||
_spec.Modifiers = _q.modifiers
|
||||
}
|
||||
for i := range hooks {
|
||||
hooks[i](ctx, _spec)
|
||||
}
|
||||
if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nodes, nil
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
func (_q *BatchImageItemQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := _q.querySpec()
|
||||
if len(_q.modifiers) > 0 {
|
||||
_spec.Modifiers = _q.modifiers
|
||||
}
|
||||
_spec.Node.Columns = _q.ctx.Fields
|
||||
if len(_q.ctx.Fields) > 0 {
|
||||
_spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, _q.driver, _spec)
|
||||
}
|
||||
|
||||
func (_q *BatchImageItemQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
_spec := sqlgraph.NewQuerySpec(batchimageitem.Table, batchimageitem.Columns, sqlgraph.NewFieldSpec(batchimageitem.FieldID, field.TypeInt64))
|
||||
_spec.From = _q.sql
|
||||
if unique := _q.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
} else if _q.path != nil {
|
||||
_spec.Unique = true
|
||||
}
|
||||
if fields := _q.ctx.Fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, batchimageitem.FieldID)
|
||||
for i := range fields {
|
||||
if fields[i] != batchimageitem.FieldID {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
if ps := _q.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := _q.ctx.Limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := _q.ctx.Offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := _q.order; len(ps) > 0 {
|
||||
_spec.Order = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
return _spec
|
||||
}
|
||||
|
||||
func (_q *BatchImageItemQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(_q.driver.Dialect())
|
||||
t1 := builder.Table(batchimageitem.Table)
|
||||
columns := _q.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = batchimageitem.Columns
|
||||
}
|
||||
selector := builder.Select(t1.Columns(columns...)...).From(t1)
|
||||
if _q.sql != nil {
|
||||
selector = _q.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if _q.ctx.Unique != nil && *_q.ctx.Unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, m := range _q.modifiers {
|
||||
m(selector)
|
||||
}
|
||||
for _, p := range _q.predicates {
|
||||
p(selector)
|
||||
}
|
||||
for _, p := range _q.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := _q.ctx.Offset; offset != nil {
|
||||
// limit is mandatory for offset clause. We start
|
||||
// with default value, and override it below if needed.
|
||||
selector.Offset(*offset).Limit(math.MaxInt32)
|
||||
}
|
||||
if limit := _q.ctx.Limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
}
|
||||
|
||||
// ForUpdate locks the selected rows against concurrent updates, and prevent them from being
|
||||
// updated, deleted or "selected ... for update" by other sessions, until the transaction is
|
||||
// either committed or rolled-back.
|
||||
func (_q *BatchImageItemQuery) ForUpdate(opts ...sql.LockOption) *BatchImageItemQuery {
|
||||
if _q.driver.Dialect() == dialect.Postgres {
|
||||
_q.Unique(false)
|
||||
}
|
||||
_q.modifiers = append(_q.modifiers, func(s *sql.Selector) {
|
||||
s.ForUpdate(opts...)
|
||||
})
|
||||
return _q
|
||||
}
|
||||
|
||||
// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock
|
||||
// on any rows that are read. Other sessions can read the rows, but cannot modify them
|
||||
// until your transaction commits.
|
||||
func (_q *BatchImageItemQuery) ForShare(opts ...sql.LockOption) *BatchImageItemQuery {
|
||||
if _q.driver.Dialect() == dialect.Postgres {
|
||||
_q.Unique(false)
|
||||
}
|
||||
_q.modifiers = append(_q.modifiers, func(s *sql.Selector) {
|
||||
s.ForShare(opts...)
|
||||
})
|
||||
return _q
|
||||
}
|
||||
|
||||
// BatchImageItemGroupBy is the group-by builder for BatchImageItem entities.
|
||||
type BatchImageItemGroupBy struct {
|
||||
selector
|
||||
build *BatchImageItemQuery
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the group-by query.
|
||||
func (_g *BatchImageItemGroupBy) Aggregate(fns ...AggregateFunc) *BatchImageItemGroupBy {
|
||||
_g.fns = append(_g.fns, fns...)
|
||||
return _g
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (_g *BatchImageItemGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy)
|
||||
if err := _g.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return scanWithInterceptors[*BatchImageItemQuery, *BatchImageItemGroupBy](ctx, _g.build, _g, _g.build.inters, v)
|
||||
}
|
||||
|
||||
func (_g *BatchImageItemGroupBy) sqlScan(ctx context.Context, root *BatchImageItemQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx).Select()
|
||||
aggregation := make([]string, 0, len(_g.fns))
|
||||
for _, fn := range _g.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
if len(selector.SelectedColumns()) == 0 {
|
||||
columns := make([]string, 0, len(*_g.flds)+len(_g.fns))
|
||||
for _, f := range *_g.flds {
|
||||
columns = append(columns, selector.C(f))
|
||||
}
|
||||
columns = append(columns, aggregation...)
|
||||
selector.Select(columns...)
|
||||
}
|
||||
selector.GroupBy(selector.Columns(*_g.flds...)...)
|
||||
if err := selector.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := _g.build.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
// BatchImageItemSelect is the builder for selecting fields of BatchImageItem entities.
|
||||
type BatchImageItemSelect struct {
|
||||
*BatchImageItemQuery
|
||||
selector
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the selector query.
|
||||
func (_s *BatchImageItemSelect) Aggregate(fns ...AggregateFunc) *BatchImageItemSelect {
|
||||
_s.fns = append(_s.fns, fns...)
|
||||
return _s
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (_s *BatchImageItemSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect)
|
||||
if err := _s.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return scanWithInterceptors[*BatchImageItemQuery, *BatchImageItemSelect](ctx, _s.BatchImageItemQuery, _s, _s.inters, v)
|
||||
}
|
||||
|
||||
func (_s *BatchImageItemSelect) sqlScan(ctx context.Context, root *BatchImageItemQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx)
|
||||
aggregation := make([]string, 0, len(_s.fns))
|
||||
for _, fn := range _s.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
switch n := len(*_s.selector.flds); {
|
||||
case n == 0 && len(aggregation) > 0:
|
||||
selector.Select(aggregation...)
|
||||
case n != 0 && len(aggregation) > 0:
|
||||
selector.AppendSelect(aggregation...)
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := _s.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,609 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"github.com/Wei-Shaw/sub2api/ent/batchimagejob"
|
||||
)
|
||||
|
||||
// BatchImageJob is the model entity for the BatchImageJob schema.
|
||||
type BatchImageJob struct {
|
||||
config `json:"-"`
|
||||
// ID of the ent.
|
||||
ID int64 `json:"id,omitempty"`
|
||||
// BatchID holds the value of the "batch_id" field.
|
||||
BatchID string `json:"batch_id,omitempty"`
|
||||
// UserID holds the value of the "user_id" field.
|
||||
UserID int64 `json:"user_id,omitempty"`
|
||||
// APIKeyID holds the value of the "api_key_id" field.
|
||||
APIKeyID *int64 `json:"api_key_id,omitempty"`
|
||||
// AccountID holds the value of the "account_id" field.
|
||||
AccountID *int64 `json:"account_id,omitempty"`
|
||||
// Provider holds the value of the "provider" field.
|
||||
Provider string `json:"provider,omitempty"`
|
||||
// Model holds the value of the "model" field.
|
||||
Model string `json:"model,omitempty"`
|
||||
// TaskName holds the value of the "task_name" field.
|
||||
TaskName string `json:"task_name,omitempty"`
|
||||
// Status holds the value of the "status" field.
|
||||
Status string `json:"status,omitempty"`
|
||||
// ProviderJobName holds the value of the "provider_job_name" field.
|
||||
ProviderJobName *string `json:"provider_job_name,omitempty"`
|
||||
// ProviderInputRef holds the value of the "provider_input_ref" field.
|
||||
ProviderInputRef *string `json:"provider_input_ref,omitempty"`
|
||||
// ProviderOutputRef holds the value of the "provider_output_ref" field.
|
||||
ProviderOutputRef *string `json:"provider_output_ref,omitempty"`
|
||||
// GcsInputURI holds the value of the "gcs_input_uri" field.
|
||||
GcsInputURI *string `json:"gcs_input_uri,omitempty"`
|
||||
// GcsOutputURI holds the value of the "gcs_output_uri" field.
|
||||
GcsOutputURI *string `json:"gcs_output_uri,omitempty"`
|
||||
// ItemCount holds the value of the "item_count" field.
|
||||
ItemCount int `json:"item_count,omitempty"`
|
||||
// SuccessCount holds the value of the "success_count" field.
|
||||
SuccessCount int `json:"success_count,omitempty"`
|
||||
// FailCount holds the value of the "fail_count" field.
|
||||
FailCount int `json:"fail_count,omitempty"`
|
||||
// CancelledCount holds the value of the "cancelled_count" field.
|
||||
CancelledCount int `json:"cancelled_count,omitempty"`
|
||||
// EstimatedCost holds the value of the "estimated_cost" field.
|
||||
EstimatedCost float64 `json:"estimated_cost,omitempty"`
|
||||
// HoldAmount holds the value of the "hold_amount" field.
|
||||
HoldAmount *float64 `json:"hold_amount,omitempty"`
|
||||
// ActualCost holds the value of the "actual_cost" field.
|
||||
ActualCost *float64 `json:"actual_cost,omitempty"`
|
||||
// Currency holds the value of the "currency" field.
|
||||
Currency string `json:"currency,omitempty"`
|
||||
// HoldID holds the value of the "hold_id" field.
|
||||
HoldID *string `json:"hold_id,omitempty"`
|
||||
// IdempotencyKey holds the value of the "idempotency_key" field.
|
||||
IdempotencyKey *string `json:"idempotency_key,omitempty"`
|
||||
// RequestHash holds the value of the "request_hash" field.
|
||||
RequestHash *string `json:"request_hash,omitempty"`
|
||||
// ManifestHash holds the value of the "manifest_hash" field.
|
||||
ManifestHash *string `json:"manifest_hash,omitempty"`
|
||||
// RetryCount holds the value of the "retry_count" field.
|
||||
RetryCount int `json:"retry_count,omitempty"`
|
||||
// Version holds the value of the "version" field.
|
||||
Version int `json:"version,omitempty"`
|
||||
// OutputExpiresAt holds the value of the "output_expires_at" field.
|
||||
OutputExpiresAt *time.Time `json:"output_expires_at,omitempty"`
|
||||
// InputDeletedAt holds the value of the "input_deleted_at" field.
|
||||
InputDeletedAt *time.Time `json:"input_deleted_at,omitempty"`
|
||||
// OutputDeletedAt holds the value of the "output_deleted_at" field.
|
||||
OutputDeletedAt *time.Time `json:"output_deleted_at,omitempty"`
|
||||
// DownloadedAt holds the value of the "downloaded_at" field.
|
||||
DownloadedAt *time.Time `json:"downloaded_at,omitempty"`
|
||||
// UserDeletedAt holds the value of the "user_deleted_at" field.
|
||||
UserDeletedAt *time.Time `json:"user_deleted_at,omitempty"`
|
||||
// LastErrorCode holds the value of the "last_error_code" field.
|
||||
LastErrorCode *string `json:"last_error_code,omitempty"`
|
||||
// LastErrorMessage holds the value of the "last_error_message" field.
|
||||
LastErrorMessage *string `json:"last_error_message,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"`
|
||||
// SubmittedAt holds the value of the "submitted_at" field.
|
||||
SubmittedAt *time.Time `json:"submitted_at,omitempty"`
|
||||
// StartedAt holds the value of the "started_at" field.
|
||||
StartedAt *time.Time `json:"started_at,omitempty"`
|
||||
// FinishedAt holds the value of the "finished_at" field.
|
||||
FinishedAt *time.Time `json:"finished_at,omitempty"`
|
||||
// SettledAt holds the value of the "settled_at" field.
|
||||
SettledAt *time.Time `json:"settled_at,omitempty"`
|
||||
selectValues sql.SelectValues
|
||||
}
|
||||
|
||||
// scanValues returns the types for scanning values from sql.Rows.
|
||||
func (*BatchImageJob) scanValues(columns []string) ([]any, error) {
|
||||
values := make([]any, len(columns))
|
||||
for i := range columns {
|
||||
switch columns[i] {
|
||||
case batchimagejob.FieldEstimatedCost, batchimagejob.FieldHoldAmount, batchimagejob.FieldActualCost:
|
||||
values[i] = new(sql.NullFloat64)
|
||||
case batchimagejob.FieldID, batchimagejob.FieldUserID, batchimagejob.FieldAPIKeyID, batchimagejob.FieldAccountID, batchimagejob.FieldItemCount, batchimagejob.FieldSuccessCount, batchimagejob.FieldFailCount, batchimagejob.FieldCancelledCount, batchimagejob.FieldRetryCount, batchimagejob.FieldVersion:
|
||||
values[i] = new(sql.NullInt64)
|
||||
case batchimagejob.FieldBatchID, batchimagejob.FieldProvider, batchimagejob.FieldModel, batchimagejob.FieldTaskName, batchimagejob.FieldStatus, batchimagejob.FieldProviderJobName, batchimagejob.FieldProviderInputRef, batchimagejob.FieldProviderOutputRef, batchimagejob.FieldGcsInputURI, batchimagejob.FieldGcsOutputURI, batchimagejob.FieldCurrency, batchimagejob.FieldHoldID, batchimagejob.FieldIdempotencyKey, batchimagejob.FieldRequestHash, batchimagejob.FieldManifestHash, batchimagejob.FieldLastErrorCode, batchimagejob.FieldLastErrorMessage:
|
||||
values[i] = new(sql.NullString)
|
||||
case batchimagejob.FieldOutputExpiresAt, batchimagejob.FieldInputDeletedAt, batchimagejob.FieldOutputDeletedAt, batchimagejob.FieldDownloadedAt, batchimagejob.FieldUserDeletedAt, batchimagejob.FieldCreatedAt, batchimagejob.FieldUpdatedAt, batchimagejob.FieldSubmittedAt, batchimagejob.FieldStartedAt, batchimagejob.FieldFinishedAt, batchimagejob.FieldSettledAt:
|
||||
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 BatchImageJob fields.
|
||||
func (_m *BatchImageJob) 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 batchimagejob.FieldID:
|
||||
value, ok := values[i].(*sql.NullInt64)
|
||||
if !ok {
|
||||
return fmt.Errorf("unexpected type %T for field id", value)
|
||||
}
|
||||
_m.ID = int64(value.Int64)
|
||||
case batchimagejob.FieldBatchID:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field batch_id", values[i])
|
||||
} else if value.Valid {
|
||||
_m.BatchID = value.String
|
||||
}
|
||||
case batchimagejob.FieldUserID:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field user_id", values[i])
|
||||
} else if value.Valid {
|
||||
_m.UserID = value.Int64
|
||||
}
|
||||
case batchimagejob.FieldAPIKeyID:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field api_key_id", values[i])
|
||||
} else if value.Valid {
|
||||
_m.APIKeyID = new(int64)
|
||||
*_m.APIKeyID = value.Int64
|
||||
}
|
||||
case batchimagejob.FieldAccountID:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field account_id", values[i])
|
||||
} else if value.Valid {
|
||||
_m.AccountID = new(int64)
|
||||
*_m.AccountID = value.Int64
|
||||
}
|
||||
case batchimagejob.FieldProvider:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field provider", values[i])
|
||||
} else if value.Valid {
|
||||
_m.Provider = value.String
|
||||
}
|
||||
case batchimagejob.FieldModel:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field model", values[i])
|
||||
} else if value.Valid {
|
||||
_m.Model = value.String
|
||||
}
|
||||
case batchimagejob.FieldTaskName:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field task_name", values[i])
|
||||
} else if value.Valid {
|
||||
_m.TaskName = value.String
|
||||
}
|
||||
case batchimagejob.FieldStatus:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field status", values[i])
|
||||
} else if value.Valid {
|
||||
_m.Status = value.String
|
||||
}
|
||||
case batchimagejob.FieldProviderJobName:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field provider_job_name", values[i])
|
||||
} else if value.Valid {
|
||||
_m.ProviderJobName = new(string)
|
||||
*_m.ProviderJobName = value.String
|
||||
}
|
||||
case batchimagejob.FieldProviderInputRef:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field provider_input_ref", values[i])
|
||||
} else if value.Valid {
|
||||
_m.ProviderInputRef = new(string)
|
||||
*_m.ProviderInputRef = value.String
|
||||
}
|
||||
case batchimagejob.FieldProviderOutputRef:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field provider_output_ref", values[i])
|
||||
} else if value.Valid {
|
||||
_m.ProviderOutputRef = new(string)
|
||||
*_m.ProviderOutputRef = value.String
|
||||
}
|
||||
case batchimagejob.FieldGcsInputURI:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field gcs_input_uri", values[i])
|
||||
} else if value.Valid {
|
||||
_m.GcsInputURI = new(string)
|
||||
*_m.GcsInputURI = value.String
|
||||
}
|
||||
case batchimagejob.FieldGcsOutputURI:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field gcs_output_uri", values[i])
|
||||
} else if value.Valid {
|
||||
_m.GcsOutputURI = new(string)
|
||||
*_m.GcsOutputURI = value.String
|
||||
}
|
||||
case batchimagejob.FieldItemCount:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field item_count", values[i])
|
||||
} else if value.Valid {
|
||||
_m.ItemCount = int(value.Int64)
|
||||
}
|
||||
case batchimagejob.FieldSuccessCount:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field success_count", values[i])
|
||||
} else if value.Valid {
|
||||
_m.SuccessCount = int(value.Int64)
|
||||
}
|
||||
case batchimagejob.FieldFailCount:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field fail_count", values[i])
|
||||
} else if value.Valid {
|
||||
_m.FailCount = int(value.Int64)
|
||||
}
|
||||
case batchimagejob.FieldCancelledCount:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field cancelled_count", values[i])
|
||||
} else if value.Valid {
|
||||
_m.CancelledCount = int(value.Int64)
|
||||
}
|
||||
case batchimagejob.FieldEstimatedCost:
|
||||
if value, ok := values[i].(*sql.NullFloat64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field estimated_cost", values[i])
|
||||
} else if value.Valid {
|
||||
_m.EstimatedCost = value.Float64
|
||||
}
|
||||
case batchimagejob.FieldHoldAmount:
|
||||
if value, ok := values[i].(*sql.NullFloat64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field hold_amount", values[i])
|
||||
} else if value.Valid {
|
||||
_m.HoldAmount = new(float64)
|
||||
*_m.HoldAmount = value.Float64
|
||||
}
|
||||
case batchimagejob.FieldActualCost:
|
||||
if value, ok := values[i].(*sql.NullFloat64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field actual_cost", values[i])
|
||||
} else if value.Valid {
|
||||
_m.ActualCost = new(float64)
|
||||
*_m.ActualCost = value.Float64
|
||||
}
|
||||
case batchimagejob.FieldCurrency:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field currency", values[i])
|
||||
} else if value.Valid {
|
||||
_m.Currency = value.String
|
||||
}
|
||||
case batchimagejob.FieldHoldID:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field hold_id", values[i])
|
||||
} else if value.Valid {
|
||||
_m.HoldID = new(string)
|
||||
*_m.HoldID = value.String
|
||||
}
|
||||
case batchimagejob.FieldIdempotencyKey:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field idempotency_key", values[i])
|
||||
} else if value.Valid {
|
||||
_m.IdempotencyKey = new(string)
|
||||
*_m.IdempotencyKey = value.String
|
||||
}
|
||||
case batchimagejob.FieldRequestHash:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field request_hash", values[i])
|
||||
} else if value.Valid {
|
||||
_m.RequestHash = new(string)
|
||||
*_m.RequestHash = value.String
|
||||
}
|
||||
case batchimagejob.FieldManifestHash:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field manifest_hash", values[i])
|
||||
} else if value.Valid {
|
||||
_m.ManifestHash = new(string)
|
||||
*_m.ManifestHash = value.String
|
||||
}
|
||||
case batchimagejob.FieldRetryCount:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field retry_count", values[i])
|
||||
} else if value.Valid {
|
||||
_m.RetryCount = int(value.Int64)
|
||||
}
|
||||
case batchimagejob.FieldVersion:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field version", values[i])
|
||||
} else if value.Valid {
|
||||
_m.Version = int(value.Int64)
|
||||
}
|
||||
case batchimagejob.FieldOutputExpiresAt:
|
||||
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field output_expires_at", values[i])
|
||||
} else if value.Valid {
|
||||
_m.OutputExpiresAt = new(time.Time)
|
||||
*_m.OutputExpiresAt = value.Time
|
||||
}
|
||||
case batchimagejob.FieldInputDeletedAt:
|
||||
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field input_deleted_at", values[i])
|
||||
} else if value.Valid {
|
||||
_m.InputDeletedAt = new(time.Time)
|
||||
*_m.InputDeletedAt = value.Time
|
||||
}
|
||||
case batchimagejob.FieldOutputDeletedAt:
|
||||
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field output_deleted_at", values[i])
|
||||
} else if value.Valid {
|
||||
_m.OutputDeletedAt = new(time.Time)
|
||||
*_m.OutputDeletedAt = value.Time
|
||||
}
|
||||
case batchimagejob.FieldDownloadedAt:
|
||||
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field downloaded_at", values[i])
|
||||
} else if value.Valid {
|
||||
_m.DownloadedAt = new(time.Time)
|
||||
*_m.DownloadedAt = value.Time
|
||||
}
|
||||
case batchimagejob.FieldUserDeletedAt:
|
||||
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field user_deleted_at", values[i])
|
||||
} else if value.Valid {
|
||||
_m.UserDeletedAt = new(time.Time)
|
||||
*_m.UserDeletedAt = value.Time
|
||||
}
|
||||
case batchimagejob.FieldLastErrorCode:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field last_error_code", values[i])
|
||||
} else if value.Valid {
|
||||
_m.LastErrorCode = new(string)
|
||||
*_m.LastErrorCode = value.String
|
||||
}
|
||||
case batchimagejob.FieldLastErrorMessage:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field last_error_message", values[i])
|
||||
} else if value.Valid {
|
||||
_m.LastErrorMessage = new(string)
|
||||
*_m.LastErrorMessage = value.String
|
||||
}
|
||||
case batchimagejob.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 {
|
||||
_m.CreatedAt = value.Time
|
||||
}
|
||||
case batchimagejob.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 {
|
||||
_m.UpdatedAt = value.Time
|
||||
}
|
||||
case batchimagejob.FieldSubmittedAt:
|
||||
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field submitted_at", values[i])
|
||||
} else if value.Valid {
|
||||
_m.SubmittedAt = new(time.Time)
|
||||
*_m.SubmittedAt = value.Time
|
||||
}
|
||||
case batchimagejob.FieldStartedAt:
|
||||
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field started_at", values[i])
|
||||
} else if value.Valid {
|
||||
_m.StartedAt = new(time.Time)
|
||||
*_m.StartedAt = value.Time
|
||||
}
|
||||
case batchimagejob.FieldFinishedAt:
|
||||
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field finished_at", values[i])
|
||||
} else if value.Valid {
|
||||
_m.FinishedAt = new(time.Time)
|
||||
*_m.FinishedAt = value.Time
|
||||
}
|
||||
case batchimagejob.FieldSettledAt:
|
||||
if value, ok := values[i].(*sql.NullTime); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field settled_at", values[i])
|
||||
} else if value.Valid {
|
||||
_m.SettledAt = new(time.Time)
|
||||
*_m.SettledAt = value.Time
|
||||
}
|
||||
default:
|
||||
_m.selectValues.Set(columns[i], values[i])
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Value returns the ent.Value that was dynamically selected and assigned to the BatchImageJob.
|
||||
// This includes values selected through modifiers, order, etc.
|
||||
func (_m *BatchImageJob) Value(name string) (ent.Value, error) {
|
||||
return _m.selectValues.Get(name)
|
||||
}
|
||||
|
||||
// Update returns a builder for updating this BatchImageJob.
|
||||
// Note that you need to call BatchImageJob.Unwrap() before calling this method if this BatchImageJob
|
||||
// was returned from a transaction, and the transaction was committed or rolled back.
|
||||
func (_m *BatchImageJob) Update() *BatchImageJobUpdateOne {
|
||||
return NewBatchImageJobClient(_m.config).UpdateOne(_m)
|
||||
}
|
||||
|
||||
// Unwrap unwraps the BatchImageJob entity that was returned from a transaction after it was closed,
|
||||
// so that all future queries will be executed through the driver which created the transaction.
|
||||
func (_m *BatchImageJob) Unwrap() *BatchImageJob {
|
||||
_tx, ok := _m.config.driver.(*txDriver)
|
||||
if !ok {
|
||||
panic("ent: BatchImageJob is not a transactional entity")
|
||||
}
|
||||
_m.config.driver = _tx.drv
|
||||
return _m
|
||||
}
|
||||
|
||||
// String implements the fmt.Stringer.
|
||||
func (_m *BatchImageJob) String() string {
|
||||
var builder strings.Builder
|
||||
builder.WriteString("BatchImageJob(")
|
||||
builder.WriteString(fmt.Sprintf("id=%v, ", _m.ID))
|
||||
builder.WriteString("batch_id=")
|
||||
builder.WriteString(_m.BatchID)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("user_id=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.UserID))
|
||||
builder.WriteString(", ")
|
||||
if v := _m.APIKeyID; v != nil {
|
||||
builder.WriteString("api_key_id=")
|
||||
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.AccountID; v != nil {
|
||||
builder.WriteString("account_id=")
|
||||
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("provider=")
|
||||
builder.WriteString(_m.Provider)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("model=")
|
||||
builder.WriteString(_m.Model)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("task_name=")
|
||||
builder.WriteString(_m.TaskName)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("status=")
|
||||
builder.WriteString(_m.Status)
|
||||
builder.WriteString(", ")
|
||||
if v := _m.ProviderJobName; v != nil {
|
||||
builder.WriteString("provider_job_name=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.ProviderInputRef; v != nil {
|
||||
builder.WriteString("provider_input_ref=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.ProviderOutputRef; v != nil {
|
||||
builder.WriteString("provider_output_ref=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.GcsInputURI; v != nil {
|
||||
builder.WriteString("gcs_input_uri=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.GcsOutputURI; v != nil {
|
||||
builder.WriteString("gcs_output_uri=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("item_count=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.ItemCount))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("success_count=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.SuccessCount))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("fail_count=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.FailCount))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("cancelled_count=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.CancelledCount))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("estimated_cost=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.EstimatedCost))
|
||||
builder.WriteString(", ")
|
||||
if v := _m.HoldAmount; v != nil {
|
||||
builder.WriteString("hold_amount=")
|
||||
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.ActualCost; v != nil {
|
||||
builder.WriteString("actual_cost=")
|
||||
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("currency=")
|
||||
builder.WriteString(_m.Currency)
|
||||
builder.WriteString(", ")
|
||||
if v := _m.HoldID; v != nil {
|
||||
builder.WriteString("hold_id=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.IdempotencyKey; v != nil {
|
||||
builder.WriteString("idempotency_key=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.RequestHash; v != nil {
|
||||
builder.WriteString("request_hash=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.ManifestHash; v != nil {
|
||||
builder.WriteString("manifest_hash=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("retry_count=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.RetryCount))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("version=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.Version))
|
||||
builder.WriteString(", ")
|
||||
if v := _m.OutputExpiresAt; v != nil {
|
||||
builder.WriteString("output_expires_at=")
|
||||
builder.WriteString(v.Format(time.ANSIC))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.InputDeletedAt; v != nil {
|
||||
builder.WriteString("input_deleted_at=")
|
||||
builder.WriteString(v.Format(time.ANSIC))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.OutputDeletedAt; v != nil {
|
||||
builder.WriteString("output_deleted_at=")
|
||||
builder.WriteString(v.Format(time.ANSIC))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.DownloadedAt; v != nil {
|
||||
builder.WriteString("downloaded_at=")
|
||||
builder.WriteString(v.Format(time.ANSIC))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.UserDeletedAt; v != nil {
|
||||
builder.WriteString("user_deleted_at=")
|
||||
builder.WriteString(v.Format(time.ANSIC))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.LastErrorCode; v != nil {
|
||||
builder.WriteString("last_error_code=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.LastErrorMessage; v != nil {
|
||||
builder.WriteString("last_error_message=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("created_at=")
|
||||
builder.WriteString(_m.CreatedAt.Format(time.ANSIC))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("updated_at=")
|
||||
builder.WriteString(_m.UpdatedAt.Format(time.ANSIC))
|
||||
builder.WriteString(", ")
|
||||
if v := _m.SubmittedAt; v != nil {
|
||||
builder.WriteString("submitted_at=")
|
||||
builder.WriteString(v.Format(time.ANSIC))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.StartedAt; v != nil {
|
||||
builder.WriteString("started_at=")
|
||||
builder.WriteString(v.Format(time.ANSIC))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.FinishedAt; v != nil {
|
||||
builder.WriteString("finished_at=")
|
||||
builder.WriteString(v.Format(time.ANSIC))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.SettledAt; v != nil {
|
||||
builder.WriteString("settled_at=")
|
||||
builder.WriteString(v.Format(time.ANSIC))
|
||||
}
|
||||
builder.WriteByte(')')
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
// BatchImageJobs is a parsable slice of BatchImageJob.
|
||||
type BatchImageJobs []*BatchImageJob
|
||||
@@ -0,0 +1,420 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package batchimagejob
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent/dialect/sql"
|
||||
)
|
||||
|
||||
const (
|
||||
// Label holds the string label denoting the batchimagejob type in the database.
|
||||
Label = "batch_image_job"
|
||||
// FieldID holds the string denoting the id field in the database.
|
||||
FieldID = "id"
|
||||
// FieldBatchID holds the string denoting the batch_id field in the database.
|
||||
FieldBatchID = "batch_id"
|
||||
// FieldUserID holds the string denoting the user_id field in the database.
|
||||
FieldUserID = "user_id"
|
||||
// FieldAPIKeyID holds the string denoting the api_key_id field in the database.
|
||||
FieldAPIKeyID = "api_key_id"
|
||||
// FieldAccountID holds the string denoting the account_id field in the database.
|
||||
FieldAccountID = "account_id"
|
||||
// FieldProvider holds the string denoting the provider field in the database.
|
||||
FieldProvider = "provider"
|
||||
// FieldModel holds the string denoting the model field in the database.
|
||||
FieldModel = "model"
|
||||
// FieldTaskName holds the string denoting the task_name field in the database.
|
||||
FieldTaskName = "task_name"
|
||||
// FieldStatus holds the string denoting the status field in the database.
|
||||
FieldStatus = "status"
|
||||
// FieldProviderJobName holds the string denoting the provider_job_name field in the database.
|
||||
FieldProviderJobName = "provider_job_name"
|
||||
// FieldProviderInputRef holds the string denoting the provider_input_ref field in the database.
|
||||
FieldProviderInputRef = "provider_input_ref"
|
||||
// FieldProviderOutputRef holds the string denoting the provider_output_ref field in the database.
|
||||
FieldProviderOutputRef = "provider_output_ref"
|
||||
// FieldGcsInputURI holds the string denoting the gcs_input_uri field in the database.
|
||||
FieldGcsInputURI = "gcs_input_uri"
|
||||
// FieldGcsOutputURI holds the string denoting the gcs_output_uri field in the database.
|
||||
FieldGcsOutputURI = "gcs_output_uri"
|
||||
// FieldItemCount holds the string denoting the item_count field in the database.
|
||||
FieldItemCount = "item_count"
|
||||
// FieldSuccessCount holds the string denoting the success_count field in the database.
|
||||
FieldSuccessCount = "success_count"
|
||||
// FieldFailCount holds the string denoting the fail_count field in the database.
|
||||
FieldFailCount = "fail_count"
|
||||
// FieldCancelledCount holds the string denoting the cancelled_count field in the database.
|
||||
FieldCancelledCount = "cancelled_count"
|
||||
// FieldEstimatedCost holds the string denoting the estimated_cost field in the database.
|
||||
FieldEstimatedCost = "estimated_cost"
|
||||
// FieldHoldAmount holds the string denoting the hold_amount field in the database.
|
||||
FieldHoldAmount = "hold_amount"
|
||||
// FieldActualCost holds the string denoting the actual_cost field in the database.
|
||||
FieldActualCost = "actual_cost"
|
||||
// FieldCurrency holds the string denoting the currency field in the database.
|
||||
FieldCurrency = "currency"
|
||||
// FieldHoldID holds the string denoting the hold_id field in the database.
|
||||
FieldHoldID = "hold_id"
|
||||
// FieldIdempotencyKey holds the string denoting the idempotency_key field in the database.
|
||||
FieldIdempotencyKey = "idempotency_key"
|
||||
// FieldRequestHash holds the string denoting the request_hash field in the database.
|
||||
FieldRequestHash = "request_hash"
|
||||
// FieldManifestHash holds the string denoting the manifest_hash field in the database.
|
||||
FieldManifestHash = "manifest_hash"
|
||||
// FieldRetryCount holds the string denoting the retry_count field in the database.
|
||||
FieldRetryCount = "retry_count"
|
||||
// FieldVersion holds the string denoting the version field in the database.
|
||||
FieldVersion = "version"
|
||||
// FieldOutputExpiresAt holds the string denoting the output_expires_at field in the database.
|
||||
FieldOutputExpiresAt = "output_expires_at"
|
||||
// FieldInputDeletedAt holds the string denoting the input_deleted_at field in the database.
|
||||
FieldInputDeletedAt = "input_deleted_at"
|
||||
// FieldOutputDeletedAt holds the string denoting the output_deleted_at field in the database.
|
||||
FieldOutputDeletedAt = "output_deleted_at"
|
||||
// FieldDownloadedAt holds the string denoting the downloaded_at field in the database.
|
||||
FieldDownloadedAt = "downloaded_at"
|
||||
// FieldUserDeletedAt holds the string denoting the user_deleted_at field in the database.
|
||||
FieldUserDeletedAt = "user_deleted_at"
|
||||
// FieldLastErrorCode holds the string denoting the last_error_code field in the database.
|
||||
FieldLastErrorCode = "last_error_code"
|
||||
// FieldLastErrorMessage holds the string denoting the last_error_message field in the database.
|
||||
FieldLastErrorMessage = "last_error_message"
|
||||
// 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"
|
||||
// FieldSubmittedAt holds the string denoting the submitted_at field in the database.
|
||||
FieldSubmittedAt = "submitted_at"
|
||||
// FieldStartedAt holds the string denoting the started_at field in the database.
|
||||
FieldStartedAt = "started_at"
|
||||
// FieldFinishedAt holds the string denoting the finished_at field in the database.
|
||||
FieldFinishedAt = "finished_at"
|
||||
// FieldSettledAt holds the string denoting the settled_at field in the database.
|
||||
FieldSettledAt = "settled_at"
|
||||
// Table holds the table name of the batchimagejob in the database.
|
||||
Table = "batch_image_jobs"
|
||||
)
|
||||
|
||||
// Columns holds all SQL columns for batchimagejob fields.
|
||||
var Columns = []string{
|
||||
FieldID,
|
||||
FieldBatchID,
|
||||
FieldUserID,
|
||||
FieldAPIKeyID,
|
||||
FieldAccountID,
|
||||
FieldProvider,
|
||||
FieldModel,
|
||||
FieldTaskName,
|
||||
FieldStatus,
|
||||
FieldProviderJobName,
|
||||
FieldProviderInputRef,
|
||||
FieldProviderOutputRef,
|
||||
FieldGcsInputURI,
|
||||
FieldGcsOutputURI,
|
||||
FieldItemCount,
|
||||
FieldSuccessCount,
|
||||
FieldFailCount,
|
||||
FieldCancelledCount,
|
||||
FieldEstimatedCost,
|
||||
FieldHoldAmount,
|
||||
FieldActualCost,
|
||||
FieldCurrency,
|
||||
FieldHoldID,
|
||||
FieldIdempotencyKey,
|
||||
FieldRequestHash,
|
||||
FieldManifestHash,
|
||||
FieldRetryCount,
|
||||
FieldVersion,
|
||||
FieldOutputExpiresAt,
|
||||
FieldInputDeletedAt,
|
||||
FieldOutputDeletedAt,
|
||||
FieldDownloadedAt,
|
||||
FieldUserDeletedAt,
|
||||
FieldLastErrorCode,
|
||||
FieldLastErrorMessage,
|
||||
FieldCreatedAt,
|
||||
FieldUpdatedAt,
|
||||
FieldSubmittedAt,
|
||||
FieldStartedAt,
|
||||
FieldFinishedAt,
|
||||
FieldSettledAt,
|
||||
}
|
||||
|
||||
// ValidColumn reports if the column name is valid (part of the table columns).
|
||||
func ValidColumn(column string) bool {
|
||||
for i := range Columns {
|
||||
if column == Columns[i] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var (
|
||||
// BatchIDValidator is a validator for the "batch_id" field. It is called by the builders before save.
|
||||
BatchIDValidator func(string) error
|
||||
// ProviderValidator is a validator for the "provider" field. It is called by the builders before save.
|
||||
ProviderValidator func(string) error
|
||||
// ModelValidator is a validator for the "model" field. It is called by the builders before save.
|
||||
ModelValidator func(string) error
|
||||
// DefaultTaskName holds the default value on creation for the "task_name" field.
|
||||
DefaultTaskName string
|
||||
// TaskNameValidator is a validator for the "task_name" field. It is called by the builders before save.
|
||||
TaskNameValidator func(string) error
|
||||
// DefaultStatus holds the default value on creation for the "status" field.
|
||||
DefaultStatus string
|
||||
// StatusValidator is a validator for the "status" field. It is called by the builders before save.
|
||||
StatusValidator func(string) error
|
||||
// ProviderJobNameValidator is a validator for the "provider_job_name" field. It is called by the builders before save.
|
||||
ProviderJobNameValidator func(string) error
|
||||
// ProviderInputRefValidator is a validator for the "provider_input_ref" field. It is called by the builders before save.
|
||||
ProviderInputRefValidator func(string) error
|
||||
// ProviderOutputRefValidator is a validator for the "provider_output_ref" field. It is called by the builders before save.
|
||||
ProviderOutputRefValidator func(string) error
|
||||
// GcsInputURIValidator is a validator for the "gcs_input_uri" field. It is called by the builders before save.
|
||||
GcsInputURIValidator func(string) error
|
||||
// GcsOutputURIValidator is a validator for the "gcs_output_uri" field. It is called by the builders before save.
|
||||
GcsOutputURIValidator func(string) error
|
||||
// DefaultSuccessCount holds the default value on creation for the "success_count" field.
|
||||
DefaultSuccessCount int
|
||||
// DefaultFailCount holds the default value on creation for the "fail_count" field.
|
||||
DefaultFailCount int
|
||||
// DefaultCancelledCount holds the default value on creation for the "cancelled_count" field.
|
||||
DefaultCancelledCount int
|
||||
// DefaultEstimatedCost holds the default value on creation for the "estimated_cost" field.
|
||||
DefaultEstimatedCost float64
|
||||
// DefaultCurrency holds the default value on creation for the "currency" field.
|
||||
DefaultCurrency string
|
||||
// CurrencyValidator is a validator for the "currency" field. It is called by the builders before save.
|
||||
CurrencyValidator func(string) error
|
||||
// HoldIDValidator is a validator for the "hold_id" field. It is called by the builders before save.
|
||||
HoldIDValidator func(string) error
|
||||
// IdempotencyKeyValidator is a validator for the "idempotency_key" field. It is called by the builders before save.
|
||||
IdempotencyKeyValidator func(string) error
|
||||
// RequestHashValidator is a validator for the "request_hash" field. It is called by the builders before save.
|
||||
RequestHashValidator func(string) error
|
||||
// ManifestHashValidator is a validator for the "manifest_hash" field. It is called by the builders before save.
|
||||
ManifestHashValidator func(string) error
|
||||
// DefaultRetryCount holds the default value on creation for the "retry_count" field.
|
||||
DefaultRetryCount int
|
||||
// DefaultVersion holds the default value on creation for the "version" field.
|
||||
DefaultVersion int
|
||||
// LastErrorCodeValidator is a validator for the "last_error_code" field. It is called by the builders before save.
|
||||
LastErrorCodeValidator func(string) error
|
||||
// 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 BatchImageJob 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()
|
||||
}
|
||||
|
||||
// ByBatchID orders the results by the batch_id field.
|
||||
func ByBatchID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldBatchID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByUserID orders the results by the user_id field.
|
||||
func ByUserID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldUserID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByAPIKeyID orders the results by the api_key_id field.
|
||||
func ByAPIKeyID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldAPIKeyID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByAccountID orders the results by the account_id field.
|
||||
func ByAccountID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldAccountID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByProvider orders the results by the provider field.
|
||||
func ByProvider(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldProvider, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByModel orders the results by the model field.
|
||||
func ByModel(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldModel, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByTaskName orders the results by the task_name field.
|
||||
func ByTaskName(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldTaskName, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByStatus orders the results by the status field.
|
||||
func ByStatus(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldStatus, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByProviderJobName orders the results by the provider_job_name field.
|
||||
func ByProviderJobName(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldProviderJobName, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByProviderInputRef orders the results by the provider_input_ref field.
|
||||
func ByProviderInputRef(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldProviderInputRef, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByProviderOutputRef orders the results by the provider_output_ref field.
|
||||
func ByProviderOutputRef(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldProviderOutputRef, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByGcsInputURI orders the results by the gcs_input_uri field.
|
||||
func ByGcsInputURI(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldGcsInputURI, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByGcsOutputURI orders the results by the gcs_output_uri field.
|
||||
func ByGcsOutputURI(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldGcsOutputURI, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByItemCount orders the results by the item_count field.
|
||||
func ByItemCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldItemCount, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// BySuccessCount orders the results by the success_count field.
|
||||
func BySuccessCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldSuccessCount, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByFailCount orders the results by the fail_count field.
|
||||
func ByFailCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldFailCount, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByCancelledCount orders the results by the cancelled_count field.
|
||||
func ByCancelledCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldCancelledCount, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByEstimatedCost orders the results by the estimated_cost field.
|
||||
func ByEstimatedCost(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldEstimatedCost, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByHoldAmount orders the results by the hold_amount field.
|
||||
func ByHoldAmount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldHoldAmount, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByActualCost orders the results by the actual_cost field.
|
||||
func ByActualCost(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldActualCost, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByCurrency orders the results by the currency field.
|
||||
func ByCurrency(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldCurrency, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByHoldID orders the results by the hold_id field.
|
||||
func ByHoldID(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldHoldID, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByIdempotencyKey orders the results by the idempotency_key field.
|
||||
func ByIdempotencyKey(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldIdempotencyKey, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByRequestHash orders the results by the request_hash field.
|
||||
func ByRequestHash(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldRequestHash, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByManifestHash orders the results by the manifest_hash field.
|
||||
func ByManifestHash(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldManifestHash, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByRetryCount orders the results by the retry_count field.
|
||||
func ByRetryCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldRetryCount, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByVersion orders the results by the version field.
|
||||
func ByVersion(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldVersion, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByOutputExpiresAt orders the results by the output_expires_at field.
|
||||
func ByOutputExpiresAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldOutputExpiresAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByInputDeletedAt orders the results by the input_deleted_at field.
|
||||
func ByInputDeletedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldInputDeletedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByOutputDeletedAt orders the results by the output_deleted_at field.
|
||||
func ByOutputDeletedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldOutputDeletedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByDownloadedAt orders the results by the downloaded_at field.
|
||||
func ByDownloadedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldDownloadedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByUserDeletedAt orders the results by the user_deleted_at field.
|
||||
func ByUserDeletedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldUserDeletedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByLastErrorCode orders the results by the last_error_code field.
|
||||
func ByLastErrorCode(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldLastErrorCode, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByLastErrorMessage orders the results by the last_error_message field.
|
||||
func ByLastErrorMessage(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldLastErrorMessage, 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()
|
||||
}
|
||||
|
||||
// BySubmittedAt orders the results by the submitted_at field.
|
||||
func BySubmittedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldSubmittedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByStartedAt orders the results by the started_at field.
|
||||
func ByStartedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldStartedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByFinishedAt orders the results by the finished_at field.
|
||||
func ByFinishedAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldFinishedAt, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// BySettledAt orders the results by the settled_at field.
|
||||
func BySettledAt(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldSettledAt, opts...).ToFunc()
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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/Wei-Shaw/sub2api/ent/batchimagejob"
|
||||
"github.com/Wei-Shaw/sub2api/ent/predicate"
|
||||
)
|
||||
|
||||
// BatchImageJobDelete is the builder for deleting a BatchImageJob entity.
|
||||
type BatchImageJobDelete struct {
|
||||
config
|
||||
hooks []Hook
|
||||
mutation *BatchImageJobMutation
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the BatchImageJobDelete builder.
|
||||
func (_d *BatchImageJobDelete) Where(ps ...predicate.BatchImageJob) *BatchImageJobDelete {
|
||||
_d.mutation.Where(ps...)
|
||||
return _d
|
||||
}
|
||||
|
||||
// Exec executes the deletion query and returns how many vertices were deleted.
|
||||
func (_d *BatchImageJobDelete) Exec(ctx context.Context) (int, error) {
|
||||
return withHooks(ctx, _d.sqlExec, _d.mutation, _d.hooks)
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (_d *BatchImageJobDelete) ExecX(ctx context.Context) int {
|
||||
n, err := _d.Exec(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
func (_d *BatchImageJobDelete) sqlExec(ctx context.Context) (int, error) {
|
||||
_spec := sqlgraph.NewDeleteSpec(batchimagejob.Table, sqlgraph.NewFieldSpec(batchimagejob.FieldID, field.TypeInt64))
|
||||
if ps := _d.mutation.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
affected, err := sqlgraph.DeleteNodes(ctx, _d.driver, _spec)
|
||||
if err != nil && sqlgraph.IsConstraintError(err) {
|
||||
err = &ConstraintError{msg: err.Error(), wrap: err}
|
||||
}
|
||||
_d.mutation.done = true
|
||||
return affected, err
|
||||
}
|
||||
|
||||
// BatchImageJobDeleteOne is the builder for deleting a single BatchImageJob entity.
|
||||
type BatchImageJobDeleteOne struct {
|
||||
_d *BatchImageJobDelete
|
||||
}
|
||||
|
||||
// Where appends a list predicates to the BatchImageJobDelete builder.
|
||||
func (_d *BatchImageJobDeleteOne) Where(ps ...predicate.BatchImageJob) *BatchImageJobDeleteOne {
|
||||
_d._d.mutation.Where(ps...)
|
||||
return _d
|
||||
}
|
||||
|
||||
// Exec executes the deletion query.
|
||||
func (_d *BatchImageJobDeleteOne) Exec(ctx context.Context) error {
|
||||
n, err := _d._d.Exec(ctx)
|
||||
switch {
|
||||
case err != nil:
|
||||
return err
|
||||
case n == 0:
|
||||
return &NotFoundError{batchimagejob.Label}
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ExecX is like Exec, but panics if an error occurs.
|
||||
func (_d *BatchImageJobDeleteOne) ExecX(ctx context.Context) {
|
||||
if err := _d.Exec(ctx); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,564 @@
|
||||
// Code generated by ent, DO NOT EDIT.
|
||||
|
||||
package ent
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect"
|
||||
"entgo.io/ent/dialect/sql"
|
||||
"entgo.io/ent/dialect/sql/sqlgraph"
|
||||
"entgo.io/ent/schema/field"
|
||||
"github.com/Wei-Shaw/sub2api/ent/batchimagejob"
|
||||
"github.com/Wei-Shaw/sub2api/ent/predicate"
|
||||
)
|
||||
|
||||
// BatchImageJobQuery is the builder for querying BatchImageJob entities.
|
||||
type BatchImageJobQuery struct {
|
||||
config
|
||||
ctx *QueryContext
|
||||
order []batchimagejob.OrderOption
|
||||
inters []Interceptor
|
||||
predicates []predicate.BatchImageJob
|
||||
modifiers []func(*sql.Selector)
|
||||
// intermediate query (i.e. traversal path).
|
||||
sql *sql.Selector
|
||||
path func(context.Context) (*sql.Selector, error)
|
||||
}
|
||||
|
||||
// Where adds a new predicate for the BatchImageJobQuery builder.
|
||||
func (_q *BatchImageJobQuery) Where(ps ...predicate.BatchImageJob) *BatchImageJobQuery {
|
||||
_q.predicates = append(_q.predicates, ps...)
|
||||
return _q
|
||||
}
|
||||
|
||||
// Limit the number of records to be returned by this query.
|
||||
func (_q *BatchImageJobQuery) Limit(limit int) *BatchImageJobQuery {
|
||||
_q.ctx.Limit = &limit
|
||||
return _q
|
||||
}
|
||||
|
||||
// Offset to start from.
|
||||
func (_q *BatchImageJobQuery) Offset(offset int) *BatchImageJobQuery {
|
||||
_q.ctx.Offset = &offset
|
||||
return _q
|
||||
}
|
||||
|
||||
// Unique configures the query builder to filter duplicate records on query.
|
||||
// By default, unique is set to true, and can be disabled using this method.
|
||||
func (_q *BatchImageJobQuery) Unique(unique bool) *BatchImageJobQuery {
|
||||
_q.ctx.Unique = &unique
|
||||
return _q
|
||||
}
|
||||
|
||||
// Order specifies how the records should be ordered.
|
||||
func (_q *BatchImageJobQuery) Order(o ...batchimagejob.OrderOption) *BatchImageJobQuery {
|
||||
_q.order = append(_q.order, o...)
|
||||
return _q
|
||||
}
|
||||
|
||||
// First returns the first BatchImageJob entity from the query.
|
||||
// Returns a *NotFoundError when no BatchImageJob was found.
|
||||
func (_q *BatchImageJobQuery) First(ctx context.Context) (*BatchImageJob, error) {
|
||||
nodes, err := _q.Limit(1).All(setContextOp(ctx, _q.ctx, ent.OpQueryFirst))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nil, &NotFoundError{batchimagejob.Label}
|
||||
}
|
||||
return nodes[0], nil
|
||||
}
|
||||
|
||||
// FirstX is like First, but panics if an error occurs.
|
||||
func (_q *BatchImageJobQuery) FirstX(ctx context.Context) *BatchImageJob {
|
||||
node, err := _q.First(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// FirstID returns the first BatchImageJob ID from the query.
|
||||
// Returns a *NotFoundError when no BatchImageJob ID was found.
|
||||
func (_q *BatchImageJobQuery) FirstID(ctx context.Context) (id int64, err error) {
|
||||
var ids []int64
|
||||
if ids, err = _q.Limit(1).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryFirstID)); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ids) == 0 {
|
||||
err = &NotFoundError{batchimagejob.Label}
|
||||
return
|
||||
}
|
||||
return ids[0], nil
|
||||
}
|
||||
|
||||
// FirstIDX is like FirstID, but panics if an error occurs.
|
||||
func (_q *BatchImageJobQuery) FirstIDX(ctx context.Context) int64 {
|
||||
id, err := _q.FirstID(ctx)
|
||||
if err != nil && !IsNotFound(err) {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// Only returns a single BatchImageJob entity found by the query, ensuring it only returns one.
|
||||
// Returns a *NotSingularError when more than one BatchImageJob entity is found.
|
||||
// Returns a *NotFoundError when no BatchImageJob entities are found.
|
||||
func (_q *BatchImageJobQuery) Only(ctx context.Context) (*BatchImageJob, error) {
|
||||
nodes, err := _q.Limit(2).All(setContextOp(ctx, _q.ctx, ent.OpQueryOnly))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch len(nodes) {
|
||||
case 1:
|
||||
return nodes[0], nil
|
||||
case 0:
|
||||
return nil, &NotFoundError{batchimagejob.Label}
|
||||
default:
|
||||
return nil, &NotSingularError{batchimagejob.Label}
|
||||
}
|
||||
}
|
||||
|
||||
// OnlyX is like Only, but panics if an error occurs.
|
||||
func (_q *BatchImageJobQuery) OnlyX(ctx context.Context) *BatchImageJob {
|
||||
node, err := _q.Only(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return node
|
||||
}
|
||||
|
||||
// OnlyID is like Only, but returns the only BatchImageJob ID in the query.
|
||||
// Returns a *NotSingularError when more than one BatchImageJob ID is found.
|
||||
// Returns a *NotFoundError when no entities are found.
|
||||
func (_q *BatchImageJobQuery) OnlyID(ctx context.Context) (id int64, err error) {
|
||||
var ids []int64
|
||||
if ids, err = _q.Limit(2).IDs(setContextOp(ctx, _q.ctx, ent.OpQueryOnlyID)); err != nil {
|
||||
return
|
||||
}
|
||||
switch len(ids) {
|
||||
case 1:
|
||||
id = ids[0]
|
||||
case 0:
|
||||
err = &NotFoundError{batchimagejob.Label}
|
||||
default:
|
||||
err = &NotSingularError{batchimagejob.Label}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// OnlyIDX is like OnlyID, but panics if an error occurs.
|
||||
func (_q *BatchImageJobQuery) OnlyIDX(ctx context.Context) int64 {
|
||||
id, err := _q.OnlyID(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// All executes the query and returns a list of BatchImageJobs.
|
||||
func (_q *BatchImageJobQuery) All(ctx context.Context) ([]*BatchImageJob, error) {
|
||||
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryAll)
|
||||
if err := _q.prepareQuery(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
qr := querierAll[[]*BatchImageJob, *BatchImageJobQuery]()
|
||||
return withInterceptors[[]*BatchImageJob](ctx, _q, qr, _q.inters)
|
||||
}
|
||||
|
||||
// AllX is like All, but panics if an error occurs.
|
||||
func (_q *BatchImageJobQuery) AllX(ctx context.Context) []*BatchImageJob {
|
||||
nodes, err := _q.All(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return nodes
|
||||
}
|
||||
|
||||
// IDs executes the query and returns a list of BatchImageJob IDs.
|
||||
func (_q *BatchImageJobQuery) IDs(ctx context.Context) (ids []int64, err error) {
|
||||
if _q.ctx.Unique == nil && _q.path != nil {
|
||||
_q.Unique(true)
|
||||
}
|
||||
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryIDs)
|
||||
if err = _q.Select(batchimagejob.FieldID).Scan(ctx, &ids); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
// IDsX is like IDs, but panics if an error occurs.
|
||||
func (_q *BatchImageJobQuery) IDsX(ctx context.Context) []int64 {
|
||||
ids, err := _q.IDs(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
// Count returns the count of the given query.
|
||||
func (_q *BatchImageJobQuery) Count(ctx context.Context) (int, error) {
|
||||
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryCount)
|
||||
if err := _q.prepareQuery(ctx); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return withInterceptors[int](ctx, _q, querierCount[*BatchImageJobQuery](), _q.inters)
|
||||
}
|
||||
|
||||
// CountX is like Count, but panics if an error occurs.
|
||||
func (_q *BatchImageJobQuery) CountX(ctx context.Context) int {
|
||||
count, err := _q.Count(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
// Exist returns true if the query has elements in the graph.
|
||||
func (_q *BatchImageJobQuery) Exist(ctx context.Context) (bool, error) {
|
||||
ctx = setContextOp(ctx, _q.ctx, ent.OpQueryExist)
|
||||
switch _, err := _q.FirstID(ctx); {
|
||||
case IsNotFound(err):
|
||||
return false, nil
|
||||
case err != nil:
|
||||
return false, fmt.Errorf("ent: check existence: %w", err)
|
||||
default:
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
// ExistX is like Exist, but panics if an error occurs.
|
||||
func (_q *BatchImageJobQuery) ExistX(ctx context.Context) bool {
|
||||
exist, err := _q.Exist(ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return exist
|
||||
}
|
||||
|
||||
// Clone returns a duplicate of the BatchImageJobQuery builder, including all associated steps. It can be
|
||||
// used to prepare common query builders and use them differently after the clone is made.
|
||||
func (_q *BatchImageJobQuery) Clone() *BatchImageJobQuery {
|
||||
if _q == nil {
|
||||
return nil
|
||||
}
|
||||
return &BatchImageJobQuery{
|
||||
config: _q.config,
|
||||
ctx: _q.ctx.Clone(),
|
||||
order: append([]batchimagejob.OrderOption{}, _q.order...),
|
||||
inters: append([]Interceptor{}, _q.inters...),
|
||||
predicates: append([]predicate.BatchImageJob{}, _q.predicates...),
|
||||
// clone intermediate query.
|
||||
sql: _q.sql.Clone(),
|
||||
path: _q.path,
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
// BatchID string `json:"batch_id,omitempty"`
|
||||
// Count int `json:"count,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.BatchImageJob.Query().
|
||||
// GroupBy(batchimagejob.FieldBatchID).
|
||||
// Aggregate(ent.Count()).
|
||||
// Scan(ctx, &v)
|
||||
func (_q *BatchImageJobQuery) GroupBy(field string, fields ...string) *BatchImageJobGroupBy {
|
||||
_q.ctx.Fields = append([]string{field}, fields...)
|
||||
grbuild := &BatchImageJobGroupBy{build: _q}
|
||||
grbuild.flds = &_q.ctx.Fields
|
||||
grbuild.label = batchimagejob.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 {
|
||||
// BatchID string `json:"batch_id,omitempty"`
|
||||
// }
|
||||
//
|
||||
// client.BatchImageJob.Query().
|
||||
// Select(batchimagejob.FieldBatchID).
|
||||
// Scan(ctx, &v)
|
||||
func (_q *BatchImageJobQuery) Select(fields ...string) *BatchImageJobSelect {
|
||||
_q.ctx.Fields = append(_q.ctx.Fields, fields...)
|
||||
sbuild := &BatchImageJobSelect{BatchImageJobQuery: _q}
|
||||
sbuild.label = batchimagejob.Label
|
||||
sbuild.flds, sbuild.scan = &_q.ctx.Fields, sbuild.Scan
|
||||
return sbuild
|
||||
}
|
||||
|
||||
// Aggregate returns a BatchImageJobSelect configured with the given aggregations.
|
||||
func (_q *BatchImageJobQuery) Aggregate(fns ...AggregateFunc) *BatchImageJobSelect {
|
||||
return _q.Select().Aggregate(fns...)
|
||||
}
|
||||
|
||||
func (_q *BatchImageJobQuery) prepareQuery(ctx context.Context) error {
|
||||
for _, inter := range _q.inters {
|
||||
if inter == nil {
|
||||
return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
|
||||
}
|
||||
if trv, ok := inter.(Traverser); ok {
|
||||
if err := trv.Traverse(ctx, _q); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, f := range _q.ctx.Fields {
|
||||
if !batchimagejob.ValidColumn(f) {
|
||||
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
|
||||
}
|
||||
}
|
||||
if _q.path != nil {
|
||||
prev, err := _q.path(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_q.sql = prev
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (_q *BatchImageJobQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*BatchImageJob, error) {
|
||||
var (
|
||||
nodes = []*BatchImageJob{}
|
||||
_spec = _q.querySpec()
|
||||
)
|
||||
_spec.ScanValues = func(columns []string) ([]any, error) {
|
||||
return (*BatchImageJob).scanValues(nil, columns)
|
||||
}
|
||||
_spec.Assign = func(columns []string, values []any) error {
|
||||
node := &BatchImageJob{config: _q.config}
|
||||
nodes = append(nodes, node)
|
||||
return node.assignValues(columns, values)
|
||||
}
|
||||
if len(_q.modifiers) > 0 {
|
||||
_spec.Modifiers = _q.modifiers
|
||||
}
|
||||
for i := range hooks {
|
||||
hooks[i](ctx, _spec)
|
||||
}
|
||||
if err := sqlgraph.QueryNodes(ctx, _q.driver, _spec); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(nodes) == 0 {
|
||||
return nodes, nil
|
||||
}
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
func (_q *BatchImageJobQuery) sqlCount(ctx context.Context) (int, error) {
|
||||
_spec := _q.querySpec()
|
||||
if len(_q.modifiers) > 0 {
|
||||
_spec.Modifiers = _q.modifiers
|
||||
}
|
||||
_spec.Node.Columns = _q.ctx.Fields
|
||||
if len(_q.ctx.Fields) > 0 {
|
||||
_spec.Unique = _q.ctx.Unique != nil && *_q.ctx.Unique
|
||||
}
|
||||
return sqlgraph.CountNodes(ctx, _q.driver, _spec)
|
||||
}
|
||||
|
||||
func (_q *BatchImageJobQuery) querySpec() *sqlgraph.QuerySpec {
|
||||
_spec := sqlgraph.NewQuerySpec(batchimagejob.Table, batchimagejob.Columns, sqlgraph.NewFieldSpec(batchimagejob.FieldID, field.TypeInt64))
|
||||
_spec.From = _q.sql
|
||||
if unique := _q.ctx.Unique; unique != nil {
|
||||
_spec.Unique = *unique
|
||||
} else if _q.path != nil {
|
||||
_spec.Unique = true
|
||||
}
|
||||
if fields := _q.ctx.Fields; len(fields) > 0 {
|
||||
_spec.Node.Columns = make([]string, 0, len(fields))
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, batchimagejob.FieldID)
|
||||
for i := range fields {
|
||||
if fields[i] != batchimagejob.FieldID {
|
||||
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
if ps := _q.predicates; len(ps) > 0 {
|
||||
_spec.Predicate = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
if limit := _q.ctx.Limit; limit != nil {
|
||||
_spec.Limit = *limit
|
||||
}
|
||||
if offset := _q.ctx.Offset; offset != nil {
|
||||
_spec.Offset = *offset
|
||||
}
|
||||
if ps := _q.order; len(ps) > 0 {
|
||||
_spec.Order = func(selector *sql.Selector) {
|
||||
for i := range ps {
|
||||
ps[i](selector)
|
||||
}
|
||||
}
|
||||
}
|
||||
return _spec
|
||||
}
|
||||
|
||||
func (_q *BatchImageJobQuery) sqlQuery(ctx context.Context) *sql.Selector {
|
||||
builder := sql.Dialect(_q.driver.Dialect())
|
||||
t1 := builder.Table(batchimagejob.Table)
|
||||
columns := _q.ctx.Fields
|
||||
if len(columns) == 0 {
|
||||
columns = batchimagejob.Columns
|
||||
}
|
||||
selector := builder.Select(t1.Columns(columns...)...).From(t1)
|
||||
if _q.sql != nil {
|
||||
selector = _q.sql
|
||||
selector.Select(selector.Columns(columns...)...)
|
||||
}
|
||||
if _q.ctx.Unique != nil && *_q.ctx.Unique {
|
||||
selector.Distinct()
|
||||
}
|
||||
for _, m := range _q.modifiers {
|
||||
m(selector)
|
||||
}
|
||||
for _, p := range _q.predicates {
|
||||
p(selector)
|
||||
}
|
||||
for _, p := range _q.order {
|
||||
p(selector)
|
||||
}
|
||||
if offset := _q.ctx.Offset; offset != nil {
|
||||
// limit is mandatory for offset clause. We start
|
||||
// with default value, and override it below if needed.
|
||||
selector.Offset(*offset).Limit(math.MaxInt32)
|
||||
}
|
||||
if limit := _q.ctx.Limit; limit != nil {
|
||||
selector.Limit(*limit)
|
||||
}
|
||||
return selector
|
||||
}
|
||||
|
||||
// ForUpdate locks the selected rows against concurrent updates, and prevent them from being
|
||||
// updated, deleted or "selected ... for update" by other sessions, until the transaction is
|
||||
// either committed or rolled-back.
|
||||
func (_q *BatchImageJobQuery) ForUpdate(opts ...sql.LockOption) *BatchImageJobQuery {
|
||||
if _q.driver.Dialect() == dialect.Postgres {
|
||||
_q.Unique(false)
|
||||
}
|
||||
_q.modifiers = append(_q.modifiers, func(s *sql.Selector) {
|
||||
s.ForUpdate(opts...)
|
||||
})
|
||||
return _q
|
||||
}
|
||||
|
||||
// ForShare behaves similarly to ForUpdate, except that it acquires a shared mode lock
|
||||
// on any rows that are read. Other sessions can read the rows, but cannot modify them
|
||||
// until your transaction commits.
|
||||
func (_q *BatchImageJobQuery) ForShare(opts ...sql.LockOption) *BatchImageJobQuery {
|
||||
if _q.driver.Dialect() == dialect.Postgres {
|
||||
_q.Unique(false)
|
||||
}
|
||||
_q.modifiers = append(_q.modifiers, func(s *sql.Selector) {
|
||||
s.ForShare(opts...)
|
||||
})
|
||||
return _q
|
||||
}
|
||||
|
||||
// BatchImageJobGroupBy is the group-by builder for BatchImageJob entities.
|
||||
type BatchImageJobGroupBy struct {
|
||||
selector
|
||||
build *BatchImageJobQuery
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the group-by query.
|
||||
func (_g *BatchImageJobGroupBy) Aggregate(fns ...AggregateFunc) *BatchImageJobGroupBy {
|
||||
_g.fns = append(_g.fns, fns...)
|
||||
return _g
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (_g *BatchImageJobGroupBy) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, _g.build.ctx, ent.OpQueryGroupBy)
|
||||
if err := _g.build.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return scanWithInterceptors[*BatchImageJobQuery, *BatchImageJobGroupBy](ctx, _g.build, _g, _g.build.inters, v)
|
||||
}
|
||||
|
||||
func (_g *BatchImageJobGroupBy) sqlScan(ctx context.Context, root *BatchImageJobQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx).Select()
|
||||
aggregation := make([]string, 0, len(_g.fns))
|
||||
for _, fn := range _g.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
if len(selector.SelectedColumns()) == 0 {
|
||||
columns := make([]string, 0, len(*_g.flds)+len(_g.fns))
|
||||
for _, f := range *_g.flds {
|
||||
columns = append(columns, selector.C(f))
|
||||
}
|
||||
columns = append(columns, aggregation...)
|
||||
selector.Select(columns...)
|
||||
}
|
||||
selector.GroupBy(selector.Columns(*_g.flds...)...)
|
||||
if err := selector.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := _g.build.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
|
||||
// BatchImageJobSelect is the builder for selecting fields of BatchImageJob entities.
|
||||
type BatchImageJobSelect struct {
|
||||
*BatchImageJobQuery
|
||||
selector
|
||||
}
|
||||
|
||||
// Aggregate adds the given aggregation functions to the selector query.
|
||||
func (_s *BatchImageJobSelect) Aggregate(fns ...AggregateFunc) *BatchImageJobSelect {
|
||||
_s.fns = append(_s.fns, fns...)
|
||||
return _s
|
||||
}
|
||||
|
||||
// Scan applies the selector query and scans the result into the given value.
|
||||
func (_s *BatchImageJobSelect) Scan(ctx context.Context, v any) error {
|
||||
ctx = setContextOp(ctx, _s.ctx, ent.OpQuerySelect)
|
||||
if err := _s.prepareQuery(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
return scanWithInterceptors[*BatchImageJobQuery, *BatchImageJobSelect](ctx, _s.BatchImageJobQuery, _s, _s.inters, v)
|
||||
}
|
||||
|
||||
func (_s *BatchImageJobSelect) sqlScan(ctx context.Context, root *BatchImageJobQuery, v any) error {
|
||||
selector := root.sqlQuery(ctx)
|
||||
aggregation := make([]string, 0, len(_s.fns))
|
||||
for _, fn := range _s.fns {
|
||||
aggregation = append(aggregation, fn(selector))
|
||||
}
|
||||
switch n := len(*_s.selector.flds); {
|
||||
case n == 0 && len(aggregation) > 0:
|
||||
selector.Select(aggregation...)
|
||||
case n != 0 && len(aggregation) > 0:
|
||||
selector.AppendSelect(aggregation...)
|
||||
}
|
||||
rows := &sql.Rows{}
|
||||
query, args := selector.Query()
|
||||
if err := _s.driver.Query(ctx, query, args, rows); err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
return sql.ScanSlice(rows, v)
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -167,6 +167,7 @@ const (
|
||||
ProviderOpenai Provider = "openai"
|
||||
ProviderAnthropic Provider = "anthropic"
|
||||
ProviderGemini Provider = "gemini"
|
||||
ProviderGrok Provider = "grok"
|
||||
)
|
||||
|
||||
func (pr Provider) String() string {
|
||||
@@ -176,7 +177,7 @@ func (pr Provider) String() string {
|
||||
// ProviderValidator is a validator for the "provider" field enum values. It is called by the builders before save.
|
||||
func ProviderValidator(pr Provider) error {
|
||||
switch pr {
|
||||
case ProviderOpenai, ProviderAnthropic, ProviderGemini:
|
||||
case ProviderOpenai, ProviderAnthropic, ProviderGemini, ProviderGrok:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("channelmonitor: invalid enum value for provider field: %q", pr)
|
||||
|
||||
@@ -103,6 +103,7 @@ const (
|
||||
ProviderOpenai Provider = "openai"
|
||||
ProviderAnthropic Provider = "anthropic"
|
||||
ProviderGemini Provider = "gemini"
|
||||
ProviderGrok Provider = "grok"
|
||||
)
|
||||
|
||||
func (pr Provider) String() string {
|
||||
@@ -112,7 +113,7 @@ func (pr Provider) String() string {
|
||||
// ProviderValidator is a validator for the "provider" field enum values. It is called by the builders before save.
|
||||
func ProviderValidator(pr Provider) error {
|
||||
switch pr {
|
||||
case ProviderOpenai, ProviderAnthropic, ProviderGemini:
|
||||
case ProviderOpenai, ProviderAnthropic, ProviderGemini, ProviderGrok:
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("channelmonitorrequesttemplate: invalid enum value for provider field: %q", pr)
|
||||
|
||||
+489
-32
@@ -22,6 +22,9 @@ import (
|
||||
"github.com/Wei-Shaw/sub2api/ent/apikey"
|
||||
"github.com/Wei-Shaw/sub2api/ent/authidentity"
|
||||
"github.com/Wei-Shaw/sub2api/ent/authidentitychannel"
|
||||
"github.com/Wei-Shaw/sub2api/ent/batchimageevent"
|
||||
"github.com/Wei-Shaw/sub2api/ent/batchimageitem"
|
||||
"github.com/Wei-Shaw/sub2api/ent/batchimagejob"
|
||||
"github.com/Wei-Shaw/sub2api/ent/channelmonitor"
|
||||
"github.com/Wei-Shaw/sub2api/ent/channelmonitordailyrollup"
|
||||
"github.com/Wei-Shaw/sub2api/ent/channelmonitorhistory"
|
||||
@@ -73,6 +76,12 @@ type Client struct {
|
||||
AuthIdentity *AuthIdentityClient
|
||||
// AuthIdentityChannel is the client for interacting with the AuthIdentityChannel builders.
|
||||
AuthIdentityChannel *AuthIdentityChannelClient
|
||||
// BatchImageEvent is the client for interacting with the BatchImageEvent builders.
|
||||
BatchImageEvent *BatchImageEventClient
|
||||
// BatchImageItem is the client for interacting with the BatchImageItem builders.
|
||||
BatchImageItem *BatchImageItemClient
|
||||
// BatchImageJob is the client for interacting with the BatchImageJob builders.
|
||||
BatchImageJob *BatchImageJobClient
|
||||
// ChannelMonitor is the client for interacting with the ChannelMonitor builders.
|
||||
ChannelMonitor *ChannelMonitorClient
|
||||
// ChannelMonitorDailyRollup is the client for interacting with the ChannelMonitorDailyRollup builders.
|
||||
@@ -147,6 +156,9 @@ func (c *Client) init() {
|
||||
c.AnnouncementRead = NewAnnouncementReadClient(c.config)
|
||||
c.AuthIdentity = NewAuthIdentityClient(c.config)
|
||||
c.AuthIdentityChannel = NewAuthIdentityChannelClient(c.config)
|
||||
c.BatchImageEvent = NewBatchImageEventClient(c.config)
|
||||
c.BatchImageItem = NewBatchImageItemClient(c.config)
|
||||
c.BatchImageJob = NewBatchImageJobClient(c.config)
|
||||
c.ChannelMonitor = NewChannelMonitorClient(c.config)
|
||||
c.ChannelMonitorDailyRollup = NewChannelMonitorDailyRollupClient(c.config)
|
||||
c.ChannelMonitorHistory = NewChannelMonitorHistoryClient(c.config)
|
||||
@@ -274,6 +286,9 @@ func (c *Client) Tx(ctx context.Context) (*Tx, error) {
|
||||
AnnouncementRead: NewAnnouncementReadClient(cfg),
|
||||
AuthIdentity: NewAuthIdentityClient(cfg),
|
||||
AuthIdentityChannel: NewAuthIdentityChannelClient(cfg),
|
||||
BatchImageEvent: NewBatchImageEventClient(cfg),
|
||||
BatchImageItem: NewBatchImageItemClient(cfg),
|
||||
BatchImageJob: NewBatchImageJobClient(cfg),
|
||||
ChannelMonitor: NewChannelMonitorClient(cfg),
|
||||
ChannelMonitorDailyRollup: NewChannelMonitorDailyRollupClient(cfg),
|
||||
ChannelMonitorHistory: NewChannelMonitorHistoryClient(cfg),
|
||||
@@ -328,6 +343,9 @@ func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error)
|
||||
AnnouncementRead: NewAnnouncementReadClient(cfg),
|
||||
AuthIdentity: NewAuthIdentityClient(cfg),
|
||||
AuthIdentityChannel: NewAuthIdentityChannelClient(cfg),
|
||||
BatchImageEvent: NewBatchImageEventClient(cfg),
|
||||
BatchImageItem: NewBatchImageItemClient(cfg),
|
||||
BatchImageJob: NewBatchImageJobClient(cfg),
|
||||
ChannelMonitor: NewChannelMonitorClient(cfg),
|
||||
ChannelMonitorDailyRollup: NewChannelMonitorDailyRollupClient(cfg),
|
||||
ChannelMonitorHistory: NewChannelMonitorHistoryClient(cfg),
|
||||
@@ -386,14 +404,15 @@ func (c *Client) Close() error {
|
||||
func (c *Client) Use(hooks ...Hook) {
|
||||
for _, n := range []interface{ Use(...Hook) }{
|
||||
c.APIKey, c.Account, c.AccountGroup, c.Announcement, c.AnnouncementRead,
|
||||
c.AuthIdentity, c.AuthIdentityChannel, c.ChannelMonitor,
|
||||
c.ChannelMonitorDailyRollup, c.ChannelMonitorHistory,
|
||||
c.ChannelMonitorRequestTemplate, c.ErrorPassthroughRule, c.Group,
|
||||
c.IdempotencyRecord, c.IdentityAdoptionDecision, c.PaymentAuditLog,
|
||||
c.PaymentOrder, c.PaymentProviderInstance, c.PendingAuthSession, c.PromoCode,
|
||||
c.PromoCodeUsage, c.Proxy, c.RedeemCode, c.SecuritySecret, c.Setting,
|
||||
c.SubscriptionPlan, c.TLSFingerprintProfile, c.UsageCleanupTask, c.UsageLog,
|
||||
c.User, c.UserAllowedGroup, c.UserAttributeDefinition, c.UserAttributeValue,
|
||||
c.AuthIdentity, c.AuthIdentityChannel, c.BatchImageEvent, c.BatchImageItem,
|
||||
c.BatchImageJob, c.ChannelMonitor, c.ChannelMonitorDailyRollup,
|
||||
c.ChannelMonitorHistory, c.ChannelMonitorRequestTemplate,
|
||||
c.ErrorPassthroughRule, c.Group, c.IdempotencyRecord,
|
||||
c.IdentityAdoptionDecision, c.PaymentAuditLog, c.PaymentOrder,
|
||||
c.PaymentProviderInstance, c.PendingAuthSession, c.PromoCode, c.PromoCodeUsage,
|
||||
c.Proxy, c.RedeemCode, c.SecuritySecret, c.Setting, c.SubscriptionPlan,
|
||||
c.TLSFingerprintProfile, c.UsageCleanupTask, c.UsageLog, c.User,
|
||||
c.UserAllowedGroup, c.UserAttributeDefinition, c.UserAttributeValue,
|
||||
c.UserPlatformQuota, c.UserSubscription,
|
||||
} {
|
||||
n.Use(hooks...)
|
||||
@@ -405,14 +424,15 @@ func (c *Client) Use(hooks ...Hook) {
|
||||
func (c *Client) Intercept(interceptors ...Interceptor) {
|
||||
for _, n := range []interface{ Intercept(...Interceptor) }{
|
||||
c.APIKey, c.Account, c.AccountGroup, c.Announcement, c.AnnouncementRead,
|
||||
c.AuthIdentity, c.AuthIdentityChannel, c.ChannelMonitor,
|
||||
c.ChannelMonitorDailyRollup, c.ChannelMonitorHistory,
|
||||
c.ChannelMonitorRequestTemplate, c.ErrorPassthroughRule, c.Group,
|
||||
c.IdempotencyRecord, c.IdentityAdoptionDecision, c.PaymentAuditLog,
|
||||
c.PaymentOrder, c.PaymentProviderInstance, c.PendingAuthSession, c.PromoCode,
|
||||
c.PromoCodeUsage, c.Proxy, c.RedeemCode, c.SecuritySecret, c.Setting,
|
||||
c.SubscriptionPlan, c.TLSFingerprintProfile, c.UsageCleanupTask, c.UsageLog,
|
||||
c.User, c.UserAllowedGroup, c.UserAttributeDefinition, c.UserAttributeValue,
|
||||
c.AuthIdentity, c.AuthIdentityChannel, c.BatchImageEvent, c.BatchImageItem,
|
||||
c.BatchImageJob, c.ChannelMonitor, c.ChannelMonitorDailyRollup,
|
||||
c.ChannelMonitorHistory, c.ChannelMonitorRequestTemplate,
|
||||
c.ErrorPassthroughRule, c.Group, c.IdempotencyRecord,
|
||||
c.IdentityAdoptionDecision, c.PaymentAuditLog, c.PaymentOrder,
|
||||
c.PaymentProviderInstance, c.PendingAuthSession, c.PromoCode, c.PromoCodeUsage,
|
||||
c.Proxy, c.RedeemCode, c.SecuritySecret, c.Setting, c.SubscriptionPlan,
|
||||
c.TLSFingerprintProfile, c.UsageCleanupTask, c.UsageLog, c.User,
|
||||
c.UserAllowedGroup, c.UserAttributeDefinition, c.UserAttributeValue,
|
||||
c.UserPlatformQuota, c.UserSubscription,
|
||||
} {
|
||||
n.Intercept(interceptors...)
|
||||
@@ -436,6 +456,12 @@ func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) {
|
||||
return c.AuthIdentity.mutate(ctx, m)
|
||||
case *AuthIdentityChannelMutation:
|
||||
return c.AuthIdentityChannel.mutate(ctx, m)
|
||||
case *BatchImageEventMutation:
|
||||
return c.BatchImageEvent.mutate(ctx, m)
|
||||
case *BatchImageItemMutation:
|
||||
return c.BatchImageItem.mutate(ctx, m)
|
||||
case *BatchImageJobMutation:
|
||||
return c.BatchImageJob.mutate(ctx, m)
|
||||
case *ChannelMonitorMutation:
|
||||
return c.ChannelMonitor.mutate(ctx, m)
|
||||
case *ChannelMonitorDailyRollupMutation:
|
||||
@@ -820,6 +846,38 @@ func (c *AccountClient) QueryProxy(_m *Account) *ProxyQuery {
|
||||
return query
|
||||
}
|
||||
|
||||
// QueryParent queries the parent edge of a Account.
|
||||
func (c *AccountClient) QueryParent(_m *Account) *AccountQuery {
|
||||
query := (&AccountClient{config: c.config}).Query()
|
||||
query.path = func(context.Context) (fromV *sql.Selector, _ error) {
|
||||
id := _m.ID
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(account.Table, account.FieldID, id),
|
||||
sqlgraph.To(account.Table, account.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.M2O, true, account.ParentTable, account.ParentColumn),
|
||||
)
|
||||
fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step)
|
||||
return fromV, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// QueryChildren queries the children edge of a Account.
|
||||
func (c *AccountClient) QueryChildren(_m *Account) *AccountQuery {
|
||||
query := (&AccountClient{config: c.config}).Query()
|
||||
query.path = func(context.Context) (fromV *sql.Selector, _ error) {
|
||||
id := _m.ID
|
||||
step := sqlgraph.NewStep(
|
||||
sqlgraph.From(account.Table, account.FieldID, id),
|
||||
sqlgraph.To(account.Table, account.FieldID),
|
||||
sqlgraph.Edge(sqlgraph.O2M, false, account.ChildrenTable, account.ChildrenColumn),
|
||||
)
|
||||
fromV = sqlgraph.Neighbors(_m.driver.Dialect(), step)
|
||||
return fromV, nil
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
// QueryUsageLogs queries the usage_logs edge of a Account.
|
||||
func (c *AccountClient) QueryUsageLogs(_m *Account) *UsageLogQuery {
|
||||
query := (&UsageLogClient{config: c.config}).Query()
|
||||
@@ -1639,6 +1697,405 @@ func (c *AuthIdentityChannelClient) mutate(ctx context.Context, m *AuthIdentityC
|
||||
}
|
||||
}
|
||||
|
||||
// BatchImageEventClient is a client for the BatchImageEvent schema.
|
||||
type BatchImageEventClient struct {
|
||||
config
|
||||
}
|
||||
|
||||
// NewBatchImageEventClient returns a client for the BatchImageEvent from the given config.
|
||||
func NewBatchImageEventClient(c config) *BatchImageEventClient {
|
||||
return &BatchImageEventClient{config: c}
|
||||
}
|
||||
|
||||
// Use adds a list of mutation hooks to the hooks stack.
|
||||
// A call to `Use(f, g, h)` equals to `batchimageevent.Hooks(f(g(h())))`.
|
||||
func (c *BatchImageEventClient) Use(hooks ...Hook) {
|
||||
c.hooks.BatchImageEvent = append(c.hooks.BatchImageEvent, hooks...)
|
||||
}
|
||||
|
||||
// Intercept adds a list of query interceptors to the interceptors stack.
|
||||
// A call to `Intercept(f, g, h)` equals to `batchimageevent.Intercept(f(g(h())))`.
|
||||
func (c *BatchImageEventClient) Intercept(interceptors ...Interceptor) {
|
||||
c.inters.BatchImageEvent = append(c.inters.BatchImageEvent, interceptors...)
|
||||
}
|
||||
|
||||
// Create returns a builder for creating a BatchImageEvent entity.
|
||||
func (c *BatchImageEventClient) Create() *BatchImageEventCreate {
|
||||
mutation := newBatchImageEventMutation(c.config, OpCreate)
|
||||
return &BatchImageEventCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// CreateBulk returns a builder for creating a bulk of BatchImageEvent entities.
|
||||
func (c *BatchImageEventClient) CreateBulk(builders ...*BatchImageEventCreate) *BatchImageEventCreateBulk {
|
||||
return &BatchImageEventCreateBulk{config: c.config, builders: builders}
|
||||
}
|
||||
|
||||
// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates
|
||||
// a builder and applies setFunc on it.
|
||||
func (c *BatchImageEventClient) MapCreateBulk(slice any, setFunc func(*BatchImageEventCreate, int)) *BatchImageEventCreateBulk {
|
||||
rv := reflect.ValueOf(slice)
|
||||
if rv.Kind() != reflect.Slice {
|
||||
return &BatchImageEventCreateBulk{err: fmt.Errorf("calling to BatchImageEventClient.MapCreateBulk with wrong type %T, need slice", slice)}
|
||||
}
|
||||
builders := make([]*BatchImageEventCreate, rv.Len())
|
||||
for i := 0; i < rv.Len(); i++ {
|
||||
builders[i] = c.Create()
|
||||
setFunc(builders[i], i)
|
||||
}
|
||||
return &BatchImageEventCreateBulk{config: c.config, builders: builders}
|
||||
}
|
||||
|
||||
// Update returns an update builder for BatchImageEvent.
|
||||
func (c *BatchImageEventClient) Update() *BatchImageEventUpdate {
|
||||
mutation := newBatchImageEventMutation(c.config, OpUpdate)
|
||||
return &BatchImageEventUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// UpdateOne returns an update builder for the given entity.
|
||||
func (c *BatchImageEventClient) UpdateOne(_m *BatchImageEvent) *BatchImageEventUpdateOne {
|
||||
mutation := newBatchImageEventMutation(c.config, OpUpdateOne, withBatchImageEvent(_m))
|
||||
return &BatchImageEventUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// UpdateOneID returns an update builder for the given id.
|
||||
func (c *BatchImageEventClient) UpdateOneID(id int64) *BatchImageEventUpdateOne {
|
||||
mutation := newBatchImageEventMutation(c.config, OpUpdateOne, withBatchImageEventID(id))
|
||||
return &BatchImageEventUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// Delete returns a delete builder for BatchImageEvent.
|
||||
func (c *BatchImageEventClient) Delete() *BatchImageEventDelete {
|
||||
mutation := newBatchImageEventMutation(c.config, OpDelete)
|
||||
return &BatchImageEventDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// DeleteOne returns a builder for deleting the given entity.
|
||||
func (c *BatchImageEventClient) DeleteOne(_m *BatchImageEvent) *BatchImageEventDeleteOne {
|
||||
return c.DeleteOneID(_m.ID)
|
||||
}
|
||||
|
||||
// DeleteOneID returns a builder for deleting the given entity by its id.
|
||||
func (c *BatchImageEventClient) DeleteOneID(id int64) *BatchImageEventDeleteOne {
|
||||
builder := c.Delete().Where(batchimageevent.ID(id))
|
||||
builder.mutation.id = &id
|
||||
builder.mutation.op = OpDeleteOne
|
||||
return &BatchImageEventDeleteOne{builder}
|
||||
}
|
||||
|
||||
// Query returns a query builder for BatchImageEvent.
|
||||
func (c *BatchImageEventClient) Query() *BatchImageEventQuery {
|
||||
return &BatchImageEventQuery{
|
||||
config: c.config,
|
||||
ctx: &QueryContext{Type: TypeBatchImageEvent},
|
||||
inters: c.Interceptors(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get returns a BatchImageEvent entity by its id.
|
||||
func (c *BatchImageEventClient) Get(ctx context.Context, id int64) (*BatchImageEvent, error) {
|
||||
return c.Query().Where(batchimageevent.ID(id)).Only(ctx)
|
||||
}
|
||||
|
||||
// GetX is like Get, but panics if an error occurs.
|
||||
func (c *BatchImageEventClient) GetX(ctx context.Context, id int64) *BatchImageEvent {
|
||||
obj, err := c.Get(ctx, id)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
// Hooks returns the client hooks.
|
||||
func (c *BatchImageEventClient) Hooks() []Hook {
|
||||
return c.hooks.BatchImageEvent
|
||||
}
|
||||
|
||||
// Interceptors returns the client interceptors.
|
||||
func (c *BatchImageEventClient) Interceptors() []Interceptor {
|
||||
return c.inters.BatchImageEvent
|
||||
}
|
||||
|
||||
func (c *BatchImageEventClient) mutate(ctx context.Context, m *BatchImageEventMutation) (Value, error) {
|
||||
switch m.Op() {
|
||||
case OpCreate:
|
||||
return (&BatchImageEventCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
|
||||
case OpUpdate:
|
||||
return (&BatchImageEventUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
|
||||
case OpUpdateOne:
|
||||
return (&BatchImageEventUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
|
||||
case OpDelete, OpDeleteOne:
|
||||
return (&BatchImageEventDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
|
||||
default:
|
||||
return nil, fmt.Errorf("ent: unknown BatchImageEvent mutation op: %q", m.Op())
|
||||
}
|
||||
}
|
||||
|
||||
// BatchImageItemClient is a client for the BatchImageItem schema.
|
||||
type BatchImageItemClient struct {
|
||||
config
|
||||
}
|
||||
|
||||
// NewBatchImageItemClient returns a client for the BatchImageItem from the given config.
|
||||
func NewBatchImageItemClient(c config) *BatchImageItemClient {
|
||||
return &BatchImageItemClient{config: c}
|
||||
}
|
||||
|
||||
// Use adds a list of mutation hooks to the hooks stack.
|
||||
// A call to `Use(f, g, h)` equals to `batchimageitem.Hooks(f(g(h())))`.
|
||||
func (c *BatchImageItemClient) Use(hooks ...Hook) {
|
||||
c.hooks.BatchImageItem = append(c.hooks.BatchImageItem, hooks...)
|
||||
}
|
||||
|
||||
// Intercept adds a list of query interceptors to the interceptors stack.
|
||||
// A call to `Intercept(f, g, h)` equals to `batchimageitem.Intercept(f(g(h())))`.
|
||||
func (c *BatchImageItemClient) Intercept(interceptors ...Interceptor) {
|
||||
c.inters.BatchImageItem = append(c.inters.BatchImageItem, interceptors...)
|
||||
}
|
||||
|
||||
// Create returns a builder for creating a BatchImageItem entity.
|
||||
func (c *BatchImageItemClient) Create() *BatchImageItemCreate {
|
||||
mutation := newBatchImageItemMutation(c.config, OpCreate)
|
||||
return &BatchImageItemCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// CreateBulk returns a builder for creating a bulk of BatchImageItem entities.
|
||||
func (c *BatchImageItemClient) CreateBulk(builders ...*BatchImageItemCreate) *BatchImageItemCreateBulk {
|
||||
return &BatchImageItemCreateBulk{config: c.config, builders: builders}
|
||||
}
|
||||
|
||||
// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates
|
||||
// a builder and applies setFunc on it.
|
||||
func (c *BatchImageItemClient) MapCreateBulk(slice any, setFunc func(*BatchImageItemCreate, int)) *BatchImageItemCreateBulk {
|
||||
rv := reflect.ValueOf(slice)
|
||||
if rv.Kind() != reflect.Slice {
|
||||
return &BatchImageItemCreateBulk{err: fmt.Errorf("calling to BatchImageItemClient.MapCreateBulk with wrong type %T, need slice", slice)}
|
||||
}
|
||||
builders := make([]*BatchImageItemCreate, rv.Len())
|
||||
for i := 0; i < rv.Len(); i++ {
|
||||
builders[i] = c.Create()
|
||||
setFunc(builders[i], i)
|
||||
}
|
||||
return &BatchImageItemCreateBulk{config: c.config, builders: builders}
|
||||
}
|
||||
|
||||
// Update returns an update builder for BatchImageItem.
|
||||
func (c *BatchImageItemClient) Update() *BatchImageItemUpdate {
|
||||
mutation := newBatchImageItemMutation(c.config, OpUpdate)
|
||||
return &BatchImageItemUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// UpdateOne returns an update builder for the given entity.
|
||||
func (c *BatchImageItemClient) UpdateOne(_m *BatchImageItem) *BatchImageItemUpdateOne {
|
||||
mutation := newBatchImageItemMutation(c.config, OpUpdateOne, withBatchImageItem(_m))
|
||||
return &BatchImageItemUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// UpdateOneID returns an update builder for the given id.
|
||||
func (c *BatchImageItemClient) UpdateOneID(id int64) *BatchImageItemUpdateOne {
|
||||
mutation := newBatchImageItemMutation(c.config, OpUpdateOne, withBatchImageItemID(id))
|
||||
return &BatchImageItemUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// Delete returns a delete builder for BatchImageItem.
|
||||
func (c *BatchImageItemClient) Delete() *BatchImageItemDelete {
|
||||
mutation := newBatchImageItemMutation(c.config, OpDelete)
|
||||
return &BatchImageItemDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// DeleteOne returns a builder for deleting the given entity.
|
||||
func (c *BatchImageItemClient) DeleteOne(_m *BatchImageItem) *BatchImageItemDeleteOne {
|
||||
return c.DeleteOneID(_m.ID)
|
||||
}
|
||||
|
||||
// DeleteOneID returns a builder for deleting the given entity by its id.
|
||||
func (c *BatchImageItemClient) DeleteOneID(id int64) *BatchImageItemDeleteOne {
|
||||
builder := c.Delete().Where(batchimageitem.ID(id))
|
||||
builder.mutation.id = &id
|
||||
builder.mutation.op = OpDeleteOne
|
||||
return &BatchImageItemDeleteOne{builder}
|
||||
}
|
||||
|
||||
// Query returns a query builder for BatchImageItem.
|
||||
func (c *BatchImageItemClient) Query() *BatchImageItemQuery {
|
||||
return &BatchImageItemQuery{
|
||||
config: c.config,
|
||||
ctx: &QueryContext{Type: TypeBatchImageItem},
|
||||
inters: c.Interceptors(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get returns a BatchImageItem entity by its id.
|
||||
func (c *BatchImageItemClient) Get(ctx context.Context, id int64) (*BatchImageItem, error) {
|
||||
return c.Query().Where(batchimageitem.ID(id)).Only(ctx)
|
||||
}
|
||||
|
||||
// GetX is like Get, but panics if an error occurs.
|
||||
func (c *BatchImageItemClient) GetX(ctx context.Context, id int64) *BatchImageItem {
|
||||
obj, err := c.Get(ctx, id)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
// Hooks returns the client hooks.
|
||||
func (c *BatchImageItemClient) Hooks() []Hook {
|
||||
return c.hooks.BatchImageItem
|
||||
}
|
||||
|
||||
// Interceptors returns the client interceptors.
|
||||
func (c *BatchImageItemClient) Interceptors() []Interceptor {
|
||||
return c.inters.BatchImageItem
|
||||
}
|
||||
|
||||
func (c *BatchImageItemClient) mutate(ctx context.Context, m *BatchImageItemMutation) (Value, error) {
|
||||
switch m.Op() {
|
||||
case OpCreate:
|
||||
return (&BatchImageItemCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
|
||||
case OpUpdate:
|
||||
return (&BatchImageItemUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
|
||||
case OpUpdateOne:
|
||||
return (&BatchImageItemUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
|
||||
case OpDelete, OpDeleteOne:
|
||||
return (&BatchImageItemDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
|
||||
default:
|
||||
return nil, fmt.Errorf("ent: unknown BatchImageItem mutation op: %q", m.Op())
|
||||
}
|
||||
}
|
||||
|
||||
// BatchImageJobClient is a client for the BatchImageJob schema.
|
||||
type BatchImageJobClient struct {
|
||||
config
|
||||
}
|
||||
|
||||
// NewBatchImageJobClient returns a client for the BatchImageJob from the given config.
|
||||
func NewBatchImageJobClient(c config) *BatchImageJobClient {
|
||||
return &BatchImageJobClient{config: c}
|
||||
}
|
||||
|
||||
// Use adds a list of mutation hooks to the hooks stack.
|
||||
// A call to `Use(f, g, h)` equals to `batchimagejob.Hooks(f(g(h())))`.
|
||||
func (c *BatchImageJobClient) Use(hooks ...Hook) {
|
||||
c.hooks.BatchImageJob = append(c.hooks.BatchImageJob, hooks...)
|
||||
}
|
||||
|
||||
// Intercept adds a list of query interceptors to the interceptors stack.
|
||||
// A call to `Intercept(f, g, h)` equals to `batchimagejob.Intercept(f(g(h())))`.
|
||||
func (c *BatchImageJobClient) Intercept(interceptors ...Interceptor) {
|
||||
c.inters.BatchImageJob = append(c.inters.BatchImageJob, interceptors...)
|
||||
}
|
||||
|
||||
// Create returns a builder for creating a BatchImageJob entity.
|
||||
func (c *BatchImageJobClient) Create() *BatchImageJobCreate {
|
||||
mutation := newBatchImageJobMutation(c.config, OpCreate)
|
||||
return &BatchImageJobCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// CreateBulk returns a builder for creating a bulk of BatchImageJob entities.
|
||||
func (c *BatchImageJobClient) CreateBulk(builders ...*BatchImageJobCreate) *BatchImageJobCreateBulk {
|
||||
return &BatchImageJobCreateBulk{config: c.config, builders: builders}
|
||||
}
|
||||
|
||||
// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates
|
||||
// a builder and applies setFunc on it.
|
||||
func (c *BatchImageJobClient) MapCreateBulk(slice any, setFunc func(*BatchImageJobCreate, int)) *BatchImageJobCreateBulk {
|
||||
rv := reflect.ValueOf(slice)
|
||||
if rv.Kind() != reflect.Slice {
|
||||
return &BatchImageJobCreateBulk{err: fmt.Errorf("calling to BatchImageJobClient.MapCreateBulk with wrong type %T, need slice", slice)}
|
||||
}
|
||||
builders := make([]*BatchImageJobCreate, rv.Len())
|
||||
for i := 0; i < rv.Len(); i++ {
|
||||
builders[i] = c.Create()
|
||||
setFunc(builders[i], i)
|
||||
}
|
||||
return &BatchImageJobCreateBulk{config: c.config, builders: builders}
|
||||
}
|
||||
|
||||
// Update returns an update builder for BatchImageJob.
|
||||
func (c *BatchImageJobClient) Update() *BatchImageJobUpdate {
|
||||
mutation := newBatchImageJobMutation(c.config, OpUpdate)
|
||||
return &BatchImageJobUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// UpdateOne returns an update builder for the given entity.
|
||||
func (c *BatchImageJobClient) UpdateOne(_m *BatchImageJob) *BatchImageJobUpdateOne {
|
||||
mutation := newBatchImageJobMutation(c.config, OpUpdateOne, withBatchImageJob(_m))
|
||||
return &BatchImageJobUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// UpdateOneID returns an update builder for the given id.
|
||||
func (c *BatchImageJobClient) UpdateOneID(id int64) *BatchImageJobUpdateOne {
|
||||
mutation := newBatchImageJobMutation(c.config, OpUpdateOne, withBatchImageJobID(id))
|
||||
return &BatchImageJobUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// Delete returns a delete builder for BatchImageJob.
|
||||
func (c *BatchImageJobClient) Delete() *BatchImageJobDelete {
|
||||
mutation := newBatchImageJobMutation(c.config, OpDelete)
|
||||
return &BatchImageJobDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
|
||||
}
|
||||
|
||||
// DeleteOne returns a builder for deleting the given entity.
|
||||
func (c *BatchImageJobClient) DeleteOne(_m *BatchImageJob) *BatchImageJobDeleteOne {
|
||||
return c.DeleteOneID(_m.ID)
|
||||
}
|
||||
|
||||
// DeleteOneID returns a builder for deleting the given entity by its id.
|
||||
func (c *BatchImageJobClient) DeleteOneID(id int64) *BatchImageJobDeleteOne {
|
||||
builder := c.Delete().Where(batchimagejob.ID(id))
|
||||
builder.mutation.id = &id
|
||||
builder.mutation.op = OpDeleteOne
|
||||
return &BatchImageJobDeleteOne{builder}
|
||||
}
|
||||
|
||||
// Query returns a query builder for BatchImageJob.
|
||||
func (c *BatchImageJobClient) Query() *BatchImageJobQuery {
|
||||
return &BatchImageJobQuery{
|
||||
config: c.config,
|
||||
ctx: &QueryContext{Type: TypeBatchImageJob},
|
||||
inters: c.Interceptors(),
|
||||
}
|
||||
}
|
||||
|
||||
// Get returns a BatchImageJob entity by its id.
|
||||
func (c *BatchImageJobClient) Get(ctx context.Context, id int64) (*BatchImageJob, error) {
|
||||
return c.Query().Where(batchimagejob.ID(id)).Only(ctx)
|
||||
}
|
||||
|
||||
// GetX is like Get, but panics if an error occurs.
|
||||
func (c *BatchImageJobClient) GetX(ctx context.Context, id int64) *BatchImageJob {
|
||||
obj, err := c.Get(ctx, id)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
// Hooks returns the client hooks.
|
||||
func (c *BatchImageJobClient) Hooks() []Hook {
|
||||
return c.hooks.BatchImageJob
|
||||
}
|
||||
|
||||
// Interceptors returns the client interceptors.
|
||||
func (c *BatchImageJobClient) Interceptors() []Interceptor {
|
||||
return c.inters.BatchImageJob
|
||||
}
|
||||
|
||||
func (c *BatchImageJobClient) mutate(ctx context.Context, m *BatchImageJobMutation) (Value, error) {
|
||||
switch m.Op() {
|
||||
case OpCreate:
|
||||
return (&BatchImageJobCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
|
||||
case OpUpdate:
|
||||
return (&BatchImageJobUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
|
||||
case OpUpdateOne:
|
||||
return (&BatchImageJobUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
|
||||
case OpDelete, OpDeleteOne:
|
||||
return (&BatchImageJobDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
|
||||
default:
|
||||
return nil, fmt.Errorf("ent: unknown BatchImageJob mutation op: %q", m.Op())
|
||||
}
|
||||
}
|
||||
|
||||
// ChannelMonitorClient is a client for the ChannelMonitor schema.
|
||||
type ChannelMonitorClient struct {
|
||||
config
|
||||
@@ -6210,25 +6667,25 @@ func (c *UserSubscriptionClient) mutate(ctx context.Context, m *UserSubscription
|
||||
type (
|
||||
hooks struct {
|
||||
APIKey, Account, AccountGroup, Announcement, AnnouncementRead, AuthIdentity,
|
||||
AuthIdentityChannel, ChannelMonitor, ChannelMonitorDailyRollup,
|
||||
ChannelMonitorHistory, ChannelMonitorRequestTemplate, ErrorPassthroughRule,
|
||||
Group, IdempotencyRecord, IdentityAdoptionDecision, PaymentAuditLog,
|
||||
PaymentOrder, PaymentProviderInstance, PendingAuthSession, PromoCode,
|
||||
PromoCodeUsage, Proxy, RedeemCode, SecuritySecret, Setting, SubscriptionPlan,
|
||||
TLSFingerprintProfile, UsageCleanupTask, UsageLog, User, UserAllowedGroup,
|
||||
UserAttributeDefinition, UserAttributeValue, UserPlatformQuota,
|
||||
UserSubscription []ent.Hook
|
||||
AuthIdentityChannel, BatchImageEvent, BatchImageItem, BatchImageJob,
|
||||
ChannelMonitor, ChannelMonitorDailyRollup, ChannelMonitorHistory,
|
||||
ChannelMonitorRequestTemplate, ErrorPassthroughRule, Group, IdempotencyRecord,
|
||||
IdentityAdoptionDecision, PaymentAuditLog, PaymentOrder,
|
||||
PaymentProviderInstance, PendingAuthSession, PromoCode, PromoCodeUsage, Proxy,
|
||||
RedeemCode, SecuritySecret, Setting, SubscriptionPlan, TLSFingerprintProfile,
|
||||
UsageCleanupTask, UsageLog, User, UserAllowedGroup, UserAttributeDefinition,
|
||||
UserAttributeValue, UserPlatformQuota, UserSubscription []ent.Hook
|
||||
}
|
||||
inters struct {
|
||||
APIKey, Account, AccountGroup, Announcement, AnnouncementRead, AuthIdentity,
|
||||
AuthIdentityChannel, ChannelMonitor, ChannelMonitorDailyRollup,
|
||||
ChannelMonitorHistory, ChannelMonitorRequestTemplate, ErrorPassthroughRule,
|
||||
Group, IdempotencyRecord, IdentityAdoptionDecision, PaymentAuditLog,
|
||||
PaymentOrder, PaymentProviderInstance, PendingAuthSession, PromoCode,
|
||||
PromoCodeUsage, Proxy, RedeemCode, SecuritySecret, Setting, SubscriptionPlan,
|
||||
TLSFingerprintProfile, UsageCleanupTask, UsageLog, User, UserAllowedGroup,
|
||||
UserAttributeDefinition, UserAttributeValue, UserPlatformQuota,
|
||||
UserSubscription []ent.Interceptor
|
||||
AuthIdentityChannel, BatchImageEvent, BatchImageItem, BatchImageJob,
|
||||
ChannelMonitor, ChannelMonitorDailyRollup, ChannelMonitorHistory,
|
||||
ChannelMonitorRequestTemplate, ErrorPassthroughRule, Group, IdempotencyRecord,
|
||||
IdentityAdoptionDecision, PaymentAuditLog, PaymentOrder,
|
||||
PaymentProviderInstance, PendingAuthSession, PromoCode, PromoCodeUsage, Proxy,
|
||||
RedeemCode, SecuritySecret, Setting, SubscriptionPlan, TLSFingerprintProfile,
|
||||
UsageCleanupTask, UsageLog, User, UserAllowedGroup, UserAttributeDefinition,
|
||||
UserAttributeValue, UserPlatformQuota, UserSubscription []ent.Interceptor
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@ import (
|
||||
"github.com/Wei-Shaw/sub2api/ent/apikey"
|
||||
"github.com/Wei-Shaw/sub2api/ent/authidentity"
|
||||
"github.com/Wei-Shaw/sub2api/ent/authidentitychannel"
|
||||
"github.com/Wei-Shaw/sub2api/ent/batchimageevent"
|
||||
"github.com/Wei-Shaw/sub2api/ent/batchimageitem"
|
||||
"github.com/Wei-Shaw/sub2api/ent/batchimagejob"
|
||||
"github.com/Wei-Shaw/sub2api/ent/channelmonitor"
|
||||
"github.com/Wei-Shaw/sub2api/ent/channelmonitordailyrollup"
|
||||
"github.com/Wei-Shaw/sub2api/ent/channelmonitorhistory"
|
||||
@@ -114,6 +117,9 @@ func checkColumn(t, c string) error {
|
||||
announcementread.Table: announcementread.ValidColumn,
|
||||
authidentity.Table: authidentity.ValidColumn,
|
||||
authidentitychannel.Table: authidentitychannel.ValidColumn,
|
||||
batchimageevent.Table: batchimageevent.ValidColumn,
|
||||
batchimageitem.Table: batchimageitem.ValidColumn,
|
||||
batchimagejob.Table: batchimagejob.ValidColumn,
|
||||
channelmonitor.Table: channelmonitor.ValidColumn,
|
||||
channelmonitordailyrollup.Table: channelmonitordailyrollup.ValidColumn,
|
||||
channelmonitorhistory.Table: channelmonitorhistory.ValidColumn,
|
||||
|
||||
+158
-3
@@ -31,6 +31,14 @@ type Group struct {
|
||||
Description *string `json:"description,omitempty"`
|
||||
// RateMultiplier holds the value of the "rate_multiplier" field.
|
||||
RateMultiplier float64 `json:"rate_multiplier,omitempty"`
|
||||
// 是否启用高峰时段倍率
|
||||
PeakRateEnabled bool `json:"peak_rate_enabled,omitempty"`
|
||||
// 高峰开始时间 HH:MM(含),如 14:00;空表示未配置;不支持跨天
|
||||
PeakStart string `json:"peak_start,omitempty"`
|
||||
// 高峰结束时间 HH:MM(不含),必须大于 peak_start;不支持跨天,如 22:00-02:00
|
||||
PeakEnd string `json:"peak_end,omitempty"`
|
||||
// 高峰时段叠加倍率,仅在 peak_rate_enabled 且处于 [peak_start, peak_end) 时乘入文本倍率
|
||||
PeakRateMultiplier float64 `json:"peak_rate_multiplier,omitempty"`
|
||||
// IsExclusive holds the value of the "is_exclusive" field.
|
||||
IsExclusive bool `json:"is_exclusive,omitempty"`
|
||||
// Status holds the value of the "status" field.
|
||||
@@ -49,6 +57,8 @@ type Group struct {
|
||||
DefaultValidityDays int `json:"default_validity_days,omitempty"`
|
||||
// 是否允许该分组使用图片生成能力
|
||||
AllowImageGeneration bool `json:"allow_image_generation,omitempty"`
|
||||
// 是否允许该分组使用批量图片生成能力
|
||||
AllowBatchImageGeneration bool `json:"allow_batch_image_generation,omitempty"`
|
||||
// 图片生成是否使用独立倍率;false 表示共享分组有效倍率
|
||||
ImageRateIndependent bool `json:"image_rate_independent,omitempty"`
|
||||
// 图片生成独立倍率,仅 image_rate_independent=true 时生效
|
||||
@@ -59,6 +69,22 @@ type Group struct {
|
||||
ImagePrice2k *float64 `json:"image_price_2k,omitempty"`
|
||||
// ImagePrice4k holds the value of the "image_price_4k" field.
|
||||
ImagePrice4k *float64 `json:"image_price_4k,omitempty"`
|
||||
// 批量图片生成折扣倍率,最终单价会乘以该值;0 表示免费
|
||||
BatchImageDiscountMultiplier float64 `json:"batch_image_discount_multiplier,omitempty"`
|
||||
// 批量图片生成冻结价格比例,按普通生图原价乘以该比例冻结,结算后释放差额
|
||||
BatchImageHoldMultiplier float64 `json:"batch_image_hold_multiplier,omitempty"`
|
||||
// 视频生成是否使用独立倍率;false 表示共享分组有效倍率
|
||||
VideoRateIndependent bool `json:"video_rate_independent,omitempty"`
|
||||
// 视频生成独立倍率,仅 video_rate_independent=true 时生效
|
||||
VideoRateMultiplier float64 `json:"video_rate_multiplier,omitempty"`
|
||||
// VideoPrice480p holds the value of the "video_price_480p" field.
|
||||
VideoPrice480p *float64 `json:"video_price_480p,omitempty"`
|
||||
// VideoPrice720p holds the value of the "video_price_720p" field.
|
||||
VideoPrice720p *float64 `json:"video_price_720p,omitempty"`
|
||||
// VideoPrice1080p holds the value of the "video_price_1080p" field.
|
||||
VideoPrice1080p *float64 `json:"video_price_1080p,omitempty"`
|
||||
// Codex alpha/search 网页搜索单次价格(USD/次);nil 表示使用默认价 0.01(官方 $10/1000 次)
|
||||
WebSearchPricePerCall *float64 `json:"web_search_price_per_call,omitempty"`
|
||||
// 是否仅允许 Claude Code 客户端
|
||||
ClaudeCodeOnly bool `json:"claude_code_only,omitempty"`
|
||||
// 非 Claude Code 请求降级使用的分组 ID
|
||||
@@ -197,13 +223,13 @@ func (*Group) scanValues(columns []string) ([]any, error) {
|
||||
switch columns[i] {
|
||||
case group.FieldModelRouting, group.FieldSupportedModelScopes, group.FieldMessagesDispatchModelConfig, group.FieldModelsListConfig:
|
||||
values[i] = new([]byte)
|
||||
case group.FieldIsExclusive, group.FieldAllowImageGeneration, group.FieldImageRateIndependent, group.FieldClaudeCodeOnly, group.FieldModelRoutingEnabled, group.FieldMcpXMLInject, group.FieldAllowMessagesDispatch, group.FieldRequireOauthOnly, group.FieldRequirePrivacySet:
|
||||
case group.FieldPeakRateEnabled, group.FieldIsExclusive, group.FieldAllowImageGeneration, group.FieldAllowBatchImageGeneration, group.FieldImageRateIndependent, group.FieldVideoRateIndependent, group.FieldClaudeCodeOnly, group.FieldModelRoutingEnabled, group.FieldMcpXMLInject, group.FieldAllowMessagesDispatch, group.FieldRequireOauthOnly, group.FieldRequirePrivacySet:
|
||||
values[i] = new(sql.NullBool)
|
||||
case group.FieldRateMultiplier, group.FieldDailyLimitUsd, group.FieldWeeklyLimitUsd, group.FieldMonthlyLimitUsd, group.FieldImageRateMultiplier, group.FieldImagePrice1k, group.FieldImagePrice2k, group.FieldImagePrice4k:
|
||||
case group.FieldRateMultiplier, group.FieldPeakRateMultiplier, group.FieldDailyLimitUsd, group.FieldWeeklyLimitUsd, group.FieldMonthlyLimitUsd, group.FieldImageRateMultiplier, group.FieldImagePrice1k, group.FieldImagePrice2k, group.FieldImagePrice4k, group.FieldBatchImageDiscountMultiplier, group.FieldBatchImageHoldMultiplier, group.FieldVideoRateMultiplier, group.FieldVideoPrice480p, group.FieldVideoPrice720p, group.FieldVideoPrice1080p, group.FieldWebSearchPricePerCall:
|
||||
values[i] = new(sql.NullFloat64)
|
||||
case group.FieldID, group.FieldDefaultValidityDays, group.FieldFallbackGroupID, group.FieldFallbackGroupIDOnInvalidRequest, group.FieldSortOrder, group.FieldRpmLimit:
|
||||
values[i] = new(sql.NullInt64)
|
||||
case group.FieldName, group.FieldDescription, group.FieldStatus, group.FieldPlatform, group.FieldSubscriptionType, group.FieldDefaultMappedModel:
|
||||
case group.FieldName, group.FieldDescription, group.FieldPeakStart, group.FieldPeakEnd, group.FieldStatus, group.FieldPlatform, group.FieldSubscriptionType, group.FieldDefaultMappedModel:
|
||||
values[i] = new(sql.NullString)
|
||||
case group.FieldCreatedAt, group.FieldUpdatedAt, group.FieldDeletedAt:
|
||||
values[i] = new(sql.NullTime)
|
||||
@@ -266,6 +292,30 @@ func (_m *Group) assignValues(columns []string, values []any) error {
|
||||
} else if value.Valid {
|
||||
_m.RateMultiplier = value.Float64
|
||||
}
|
||||
case group.FieldPeakRateEnabled:
|
||||
if value, ok := values[i].(*sql.NullBool); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field peak_rate_enabled", values[i])
|
||||
} else if value.Valid {
|
||||
_m.PeakRateEnabled = value.Bool
|
||||
}
|
||||
case group.FieldPeakStart:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field peak_start", values[i])
|
||||
} else if value.Valid {
|
||||
_m.PeakStart = value.String
|
||||
}
|
||||
case group.FieldPeakEnd:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field peak_end", values[i])
|
||||
} else if value.Valid {
|
||||
_m.PeakEnd = value.String
|
||||
}
|
||||
case group.FieldPeakRateMultiplier:
|
||||
if value, ok := values[i].(*sql.NullFloat64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field peak_rate_multiplier", values[i])
|
||||
} else if value.Valid {
|
||||
_m.PeakRateMultiplier = value.Float64
|
||||
}
|
||||
case group.FieldIsExclusive:
|
||||
if value, ok := values[i].(*sql.NullBool); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field is_exclusive", values[i])
|
||||
@@ -323,6 +373,12 @@ func (_m *Group) assignValues(columns []string, values []any) error {
|
||||
} else if value.Valid {
|
||||
_m.AllowImageGeneration = value.Bool
|
||||
}
|
||||
case group.FieldAllowBatchImageGeneration:
|
||||
if value, ok := values[i].(*sql.NullBool); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field allow_batch_image_generation", values[i])
|
||||
} else if value.Valid {
|
||||
_m.AllowBatchImageGeneration = value.Bool
|
||||
}
|
||||
case group.FieldImageRateIndependent:
|
||||
if value, ok := values[i].(*sql.NullBool); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field image_rate_independent", values[i])
|
||||
@@ -356,6 +412,58 @@ func (_m *Group) assignValues(columns []string, values []any) error {
|
||||
_m.ImagePrice4k = new(float64)
|
||||
*_m.ImagePrice4k = value.Float64
|
||||
}
|
||||
case group.FieldBatchImageDiscountMultiplier:
|
||||
if value, ok := values[i].(*sql.NullFloat64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field batch_image_discount_multiplier", values[i])
|
||||
} else if value.Valid {
|
||||
_m.BatchImageDiscountMultiplier = value.Float64
|
||||
}
|
||||
case group.FieldBatchImageHoldMultiplier:
|
||||
if value, ok := values[i].(*sql.NullFloat64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field batch_image_hold_multiplier", values[i])
|
||||
} else if value.Valid {
|
||||
_m.BatchImageHoldMultiplier = value.Float64
|
||||
}
|
||||
case group.FieldVideoRateIndependent:
|
||||
if value, ok := values[i].(*sql.NullBool); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field video_rate_independent", values[i])
|
||||
} else if value.Valid {
|
||||
_m.VideoRateIndependent = value.Bool
|
||||
}
|
||||
case group.FieldVideoRateMultiplier:
|
||||
if value, ok := values[i].(*sql.NullFloat64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field video_rate_multiplier", values[i])
|
||||
} else if value.Valid {
|
||||
_m.VideoRateMultiplier = value.Float64
|
||||
}
|
||||
case group.FieldVideoPrice480p:
|
||||
if value, ok := values[i].(*sql.NullFloat64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field video_price_480p", values[i])
|
||||
} else if value.Valid {
|
||||
_m.VideoPrice480p = new(float64)
|
||||
*_m.VideoPrice480p = value.Float64
|
||||
}
|
||||
case group.FieldVideoPrice720p:
|
||||
if value, ok := values[i].(*sql.NullFloat64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field video_price_720p", values[i])
|
||||
} else if value.Valid {
|
||||
_m.VideoPrice720p = new(float64)
|
||||
*_m.VideoPrice720p = value.Float64
|
||||
}
|
||||
case group.FieldVideoPrice1080p:
|
||||
if value, ok := values[i].(*sql.NullFloat64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field video_price_1080p", values[i])
|
||||
} else if value.Valid {
|
||||
_m.VideoPrice1080p = new(float64)
|
||||
*_m.VideoPrice1080p = value.Float64
|
||||
}
|
||||
case group.FieldWebSearchPricePerCall:
|
||||
if value, ok := values[i].(*sql.NullFloat64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field web_search_price_per_call", values[i])
|
||||
} else if value.Valid {
|
||||
_m.WebSearchPricePerCall = new(float64)
|
||||
*_m.WebSearchPricePerCall = value.Float64
|
||||
}
|
||||
case group.FieldClaudeCodeOnly:
|
||||
if value, ok := values[i].(*sql.NullBool); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field claude_code_only", values[i])
|
||||
@@ -554,6 +662,18 @@ func (_m *Group) String() string {
|
||||
builder.WriteString("rate_multiplier=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.RateMultiplier))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("peak_rate_enabled=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.PeakRateEnabled))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("peak_start=")
|
||||
builder.WriteString(_m.PeakStart)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("peak_end=")
|
||||
builder.WriteString(_m.PeakEnd)
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("peak_rate_multiplier=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.PeakRateMultiplier))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("is_exclusive=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.IsExclusive))
|
||||
builder.WriteString(", ")
|
||||
@@ -587,6 +707,9 @@ func (_m *Group) String() string {
|
||||
builder.WriteString("allow_image_generation=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.AllowImageGeneration))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("allow_batch_image_generation=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.AllowBatchImageGeneration))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("image_rate_independent=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.ImageRateIndependent))
|
||||
builder.WriteString(", ")
|
||||
@@ -608,6 +731,38 @@ func (_m *Group) String() string {
|
||||
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("batch_image_discount_multiplier=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.BatchImageDiscountMultiplier))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("batch_image_hold_multiplier=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.BatchImageHoldMultiplier))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("video_rate_independent=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.VideoRateIndependent))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("video_rate_multiplier=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.VideoRateMultiplier))
|
||||
builder.WriteString(", ")
|
||||
if v := _m.VideoPrice480p; v != nil {
|
||||
builder.WriteString("video_price_480p=")
|
||||
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.VideoPrice720p; v != nil {
|
||||
builder.WriteString("video_price_720p=")
|
||||
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.VideoPrice1080p; v != nil {
|
||||
builder.WriteString("video_price_1080p=")
|
||||
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.WebSearchPricePerCall; v != nil {
|
||||
builder.WriteString("web_search_price_per_call=")
|
||||
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("claude_code_only=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.ClaudeCodeOnly))
|
||||
builder.WriteString(", ")
|
||||
|
||||
@@ -28,6 +28,14 @@ const (
|
||||
FieldDescription = "description"
|
||||
// FieldRateMultiplier holds the string denoting the rate_multiplier field in the database.
|
||||
FieldRateMultiplier = "rate_multiplier"
|
||||
// FieldPeakRateEnabled holds the string denoting the peak_rate_enabled field in the database.
|
||||
FieldPeakRateEnabled = "peak_rate_enabled"
|
||||
// FieldPeakStart holds the string denoting the peak_start field in the database.
|
||||
FieldPeakStart = "peak_start"
|
||||
// FieldPeakEnd holds the string denoting the peak_end field in the database.
|
||||
FieldPeakEnd = "peak_end"
|
||||
// FieldPeakRateMultiplier holds the string denoting the peak_rate_multiplier field in the database.
|
||||
FieldPeakRateMultiplier = "peak_rate_multiplier"
|
||||
// FieldIsExclusive holds the string denoting the is_exclusive field in the database.
|
||||
FieldIsExclusive = "is_exclusive"
|
||||
// FieldStatus holds the string denoting the status field in the database.
|
||||
@@ -46,6 +54,8 @@ const (
|
||||
FieldDefaultValidityDays = "default_validity_days"
|
||||
// FieldAllowImageGeneration holds the string denoting the allow_image_generation field in the database.
|
||||
FieldAllowImageGeneration = "allow_image_generation"
|
||||
// FieldAllowBatchImageGeneration holds the string denoting the allow_batch_image_generation field in the database.
|
||||
FieldAllowBatchImageGeneration = "allow_batch_image_generation"
|
||||
// FieldImageRateIndependent holds the string denoting the image_rate_independent field in the database.
|
||||
FieldImageRateIndependent = "image_rate_independent"
|
||||
// FieldImageRateMultiplier holds the string denoting the image_rate_multiplier field in the database.
|
||||
@@ -56,6 +66,22 @@ const (
|
||||
FieldImagePrice2k = "image_price_2k"
|
||||
// FieldImagePrice4k holds the string denoting the image_price_4k field in the database.
|
||||
FieldImagePrice4k = "image_price_4k"
|
||||
// FieldBatchImageDiscountMultiplier holds the string denoting the batch_image_discount_multiplier field in the database.
|
||||
FieldBatchImageDiscountMultiplier = "batch_image_discount_multiplier"
|
||||
// FieldBatchImageHoldMultiplier holds the string denoting the batch_image_hold_multiplier field in the database.
|
||||
FieldBatchImageHoldMultiplier = "batch_image_hold_multiplier"
|
||||
// FieldVideoRateIndependent holds the string denoting the video_rate_independent field in the database.
|
||||
FieldVideoRateIndependent = "video_rate_independent"
|
||||
// FieldVideoRateMultiplier holds the string denoting the video_rate_multiplier field in the database.
|
||||
FieldVideoRateMultiplier = "video_rate_multiplier"
|
||||
// FieldVideoPrice480p holds the string denoting the video_price_480p field in the database.
|
||||
FieldVideoPrice480p = "video_price_480p"
|
||||
// FieldVideoPrice720p holds the string denoting the video_price_720p field in the database.
|
||||
FieldVideoPrice720p = "video_price_720p"
|
||||
// FieldVideoPrice1080p holds the string denoting the video_price_1080p field in the database.
|
||||
FieldVideoPrice1080p = "video_price_1080p"
|
||||
// FieldWebSearchPricePerCall holds the string denoting the web_search_price_per_call field in the database.
|
||||
FieldWebSearchPricePerCall = "web_search_price_per_call"
|
||||
// FieldClaudeCodeOnly holds the string denoting the claude_code_only field in the database.
|
||||
FieldClaudeCodeOnly = "claude_code_only"
|
||||
// FieldFallbackGroupID holds the string denoting the fallback_group_id field in the database.
|
||||
@@ -167,6 +193,10 @@ var Columns = []string{
|
||||
FieldName,
|
||||
FieldDescription,
|
||||
FieldRateMultiplier,
|
||||
FieldPeakRateEnabled,
|
||||
FieldPeakStart,
|
||||
FieldPeakEnd,
|
||||
FieldPeakRateMultiplier,
|
||||
FieldIsExclusive,
|
||||
FieldStatus,
|
||||
FieldPlatform,
|
||||
@@ -176,11 +206,20 @@ var Columns = []string{
|
||||
FieldMonthlyLimitUsd,
|
||||
FieldDefaultValidityDays,
|
||||
FieldAllowImageGeneration,
|
||||
FieldAllowBatchImageGeneration,
|
||||
FieldImageRateIndependent,
|
||||
FieldImageRateMultiplier,
|
||||
FieldImagePrice1k,
|
||||
FieldImagePrice2k,
|
||||
FieldImagePrice4k,
|
||||
FieldBatchImageDiscountMultiplier,
|
||||
FieldBatchImageHoldMultiplier,
|
||||
FieldVideoRateIndependent,
|
||||
FieldVideoRateMultiplier,
|
||||
FieldVideoPrice480p,
|
||||
FieldVideoPrice720p,
|
||||
FieldVideoPrice1080p,
|
||||
FieldWebSearchPricePerCall,
|
||||
FieldClaudeCodeOnly,
|
||||
FieldFallbackGroupID,
|
||||
FieldFallbackGroupIDOnInvalidRequest,
|
||||
@@ -235,6 +274,18 @@ var (
|
||||
NameValidator func(string) error
|
||||
// DefaultRateMultiplier holds the default value on creation for the "rate_multiplier" field.
|
||||
DefaultRateMultiplier float64
|
||||
// DefaultPeakRateEnabled holds the default value on creation for the "peak_rate_enabled" field.
|
||||
DefaultPeakRateEnabled bool
|
||||
// DefaultPeakStart holds the default value on creation for the "peak_start" field.
|
||||
DefaultPeakStart string
|
||||
// PeakStartValidator is a validator for the "peak_start" field. It is called by the builders before save.
|
||||
PeakStartValidator func(string) error
|
||||
// DefaultPeakEnd holds the default value on creation for the "peak_end" field.
|
||||
DefaultPeakEnd string
|
||||
// PeakEndValidator is a validator for the "peak_end" field. It is called by the builders before save.
|
||||
PeakEndValidator func(string) error
|
||||
// DefaultPeakRateMultiplier holds the default value on creation for the "peak_rate_multiplier" field.
|
||||
DefaultPeakRateMultiplier float64
|
||||
// DefaultIsExclusive holds the default value on creation for the "is_exclusive" field.
|
||||
DefaultIsExclusive bool
|
||||
// DefaultStatus holds the default value on creation for the "status" field.
|
||||
@@ -253,10 +304,20 @@ var (
|
||||
DefaultDefaultValidityDays int
|
||||
// DefaultAllowImageGeneration holds the default value on creation for the "allow_image_generation" field.
|
||||
DefaultAllowImageGeneration bool
|
||||
// DefaultAllowBatchImageGeneration holds the default value on creation for the "allow_batch_image_generation" field.
|
||||
DefaultAllowBatchImageGeneration bool
|
||||
// DefaultImageRateIndependent holds the default value on creation for the "image_rate_independent" field.
|
||||
DefaultImageRateIndependent bool
|
||||
// DefaultImageRateMultiplier holds the default value on creation for the "image_rate_multiplier" field.
|
||||
DefaultImageRateMultiplier float64
|
||||
// DefaultBatchImageDiscountMultiplier holds the default value on creation for the "batch_image_discount_multiplier" field.
|
||||
DefaultBatchImageDiscountMultiplier float64
|
||||
// DefaultBatchImageHoldMultiplier holds the default value on creation for the "batch_image_hold_multiplier" field.
|
||||
DefaultBatchImageHoldMultiplier float64
|
||||
// DefaultVideoRateIndependent holds the default value on creation for the "video_rate_independent" field.
|
||||
DefaultVideoRateIndependent bool
|
||||
// DefaultVideoRateMultiplier holds the default value on creation for the "video_rate_multiplier" field.
|
||||
DefaultVideoRateMultiplier float64
|
||||
// DefaultClaudeCodeOnly holds the default value on creation for the "claude_code_only" field.
|
||||
DefaultClaudeCodeOnly bool
|
||||
// DefaultModelRoutingEnabled holds the default value on creation for the "model_routing_enabled" field.
|
||||
@@ -323,6 +384,26 @@ func ByRateMultiplier(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldRateMultiplier, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByPeakRateEnabled orders the results by the peak_rate_enabled field.
|
||||
func ByPeakRateEnabled(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldPeakRateEnabled, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByPeakStart orders the results by the peak_start field.
|
||||
func ByPeakStart(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldPeakStart, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByPeakEnd orders the results by the peak_end field.
|
||||
func ByPeakEnd(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldPeakEnd, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByPeakRateMultiplier orders the results by the peak_rate_multiplier field.
|
||||
func ByPeakRateMultiplier(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldPeakRateMultiplier, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByIsExclusive orders the results by the is_exclusive field.
|
||||
func ByIsExclusive(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldIsExclusive, opts...).ToFunc()
|
||||
@@ -368,6 +449,11 @@ func ByAllowImageGeneration(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldAllowImageGeneration, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByAllowBatchImageGeneration orders the results by the allow_batch_image_generation field.
|
||||
func ByAllowBatchImageGeneration(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldAllowBatchImageGeneration, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByImageRateIndependent orders the results by the image_rate_independent field.
|
||||
func ByImageRateIndependent(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldImageRateIndependent, opts...).ToFunc()
|
||||
@@ -393,6 +479,46 @@ func ByImagePrice4k(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldImagePrice4k, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByBatchImageDiscountMultiplier orders the results by the batch_image_discount_multiplier field.
|
||||
func ByBatchImageDiscountMultiplier(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldBatchImageDiscountMultiplier, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByBatchImageHoldMultiplier orders the results by the batch_image_hold_multiplier field.
|
||||
func ByBatchImageHoldMultiplier(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldBatchImageHoldMultiplier, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByVideoRateIndependent orders the results by the video_rate_independent field.
|
||||
func ByVideoRateIndependent(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldVideoRateIndependent, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByVideoRateMultiplier orders the results by the video_rate_multiplier field.
|
||||
func ByVideoRateMultiplier(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldVideoRateMultiplier, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByVideoPrice480p orders the results by the video_price_480p field.
|
||||
func ByVideoPrice480p(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldVideoPrice480p, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByVideoPrice720p orders the results by the video_price_720p field.
|
||||
func ByVideoPrice720p(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldVideoPrice720p, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByVideoPrice1080p orders the results by the video_price_1080p field.
|
||||
func ByVideoPrice1080p(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldVideoPrice1080p, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByWebSearchPricePerCall orders the results by the web_search_price_per_call field.
|
||||
func ByWebSearchPricePerCall(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldWebSearchPricePerCall, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByClaudeCodeOnly orders the results by the claude_code_only field.
|
||||
func ByClaudeCodeOnly(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldClaudeCodeOnly, opts...).ToFunc()
|
||||
|
||||
@@ -85,6 +85,26 @@ func RateMultiplier(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldRateMultiplier, v))
|
||||
}
|
||||
|
||||
// PeakRateEnabled applies equality check predicate on the "peak_rate_enabled" field. It's identical to PeakRateEnabledEQ.
|
||||
func PeakRateEnabled(v bool) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldPeakRateEnabled, v))
|
||||
}
|
||||
|
||||
// PeakStart applies equality check predicate on the "peak_start" field. It's identical to PeakStartEQ.
|
||||
func PeakStart(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldPeakStart, v))
|
||||
}
|
||||
|
||||
// PeakEnd applies equality check predicate on the "peak_end" field. It's identical to PeakEndEQ.
|
||||
func PeakEnd(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldPeakEnd, v))
|
||||
}
|
||||
|
||||
// PeakRateMultiplier applies equality check predicate on the "peak_rate_multiplier" field. It's identical to PeakRateMultiplierEQ.
|
||||
func PeakRateMultiplier(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldPeakRateMultiplier, v))
|
||||
}
|
||||
|
||||
// IsExclusive applies equality check predicate on the "is_exclusive" field. It's identical to IsExclusiveEQ.
|
||||
func IsExclusive(v bool) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldIsExclusive, v))
|
||||
@@ -130,6 +150,11 @@ func AllowImageGeneration(v bool) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldAllowImageGeneration, v))
|
||||
}
|
||||
|
||||
// AllowBatchImageGeneration applies equality check predicate on the "allow_batch_image_generation" field. It's identical to AllowBatchImageGenerationEQ.
|
||||
func AllowBatchImageGeneration(v bool) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldAllowBatchImageGeneration, v))
|
||||
}
|
||||
|
||||
// ImageRateIndependent applies equality check predicate on the "image_rate_independent" field. It's identical to ImageRateIndependentEQ.
|
||||
func ImageRateIndependent(v bool) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldImageRateIndependent, v))
|
||||
@@ -155,6 +180,46 @@ func ImagePrice4k(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldImagePrice4k, v))
|
||||
}
|
||||
|
||||
// BatchImageDiscountMultiplier applies equality check predicate on the "batch_image_discount_multiplier" field. It's identical to BatchImageDiscountMultiplierEQ.
|
||||
func BatchImageDiscountMultiplier(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldBatchImageDiscountMultiplier, v))
|
||||
}
|
||||
|
||||
// BatchImageHoldMultiplier applies equality check predicate on the "batch_image_hold_multiplier" field. It's identical to BatchImageHoldMultiplierEQ.
|
||||
func BatchImageHoldMultiplier(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldBatchImageHoldMultiplier, v))
|
||||
}
|
||||
|
||||
// VideoRateIndependent applies equality check predicate on the "video_rate_independent" field. It's identical to VideoRateIndependentEQ.
|
||||
func VideoRateIndependent(v bool) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldVideoRateIndependent, v))
|
||||
}
|
||||
|
||||
// VideoRateMultiplier applies equality check predicate on the "video_rate_multiplier" field. It's identical to VideoRateMultiplierEQ.
|
||||
func VideoRateMultiplier(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldVideoRateMultiplier, v))
|
||||
}
|
||||
|
||||
// VideoPrice480p applies equality check predicate on the "video_price_480p" field. It's identical to VideoPrice480pEQ.
|
||||
func VideoPrice480p(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldVideoPrice480p, v))
|
||||
}
|
||||
|
||||
// VideoPrice720p applies equality check predicate on the "video_price_720p" field. It's identical to VideoPrice720pEQ.
|
||||
func VideoPrice720p(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldVideoPrice720p, v))
|
||||
}
|
||||
|
||||
// VideoPrice1080p applies equality check predicate on the "video_price_1080p" field. It's identical to VideoPrice1080pEQ.
|
||||
func VideoPrice1080p(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldVideoPrice1080p, v))
|
||||
}
|
||||
|
||||
// WebSearchPricePerCall applies equality check predicate on the "web_search_price_per_call" field. It's identical to WebSearchPricePerCallEQ.
|
||||
func WebSearchPricePerCall(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldWebSearchPricePerCall, v))
|
||||
}
|
||||
|
||||
// ClaudeCodeOnly applies equality check predicate on the "claude_code_only" field. It's identical to ClaudeCodeOnlyEQ.
|
||||
func ClaudeCodeOnly(v bool) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldClaudeCodeOnly, v))
|
||||
@@ -520,6 +585,186 @@ func RateMultiplierLTE(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldLTE(FieldRateMultiplier, v))
|
||||
}
|
||||
|
||||
// PeakRateEnabledEQ applies the EQ predicate on the "peak_rate_enabled" field.
|
||||
func PeakRateEnabledEQ(v bool) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldPeakRateEnabled, v))
|
||||
}
|
||||
|
||||
// PeakRateEnabledNEQ applies the NEQ predicate on the "peak_rate_enabled" field.
|
||||
func PeakRateEnabledNEQ(v bool) predicate.Group {
|
||||
return predicate.Group(sql.FieldNEQ(FieldPeakRateEnabled, v))
|
||||
}
|
||||
|
||||
// PeakStartEQ applies the EQ predicate on the "peak_start" field.
|
||||
func PeakStartEQ(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldPeakStart, v))
|
||||
}
|
||||
|
||||
// PeakStartNEQ applies the NEQ predicate on the "peak_start" field.
|
||||
func PeakStartNEQ(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldNEQ(FieldPeakStart, v))
|
||||
}
|
||||
|
||||
// PeakStartIn applies the In predicate on the "peak_start" field.
|
||||
func PeakStartIn(vs ...string) predicate.Group {
|
||||
return predicate.Group(sql.FieldIn(FieldPeakStart, vs...))
|
||||
}
|
||||
|
||||
// PeakStartNotIn applies the NotIn predicate on the "peak_start" field.
|
||||
func PeakStartNotIn(vs ...string) predicate.Group {
|
||||
return predicate.Group(sql.FieldNotIn(FieldPeakStart, vs...))
|
||||
}
|
||||
|
||||
// PeakStartGT applies the GT predicate on the "peak_start" field.
|
||||
func PeakStartGT(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldGT(FieldPeakStart, v))
|
||||
}
|
||||
|
||||
// PeakStartGTE applies the GTE predicate on the "peak_start" field.
|
||||
func PeakStartGTE(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldGTE(FieldPeakStart, v))
|
||||
}
|
||||
|
||||
// PeakStartLT applies the LT predicate on the "peak_start" field.
|
||||
func PeakStartLT(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldLT(FieldPeakStart, v))
|
||||
}
|
||||
|
||||
// PeakStartLTE applies the LTE predicate on the "peak_start" field.
|
||||
func PeakStartLTE(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldLTE(FieldPeakStart, v))
|
||||
}
|
||||
|
||||
// PeakStartContains applies the Contains predicate on the "peak_start" field.
|
||||
func PeakStartContains(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldContains(FieldPeakStart, v))
|
||||
}
|
||||
|
||||
// PeakStartHasPrefix applies the HasPrefix predicate on the "peak_start" field.
|
||||
func PeakStartHasPrefix(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldHasPrefix(FieldPeakStart, v))
|
||||
}
|
||||
|
||||
// PeakStartHasSuffix applies the HasSuffix predicate on the "peak_start" field.
|
||||
func PeakStartHasSuffix(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldHasSuffix(FieldPeakStart, v))
|
||||
}
|
||||
|
||||
// PeakStartEqualFold applies the EqualFold predicate on the "peak_start" field.
|
||||
func PeakStartEqualFold(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldEqualFold(FieldPeakStart, v))
|
||||
}
|
||||
|
||||
// PeakStartContainsFold applies the ContainsFold predicate on the "peak_start" field.
|
||||
func PeakStartContainsFold(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldContainsFold(FieldPeakStart, v))
|
||||
}
|
||||
|
||||
// PeakEndEQ applies the EQ predicate on the "peak_end" field.
|
||||
func PeakEndEQ(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldPeakEnd, v))
|
||||
}
|
||||
|
||||
// PeakEndNEQ applies the NEQ predicate on the "peak_end" field.
|
||||
func PeakEndNEQ(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldNEQ(FieldPeakEnd, v))
|
||||
}
|
||||
|
||||
// PeakEndIn applies the In predicate on the "peak_end" field.
|
||||
func PeakEndIn(vs ...string) predicate.Group {
|
||||
return predicate.Group(sql.FieldIn(FieldPeakEnd, vs...))
|
||||
}
|
||||
|
||||
// PeakEndNotIn applies the NotIn predicate on the "peak_end" field.
|
||||
func PeakEndNotIn(vs ...string) predicate.Group {
|
||||
return predicate.Group(sql.FieldNotIn(FieldPeakEnd, vs...))
|
||||
}
|
||||
|
||||
// PeakEndGT applies the GT predicate on the "peak_end" field.
|
||||
func PeakEndGT(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldGT(FieldPeakEnd, v))
|
||||
}
|
||||
|
||||
// PeakEndGTE applies the GTE predicate on the "peak_end" field.
|
||||
func PeakEndGTE(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldGTE(FieldPeakEnd, v))
|
||||
}
|
||||
|
||||
// PeakEndLT applies the LT predicate on the "peak_end" field.
|
||||
func PeakEndLT(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldLT(FieldPeakEnd, v))
|
||||
}
|
||||
|
||||
// PeakEndLTE applies the LTE predicate on the "peak_end" field.
|
||||
func PeakEndLTE(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldLTE(FieldPeakEnd, v))
|
||||
}
|
||||
|
||||
// PeakEndContains applies the Contains predicate on the "peak_end" field.
|
||||
func PeakEndContains(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldContains(FieldPeakEnd, v))
|
||||
}
|
||||
|
||||
// PeakEndHasPrefix applies the HasPrefix predicate on the "peak_end" field.
|
||||
func PeakEndHasPrefix(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldHasPrefix(FieldPeakEnd, v))
|
||||
}
|
||||
|
||||
// PeakEndHasSuffix applies the HasSuffix predicate on the "peak_end" field.
|
||||
func PeakEndHasSuffix(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldHasSuffix(FieldPeakEnd, v))
|
||||
}
|
||||
|
||||
// PeakEndEqualFold applies the EqualFold predicate on the "peak_end" field.
|
||||
func PeakEndEqualFold(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldEqualFold(FieldPeakEnd, v))
|
||||
}
|
||||
|
||||
// PeakEndContainsFold applies the ContainsFold predicate on the "peak_end" field.
|
||||
func PeakEndContainsFold(v string) predicate.Group {
|
||||
return predicate.Group(sql.FieldContainsFold(FieldPeakEnd, v))
|
||||
}
|
||||
|
||||
// PeakRateMultiplierEQ applies the EQ predicate on the "peak_rate_multiplier" field.
|
||||
func PeakRateMultiplierEQ(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldPeakRateMultiplier, v))
|
||||
}
|
||||
|
||||
// PeakRateMultiplierNEQ applies the NEQ predicate on the "peak_rate_multiplier" field.
|
||||
func PeakRateMultiplierNEQ(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldNEQ(FieldPeakRateMultiplier, v))
|
||||
}
|
||||
|
||||
// PeakRateMultiplierIn applies the In predicate on the "peak_rate_multiplier" field.
|
||||
func PeakRateMultiplierIn(vs ...float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldIn(FieldPeakRateMultiplier, vs...))
|
||||
}
|
||||
|
||||
// PeakRateMultiplierNotIn applies the NotIn predicate on the "peak_rate_multiplier" field.
|
||||
func PeakRateMultiplierNotIn(vs ...float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldNotIn(FieldPeakRateMultiplier, vs...))
|
||||
}
|
||||
|
||||
// PeakRateMultiplierGT applies the GT predicate on the "peak_rate_multiplier" field.
|
||||
func PeakRateMultiplierGT(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldGT(FieldPeakRateMultiplier, v))
|
||||
}
|
||||
|
||||
// PeakRateMultiplierGTE applies the GTE predicate on the "peak_rate_multiplier" field.
|
||||
func PeakRateMultiplierGTE(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldGTE(FieldPeakRateMultiplier, v))
|
||||
}
|
||||
|
||||
// PeakRateMultiplierLT applies the LT predicate on the "peak_rate_multiplier" field.
|
||||
func PeakRateMultiplierLT(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldLT(FieldPeakRateMultiplier, v))
|
||||
}
|
||||
|
||||
// PeakRateMultiplierLTE applies the LTE predicate on the "peak_rate_multiplier" field.
|
||||
func PeakRateMultiplierLTE(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldLTE(FieldPeakRateMultiplier, v))
|
||||
}
|
||||
|
||||
// IsExclusiveEQ applies the EQ predicate on the "is_exclusive" field.
|
||||
func IsExclusiveEQ(v bool) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldIsExclusive, v))
|
||||
@@ -925,6 +1170,16 @@ func AllowImageGenerationNEQ(v bool) predicate.Group {
|
||||
return predicate.Group(sql.FieldNEQ(FieldAllowImageGeneration, v))
|
||||
}
|
||||
|
||||
// AllowBatchImageGenerationEQ applies the EQ predicate on the "allow_batch_image_generation" field.
|
||||
func AllowBatchImageGenerationEQ(v bool) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldAllowBatchImageGeneration, v))
|
||||
}
|
||||
|
||||
// AllowBatchImageGenerationNEQ applies the NEQ predicate on the "allow_batch_image_generation" field.
|
||||
func AllowBatchImageGenerationNEQ(v bool) predicate.Group {
|
||||
return predicate.Group(sql.FieldNEQ(FieldAllowBatchImageGeneration, v))
|
||||
}
|
||||
|
||||
// ImageRateIndependentEQ applies the EQ predicate on the "image_rate_independent" field.
|
||||
func ImageRateIndependentEQ(v bool) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldImageRateIndependent, v))
|
||||
@@ -1125,6 +1380,336 @@ func ImagePrice4kNotNil() predicate.Group {
|
||||
return predicate.Group(sql.FieldNotNull(FieldImagePrice4k))
|
||||
}
|
||||
|
||||
// BatchImageDiscountMultiplierEQ applies the EQ predicate on the "batch_image_discount_multiplier" field.
|
||||
func BatchImageDiscountMultiplierEQ(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldBatchImageDiscountMultiplier, v))
|
||||
}
|
||||
|
||||
// BatchImageDiscountMultiplierNEQ applies the NEQ predicate on the "batch_image_discount_multiplier" field.
|
||||
func BatchImageDiscountMultiplierNEQ(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldNEQ(FieldBatchImageDiscountMultiplier, v))
|
||||
}
|
||||
|
||||
// BatchImageDiscountMultiplierIn applies the In predicate on the "batch_image_discount_multiplier" field.
|
||||
func BatchImageDiscountMultiplierIn(vs ...float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldIn(FieldBatchImageDiscountMultiplier, vs...))
|
||||
}
|
||||
|
||||
// BatchImageDiscountMultiplierNotIn applies the NotIn predicate on the "batch_image_discount_multiplier" field.
|
||||
func BatchImageDiscountMultiplierNotIn(vs ...float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldNotIn(FieldBatchImageDiscountMultiplier, vs...))
|
||||
}
|
||||
|
||||
// BatchImageDiscountMultiplierGT applies the GT predicate on the "batch_image_discount_multiplier" field.
|
||||
func BatchImageDiscountMultiplierGT(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldGT(FieldBatchImageDiscountMultiplier, v))
|
||||
}
|
||||
|
||||
// BatchImageDiscountMultiplierGTE applies the GTE predicate on the "batch_image_discount_multiplier" field.
|
||||
func BatchImageDiscountMultiplierGTE(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldGTE(FieldBatchImageDiscountMultiplier, v))
|
||||
}
|
||||
|
||||
// BatchImageDiscountMultiplierLT applies the LT predicate on the "batch_image_discount_multiplier" field.
|
||||
func BatchImageDiscountMultiplierLT(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldLT(FieldBatchImageDiscountMultiplier, v))
|
||||
}
|
||||
|
||||
// BatchImageDiscountMultiplierLTE applies the LTE predicate on the "batch_image_discount_multiplier" field.
|
||||
func BatchImageDiscountMultiplierLTE(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldLTE(FieldBatchImageDiscountMultiplier, v))
|
||||
}
|
||||
|
||||
// BatchImageHoldMultiplierEQ applies the EQ predicate on the "batch_image_hold_multiplier" field.
|
||||
func BatchImageHoldMultiplierEQ(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldBatchImageHoldMultiplier, v))
|
||||
}
|
||||
|
||||
// BatchImageHoldMultiplierNEQ applies the NEQ predicate on the "batch_image_hold_multiplier" field.
|
||||
func BatchImageHoldMultiplierNEQ(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldNEQ(FieldBatchImageHoldMultiplier, v))
|
||||
}
|
||||
|
||||
// BatchImageHoldMultiplierIn applies the In predicate on the "batch_image_hold_multiplier" field.
|
||||
func BatchImageHoldMultiplierIn(vs ...float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldIn(FieldBatchImageHoldMultiplier, vs...))
|
||||
}
|
||||
|
||||
// BatchImageHoldMultiplierNotIn applies the NotIn predicate on the "batch_image_hold_multiplier" field.
|
||||
func BatchImageHoldMultiplierNotIn(vs ...float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldNotIn(FieldBatchImageHoldMultiplier, vs...))
|
||||
}
|
||||
|
||||
// BatchImageHoldMultiplierGT applies the GT predicate on the "batch_image_hold_multiplier" field.
|
||||
func BatchImageHoldMultiplierGT(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldGT(FieldBatchImageHoldMultiplier, v))
|
||||
}
|
||||
|
||||
// BatchImageHoldMultiplierGTE applies the GTE predicate on the "batch_image_hold_multiplier" field.
|
||||
func BatchImageHoldMultiplierGTE(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldGTE(FieldBatchImageHoldMultiplier, v))
|
||||
}
|
||||
|
||||
// BatchImageHoldMultiplierLT applies the LT predicate on the "batch_image_hold_multiplier" field.
|
||||
func BatchImageHoldMultiplierLT(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldLT(FieldBatchImageHoldMultiplier, v))
|
||||
}
|
||||
|
||||
// BatchImageHoldMultiplierLTE applies the LTE predicate on the "batch_image_hold_multiplier" field.
|
||||
func BatchImageHoldMultiplierLTE(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldLTE(FieldBatchImageHoldMultiplier, v))
|
||||
}
|
||||
|
||||
// VideoRateIndependentEQ applies the EQ predicate on the "video_rate_independent" field.
|
||||
func VideoRateIndependentEQ(v bool) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldVideoRateIndependent, v))
|
||||
}
|
||||
|
||||
// VideoRateIndependentNEQ applies the NEQ predicate on the "video_rate_independent" field.
|
||||
func VideoRateIndependentNEQ(v bool) predicate.Group {
|
||||
return predicate.Group(sql.FieldNEQ(FieldVideoRateIndependent, v))
|
||||
}
|
||||
|
||||
// VideoRateMultiplierEQ applies the EQ predicate on the "video_rate_multiplier" field.
|
||||
func VideoRateMultiplierEQ(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldVideoRateMultiplier, v))
|
||||
}
|
||||
|
||||
// VideoRateMultiplierNEQ applies the NEQ predicate on the "video_rate_multiplier" field.
|
||||
func VideoRateMultiplierNEQ(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldNEQ(FieldVideoRateMultiplier, v))
|
||||
}
|
||||
|
||||
// VideoRateMultiplierIn applies the In predicate on the "video_rate_multiplier" field.
|
||||
func VideoRateMultiplierIn(vs ...float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldIn(FieldVideoRateMultiplier, vs...))
|
||||
}
|
||||
|
||||
// VideoRateMultiplierNotIn applies the NotIn predicate on the "video_rate_multiplier" field.
|
||||
func VideoRateMultiplierNotIn(vs ...float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldNotIn(FieldVideoRateMultiplier, vs...))
|
||||
}
|
||||
|
||||
// VideoRateMultiplierGT applies the GT predicate on the "video_rate_multiplier" field.
|
||||
func VideoRateMultiplierGT(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldGT(FieldVideoRateMultiplier, v))
|
||||
}
|
||||
|
||||
// VideoRateMultiplierGTE applies the GTE predicate on the "video_rate_multiplier" field.
|
||||
func VideoRateMultiplierGTE(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldGTE(FieldVideoRateMultiplier, v))
|
||||
}
|
||||
|
||||
// VideoRateMultiplierLT applies the LT predicate on the "video_rate_multiplier" field.
|
||||
func VideoRateMultiplierLT(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldLT(FieldVideoRateMultiplier, v))
|
||||
}
|
||||
|
||||
// VideoRateMultiplierLTE applies the LTE predicate on the "video_rate_multiplier" field.
|
||||
func VideoRateMultiplierLTE(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldLTE(FieldVideoRateMultiplier, v))
|
||||
}
|
||||
|
||||
// VideoPrice480pEQ applies the EQ predicate on the "video_price_480p" field.
|
||||
func VideoPrice480pEQ(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldVideoPrice480p, v))
|
||||
}
|
||||
|
||||
// VideoPrice480pNEQ applies the NEQ predicate on the "video_price_480p" field.
|
||||
func VideoPrice480pNEQ(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldNEQ(FieldVideoPrice480p, v))
|
||||
}
|
||||
|
||||
// VideoPrice480pIn applies the In predicate on the "video_price_480p" field.
|
||||
func VideoPrice480pIn(vs ...float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldIn(FieldVideoPrice480p, vs...))
|
||||
}
|
||||
|
||||
// VideoPrice480pNotIn applies the NotIn predicate on the "video_price_480p" field.
|
||||
func VideoPrice480pNotIn(vs ...float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldNotIn(FieldVideoPrice480p, vs...))
|
||||
}
|
||||
|
||||
// VideoPrice480pGT applies the GT predicate on the "video_price_480p" field.
|
||||
func VideoPrice480pGT(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldGT(FieldVideoPrice480p, v))
|
||||
}
|
||||
|
||||
// VideoPrice480pGTE applies the GTE predicate on the "video_price_480p" field.
|
||||
func VideoPrice480pGTE(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldGTE(FieldVideoPrice480p, v))
|
||||
}
|
||||
|
||||
// VideoPrice480pLT applies the LT predicate on the "video_price_480p" field.
|
||||
func VideoPrice480pLT(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldLT(FieldVideoPrice480p, v))
|
||||
}
|
||||
|
||||
// VideoPrice480pLTE applies the LTE predicate on the "video_price_480p" field.
|
||||
func VideoPrice480pLTE(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldLTE(FieldVideoPrice480p, v))
|
||||
}
|
||||
|
||||
// VideoPrice480pIsNil applies the IsNil predicate on the "video_price_480p" field.
|
||||
func VideoPrice480pIsNil() predicate.Group {
|
||||
return predicate.Group(sql.FieldIsNull(FieldVideoPrice480p))
|
||||
}
|
||||
|
||||
// VideoPrice480pNotNil applies the NotNil predicate on the "video_price_480p" field.
|
||||
func VideoPrice480pNotNil() predicate.Group {
|
||||
return predicate.Group(sql.FieldNotNull(FieldVideoPrice480p))
|
||||
}
|
||||
|
||||
// VideoPrice720pEQ applies the EQ predicate on the "video_price_720p" field.
|
||||
func VideoPrice720pEQ(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldVideoPrice720p, v))
|
||||
}
|
||||
|
||||
// VideoPrice720pNEQ applies the NEQ predicate on the "video_price_720p" field.
|
||||
func VideoPrice720pNEQ(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldNEQ(FieldVideoPrice720p, v))
|
||||
}
|
||||
|
||||
// VideoPrice720pIn applies the In predicate on the "video_price_720p" field.
|
||||
func VideoPrice720pIn(vs ...float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldIn(FieldVideoPrice720p, vs...))
|
||||
}
|
||||
|
||||
// VideoPrice720pNotIn applies the NotIn predicate on the "video_price_720p" field.
|
||||
func VideoPrice720pNotIn(vs ...float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldNotIn(FieldVideoPrice720p, vs...))
|
||||
}
|
||||
|
||||
// VideoPrice720pGT applies the GT predicate on the "video_price_720p" field.
|
||||
func VideoPrice720pGT(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldGT(FieldVideoPrice720p, v))
|
||||
}
|
||||
|
||||
// VideoPrice720pGTE applies the GTE predicate on the "video_price_720p" field.
|
||||
func VideoPrice720pGTE(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldGTE(FieldVideoPrice720p, v))
|
||||
}
|
||||
|
||||
// VideoPrice720pLT applies the LT predicate on the "video_price_720p" field.
|
||||
func VideoPrice720pLT(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldLT(FieldVideoPrice720p, v))
|
||||
}
|
||||
|
||||
// VideoPrice720pLTE applies the LTE predicate on the "video_price_720p" field.
|
||||
func VideoPrice720pLTE(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldLTE(FieldVideoPrice720p, v))
|
||||
}
|
||||
|
||||
// VideoPrice720pIsNil applies the IsNil predicate on the "video_price_720p" field.
|
||||
func VideoPrice720pIsNil() predicate.Group {
|
||||
return predicate.Group(sql.FieldIsNull(FieldVideoPrice720p))
|
||||
}
|
||||
|
||||
// VideoPrice720pNotNil applies the NotNil predicate on the "video_price_720p" field.
|
||||
func VideoPrice720pNotNil() predicate.Group {
|
||||
return predicate.Group(sql.FieldNotNull(FieldVideoPrice720p))
|
||||
}
|
||||
|
||||
// VideoPrice1080pEQ applies the EQ predicate on the "video_price_1080p" field.
|
||||
func VideoPrice1080pEQ(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldVideoPrice1080p, v))
|
||||
}
|
||||
|
||||
// VideoPrice1080pNEQ applies the NEQ predicate on the "video_price_1080p" field.
|
||||
func VideoPrice1080pNEQ(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldNEQ(FieldVideoPrice1080p, v))
|
||||
}
|
||||
|
||||
// VideoPrice1080pIn applies the In predicate on the "video_price_1080p" field.
|
||||
func VideoPrice1080pIn(vs ...float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldIn(FieldVideoPrice1080p, vs...))
|
||||
}
|
||||
|
||||
// VideoPrice1080pNotIn applies the NotIn predicate on the "video_price_1080p" field.
|
||||
func VideoPrice1080pNotIn(vs ...float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldNotIn(FieldVideoPrice1080p, vs...))
|
||||
}
|
||||
|
||||
// VideoPrice1080pGT applies the GT predicate on the "video_price_1080p" field.
|
||||
func VideoPrice1080pGT(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldGT(FieldVideoPrice1080p, v))
|
||||
}
|
||||
|
||||
// VideoPrice1080pGTE applies the GTE predicate on the "video_price_1080p" field.
|
||||
func VideoPrice1080pGTE(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldGTE(FieldVideoPrice1080p, v))
|
||||
}
|
||||
|
||||
// VideoPrice1080pLT applies the LT predicate on the "video_price_1080p" field.
|
||||
func VideoPrice1080pLT(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldLT(FieldVideoPrice1080p, v))
|
||||
}
|
||||
|
||||
// VideoPrice1080pLTE applies the LTE predicate on the "video_price_1080p" field.
|
||||
func VideoPrice1080pLTE(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldLTE(FieldVideoPrice1080p, v))
|
||||
}
|
||||
|
||||
// VideoPrice1080pIsNil applies the IsNil predicate on the "video_price_1080p" field.
|
||||
func VideoPrice1080pIsNil() predicate.Group {
|
||||
return predicate.Group(sql.FieldIsNull(FieldVideoPrice1080p))
|
||||
}
|
||||
|
||||
// VideoPrice1080pNotNil applies the NotNil predicate on the "video_price_1080p" field.
|
||||
func VideoPrice1080pNotNil() predicate.Group {
|
||||
return predicate.Group(sql.FieldNotNull(FieldVideoPrice1080p))
|
||||
}
|
||||
|
||||
// WebSearchPricePerCallEQ applies the EQ predicate on the "web_search_price_per_call" field.
|
||||
func WebSearchPricePerCallEQ(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldWebSearchPricePerCall, v))
|
||||
}
|
||||
|
||||
// WebSearchPricePerCallNEQ applies the NEQ predicate on the "web_search_price_per_call" field.
|
||||
func WebSearchPricePerCallNEQ(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldNEQ(FieldWebSearchPricePerCall, v))
|
||||
}
|
||||
|
||||
// WebSearchPricePerCallIn applies the In predicate on the "web_search_price_per_call" field.
|
||||
func WebSearchPricePerCallIn(vs ...float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldIn(FieldWebSearchPricePerCall, vs...))
|
||||
}
|
||||
|
||||
// WebSearchPricePerCallNotIn applies the NotIn predicate on the "web_search_price_per_call" field.
|
||||
func WebSearchPricePerCallNotIn(vs ...float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldNotIn(FieldWebSearchPricePerCall, vs...))
|
||||
}
|
||||
|
||||
// WebSearchPricePerCallGT applies the GT predicate on the "web_search_price_per_call" field.
|
||||
func WebSearchPricePerCallGT(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldGT(FieldWebSearchPricePerCall, v))
|
||||
}
|
||||
|
||||
// WebSearchPricePerCallGTE applies the GTE predicate on the "web_search_price_per_call" field.
|
||||
func WebSearchPricePerCallGTE(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldGTE(FieldWebSearchPricePerCall, v))
|
||||
}
|
||||
|
||||
// WebSearchPricePerCallLT applies the LT predicate on the "web_search_price_per_call" field.
|
||||
func WebSearchPricePerCallLT(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldLT(FieldWebSearchPricePerCall, v))
|
||||
}
|
||||
|
||||
// WebSearchPricePerCallLTE applies the LTE predicate on the "web_search_price_per_call" field.
|
||||
func WebSearchPricePerCallLTE(v float64) predicate.Group {
|
||||
return predicate.Group(sql.FieldLTE(FieldWebSearchPricePerCall, v))
|
||||
}
|
||||
|
||||
// WebSearchPricePerCallIsNil applies the IsNil predicate on the "web_search_price_per_call" field.
|
||||
func WebSearchPricePerCallIsNil() predicate.Group {
|
||||
return predicate.Group(sql.FieldIsNull(FieldWebSearchPricePerCall))
|
||||
}
|
||||
|
||||
// WebSearchPricePerCallNotNil applies the NotNil predicate on the "web_search_price_per_call" field.
|
||||
func WebSearchPricePerCallNotNil() predicate.Group {
|
||||
return predicate.Group(sql.FieldNotNull(FieldWebSearchPricePerCall))
|
||||
}
|
||||
|
||||
// ClaudeCodeOnlyEQ applies the EQ predicate on the "claude_code_only" field.
|
||||
func ClaudeCodeOnlyEQ(v bool) predicate.Group {
|
||||
return predicate.Group(sql.FieldEQ(FieldClaudeCodeOnly, v))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -117,6 +117,69 @@ func (_u *GroupUpdate) AddRateMultiplier(v float64) *GroupUpdate {
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetPeakRateEnabled sets the "peak_rate_enabled" field.
|
||||
func (_u *GroupUpdate) SetPeakRateEnabled(v bool) *GroupUpdate {
|
||||
_u.mutation.SetPeakRateEnabled(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillablePeakRateEnabled sets the "peak_rate_enabled" field if the given value is not nil.
|
||||
func (_u *GroupUpdate) SetNillablePeakRateEnabled(v *bool) *GroupUpdate {
|
||||
if v != nil {
|
||||
_u.SetPeakRateEnabled(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetPeakStart sets the "peak_start" field.
|
||||
func (_u *GroupUpdate) SetPeakStart(v string) *GroupUpdate {
|
||||
_u.mutation.SetPeakStart(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillablePeakStart sets the "peak_start" field if the given value is not nil.
|
||||
func (_u *GroupUpdate) SetNillablePeakStart(v *string) *GroupUpdate {
|
||||
if v != nil {
|
||||
_u.SetPeakStart(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetPeakEnd sets the "peak_end" field.
|
||||
func (_u *GroupUpdate) SetPeakEnd(v string) *GroupUpdate {
|
||||
_u.mutation.SetPeakEnd(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillablePeakEnd sets the "peak_end" field if the given value is not nil.
|
||||
func (_u *GroupUpdate) SetNillablePeakEnd(v *string) *GroupUpdate {
|
||||
if v != nil {
|
||||
_u.SetPeakEnd(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetPeakRateMultiplier sets the "peak_rate_multiplier" field.
|
||||
func (_u *GroupUpdate) SetPeakRateMultiplier(v float64) *GroupUpdate {
|
||||
_u.mutation.ResetPeakRateMultiplier()
|
||||
_u.mutation.SetPeakRateMultiplier(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillablePeakRateMultiplier sets the "peak_rate_multiplier" field if the given value is not nil.
|
||||
func (_u *GroupUpdate) SetNillablePeakRateMultiplier(v *float64) *GroupUpdate {
|
||||
if v != nil {
|
||||
_u.SetPeakRateMultiplier(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddPeakRateMultiplier adds value to the "peak_rate_multiplier" field.
|
||||
func (_u *GroupUpdate) AddPeakRateMultiplier(v float64) *GroupUpdate {
|
||||
_u.mutation.AddPeakRateMultiplier(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetIsExclusive sets the "is_exclusive" field.
|
||||
func (_u *GroupUpdate) SetIsExclusive(v bool) *GroupUpdate {
|
||||
_u.mutation.SetIsExclusive(v)
|
||||
@@ -289,6 +352,20 @@ func (_u *GroupUpdate) SetNillableAllowImageGeneration(v *bool) *GroupUpdate {
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetAllowBatchImageGeneration sets the "allow_batch_image_generation" field.
|
||||
func (_u *GroupUpdate) SetAllowBatchImageGeneration(v bool) *GroupUpdate {
|
||||
_u.mutation.SetAllowBatchImageGeneration(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableAllowBatchImageGeneration sets the "allow_batch_image_generation" field if the given value is not nil.
|
||||
func (_u *GroupUpdate) SetNillableAllowBatchImageGeneration(v *bool) *GroupUpdate {
|
||||
if v != nil {
|
||||
_u.SetAllowBatchImageGeneration(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetImageRateIndependent sets the "image_rate_independent" field.
|
||||
func (_u *GroupUpdate) SetImageRateIndependent(v bool) *GroupUpdate {
|
||||
_u.mutation.SetImageRateIndependent(v)
|
||||
@@ -405,6 +482,191 @@ func (_u *GroupUpdate) ClearImagePrice4k() *GroupUpdate {
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetBatchImageDiscountMultiplier sets the "batch_image_discount_multiplier" field.
|
||||
func (_u *GroupUpdate) SetBatchImageDiscountMultiplier(v float64) *GroupUpdate {
|
||||
_u.mutation.ResetBatchImageDiscountMultiplier()
|
||||
_u.mutation.SetBatchImageDiscountMultiplier(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableBatchImageDiscountMultiplier sets the "batch_image_discount_multiplier" field if the given value is not nil.
|
||||
func (_u *GroupUpdate) SetNillableBatchImageDiscountMultiplier(v *float64) *GroupUpdate {
|
||||
if v != nil {
|
||||
_u.SetBatchImageDiscountMultiplier(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddBatchImageDiscountMultiplier adds value to the "batch_image_discount_multiplier" field.
|
||||
func (_u *GroupUpdate) AddBatchImageDiscountMultiplier(v float64) *GroupUpdate {
|
||||
_u.mutation.AddBatchImageDiscountMultiplier(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetBatchImageHoldMultiplier sets the "batch_image_hold_multiplier" field.
|
||||
func (_u *GroupUpdate) SetBatchImageHoldMultiplier(v float64) *GroupUpdate {
|
||||
_u.mutation.ResetBatchImageHoldMultiplier()
|
||||
_u.mutation.SetBatchImageHoldMultiplier(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableBatchImageHoldMultiplier sets the "batch_image_hold_multiplier" field if the given value is not nil.
|
||||
func (_u *GroupUpdate) SetNillableBatchImageHoldMultiplier(v *float64) *GroupUpdate {
|
||||
if v != nil {
|
||||
_u.SetBatchImageHoldMultiplier(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddBatchImageHoldMultiplier adds value to the "batch_image_hold_multiplier" field.
|
||||
func (_u *GroupUpdate) AddBatchImageHoldMultiplier(v float64) *GroupUpdate {
|
||||
_u.mutation.AddBatchImageHoldMultiplier(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetVideoRateIndependent sets the "video_rate_independent" field.
|
||||
func (_u *GroupUpdate) SetVideoRateIndependent(v bool) *GroupUpdate {
|
||||
_u.mutation.SetVideoRateIndependent(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableVideoRateIndependent sets the "video_rate_independent" field if the given value is not nil.
|
||||
func (_u *GroupUpdate) SetNillableVideoRateIndependent(v *bool) *GroupUpdate {
|
||||
if v != nil {
|
||||
_u.SetVideoRateIndependent(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetVideoRateMultiplier sets the "video_rate_multiplier" field.
|
||||
func (_u *GroupUpdate) SetVideoRateMultiplier(v float64) *GroupUpdate {
|
||||
_u.mutation.ResetVideoRateMultiplier()
|
||||
_u.mutation.SetVideoRateMultiplier(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableVideoRateMultiplier sets the "video_rate_multiplier" field if the given value is not nil.
|
||||
func (_u *GroupUpdate) SetNillableVideoRateMultiplier(v *float64) *GroupUpdate {
|
||||
if v != nil {
|
||||
_u.SetVideoRateMultiplier(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddVideoRateMultiplier adds value to the "video_rate_multiplier" field.
|
||||
func (_u *GroupUpdate) AddVideoRateMultiplier(v float64) *GroupUpdate {
|
||||
_u.mutation.AddVideoRateMultiplier(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetVideoPrice480p sets the "video_price_480p" field.
|
||||
func (_u *GroupUpdate) SetVideoPrice480p(v float64) *GroupUpdate {
|
||||
_u.mutation.ResetVideoPrice480p()
|
||||
_u.mutation.SetVideoPrice480p(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableVideoPrice480p sets the "video_price_480p" field if the given value is not nil.
|
||||
func (_u *GroupUpdate) SetNillableVideoPrice480p(v *float64) *GroupUpdate {
|
||||
if v != nil {
|
||||
_u.SetVideoPrice480p(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddVideoPrice480p adds value to the "video_price_480p" field.
|
||||
func (_u *GroupUpdate) AddVideoPrice480p(v float64) *GroupUpdate {
|
||||
_u.mutation.AddVideoPrice480p(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearVideoPrice480p clears the value of the "video_price_480p" field.
|
||||
func (_u *GroupUpdate) ClearVideoPrice480p() *GroupUpdate {
|
||||
_u.mutation.ClearVideoPrice480p()
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetVideoPrice720p sets the "video_price_720p" field.
|
||||
func (_u *GroupUpdate) SetVideoPrice720p(v float64) *GroupUpdate {
|
||||
_u.mutation.ResetVideoPrice720p()
|
||||
_u.mutation.SetVideoPrice720p(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableVideoPrice720p sets the "video_price_720p" field if the given value is not nil.
|
||||
func (_u *GroupUpdate) SetNillableVideoPrice720p(v *float64) *GroupUpdate {
|
||||
if v != nil {
|
||||
_u.SetVideoPrice720p(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddVideoPrice720p adds value to the "video_price_720p" field.
|
||||
func (_u *GroupUpdate) AddVideoPrice720p(v float64) *GroupUpdate {
|
||||
_u.mutation.AddVideoPrice720p(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearVideoPrice720p clears the value of the "video_price_720p" field.
|
||||
func (_u *GroupUpdate) ClearVideoPrice720p() *GroupUpdate {
|
||||
_u.mutation.ClearVideoPrice720p()
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetVideoPrice1080p sets the "video_price_1080p" field.
|
||||
func (_u *GroupUpdate) SetVideoPrice1080p(v float64) *GroupUpdate {
|
||||
_u.mutation.ResetVideoPrice1080p()
|
||||
_u.mutation.SetVideoPrice1080p(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableVideoPrice1080p sets the "video_price_1080p" field if the given value is not nil.
|
||||
func (_u *GroupUpdate) SetNillableVideoPrice1080p(v *float64) *GroupUpdate {
|
||||
if v != nil {
|
||||
_u.SetVideoPrice1080p(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddVideoPrice1080p adds value to the "video_price_1080p" field.
|
||||
func (_u *GroupUpdate) AddVideoPrice1080p(v float64) *GroupUpdate {
|
||||
_u.mutation.AddVideoPrice1080p(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearVideoPrice1080p clears the value of the "video_price_1080p" field.
|
||||
func (_u *GroupUpdate) ClearVideoPrice1080p() *GroupUpdate {
|
||||
_u.mutation.ClearVideoPrice1080p()
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetWebSearchPricePerCall sets the "web_search_price_per_call" field.
|
||||
func (_u *GroupUpdate) SetWebSearchPricePerCall(v float64) *GroupUpdate {
|
||||
_u.mutation.ResetWebSearchPricePerCall()
|
||||
_u.mutation.SetWebSearchPricePerCall(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableWebSearchPricePerCall sets the "web_search_price_per_call" field if the given value is not nil.
|
||||
func (_u *GroupUpdate) SetNillableWebSearchPricePerCall(v *float64) *GroupUpdate {
|
||||
if v != nil {
|
||||
_u.SetWebSearchPricePerCall(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddWebSearchPricePerCall adds value to the "web_search_price_per_call" field.
|
||||
func (_u *GroupUpdate) AddWebSearchPricePerCall(v float64) *GroupUpdate {
|
||||
_u.mutation.AddWebSearchPricePerCall(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearWebSearchPricePerCall clears the value of the "web_search_price_per_call" field.
|
||||
func (_u *GroupUpdate) ClearWebSearchPricePerCall() *GroupUpdate {
|
||||
_u.mutation.ClearWebSearchPricePerCall()
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetClaudeCodeOnly sets the "claude_code_only" field.
|
||||
func (_u *GroupUpdate) SetClaudeCodeOnly(v bool) *GroupUpdate {
|
||||
_u.mutation.SetClaudeCodeOnly(v)
|
||||
@@ -921,6 +1183,16 @@ func (_u *GroupUpdate) check() error {
|
||||
return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "Group.name": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := _u.mutation.PeakStart(); ok {
|
||||
if err := group.PeakStartValidator(v); err != nil {
|
||||
return &ValidationError{Name: "peak_start", err: fmt.Errorf(`ent: validator failed for field "Group.peak_start": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := _u.mutation.PeakEnd(); ok {
|
||||
if err := group.PeakEndValidator(v); err != nil {
|
||||
return &ValidationError{Name: "peak_end", err: fmt.Errorf(`ent: validator failed for field "Group.peak_end": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := _u.mutation.Status(); ok {
|
||||
if err := group.StatusValidator(v); err != nil {
|
||||
return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "Group.status": %w`, err)}
|
||||
@@ -980,6 +1252,21 @@ func (_u *GroupUpdate) sqlSave(ctx context.Context) (_node int, err error) {
|
||||
if value, ok := _u.mutation.AddedRateMultiplier(); ok {
|
||||
_spec.AddField(group.FieldRateMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.PeakRateEnabled(); ok {
|
||||
_spec.SetField(group.FieldPeakRateEnabled, field.TypeBool, value)
|
||||
}
|
||||
if value, ok := _u.mutation.PeakStart(); ok {
|
||||
_spec.SetField(group.FieldPeakStart, field.TypeString, value)
|
||||
}
|
||||
if value, ok := _u.mutation.PeakEnd(); ok {
|
||||
_spec.SetField(group.FieldPeakEnd, field.TypeString, value)
|
||||
}
|
||||
if value, ok := _u.mutation.PeakRateMultiplier(); ok {
|
||||
_spec.SetField(group.FieldPeakRateMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedPeakRateMultiplier(); ok {
|
||||
_spec.AddField(group.FieldPeakRateMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.IsExclusive(); ok {
|
||||
_spec.SetField(group.FieldIsExclusive, field.TypeBool, value)
|
||||
}
|
||||
@@ -1028,6 +1315,9 @@ func (_u *GroupUpdate) sqlSave(ctx context.Context) (_node int, err error) {
|
||||
if value, ok := _u.mutation.AllowImageGeneration(); ok {
|
||||
_spec.SetField(group.FieldAllowImageGeneration, field.TypeBool, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AllowBatchImageGeneration(); ok {
|
||||
_spec.SetField(group.FieldAllowBatchImageGeneration, field.TypeBool, value)
|
||||
}
|
||||
if value, ok := _u.mutation.ImageRateIndependent(); ok {
|
||||
_spec.SetField(group.FieldImageRateIndependent, field.TypeBool, value)
|
||||
}
|
||||
@@ -1064,6 +1354,63 @@ func (_u *GroupUpdate) sqlSave(ctx context.Context) (_node int, err error) {
|
||||
if _u.mutation.ImagePrice4kCleared() {
|
||||
_spec.ClearField(group.FieldImagePrice4k, field.TypeFloat64)
|
||||
}
|
||||
if value, ok := _u.mutation.BatchImageDiscountMultiplier(); ok {
|
||||
_spec.SetField(group.FieldBatchImageDiscountMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedBatchImageDiscountMultiplier(); ok {
|
||||
_spec.AddField(group.FieldBatchImageDiscountMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.BatchImageHoldMultiplier(); ok {
|
||||
_spec.SetField(group.FieldBatchImageHoldMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedBatchImageHoldMultiplier(); ok {
|
||||
_spec.AddField(group.FieldBatchImageHoldMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.VideoRateIndependent(); ok {
|
||||
_spec.SetField(group.FieldVideoRateIndependent, field.TypeBool, value)
|
||||
}
|
||||
if value, ok := _u.mutation.VideoRateMultiplier(); ok {
|
||||
_spec.SetField(group.FieldVideoRateMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedVideoRateMultiplier(); ok {
|
||||
_spec.AddField(group.FieldVideoRateMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.VideoPrice480p(); ok {
|
||||
_spec.SetField(group.FieldVideoPrice480p, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedVideoPrice480p(); ok {
|
||||
_spec.AddField(group.FieldVideoPrice480p, field.TypeFloat64, value)
|
||||
}
|
||||
if _u.mutation.VideoPrice480pCleared() {
|
||||
_spec.ClearField(group.FieldVideoPrice480p, field.TypeFloat64)
|
||||
}
|
||||
if value, ok := _u.mutation.VideoPrice720p(); ok {
|
||||
_spec.SetField(group.FieldVideoPrice720p, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedVideoPrice720p(); ok {
|
||||
_spec.AddField(group.FieldVideoPrice720p, field.TypeFloat64, value)
|
||||
}
|
||||
if _u.mutation.VideoPrice720pCleared() {
|
||||
_spec.ClearField(group.FieldVideoPrice720p, field.TypeFloat64)
|
||||
}
|
||||
if value, ok := _u.mutation.VideoPrice1080p(); ok {
|
||||
_spec.SetField(group.FieldVideoPrice1080p, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedVideoPrice1080p(); ok {
|
||||
_spec.AddField(group.FieldVideoPrice1080p, field.TypeFloat64, value)
|
||||
}
|
||||
if _u.mutation.VideoPrice1080pCleared() {
|
||||
_spec.ClearField(group.FieldVideoPrice1080p, field.TypeFloat64)
|
||||
}
|
||||
if value, ok := _u.mutation.WebSearchPricePerCall(); ok {
|
||||
_spec.SetField(group.FieldWebSearchPricePerCall, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedWebSearchPricePerCall(); ok {
|
||||
_spec.AddField(group.FieldWebSearchPricePerCall, field.TypeFloat64, value)
|
||||
}
|
||||
if _u.mutation.WebSearchPricePerCallCleared() {
|
||||
_spec.ClearField(group.FieldWebSearchPricePerCall, field.TypeFloat64)
|
||||
}
|
||||
if value, ok := _u.mutation.ClaudeCodeOnly(); ok {
|
||||
_spec.SetField(group.FieldClaudeCodeOnly, field.TypeBool, value)
|
||||
}
|
||||
@@ -1530,6 +1877,69 @@ func (_u *GroupUpdateOne) AddRateMultiplier(v float64) *GroupUpdateOne {
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetPeakRateEnabled sets the "peak_rate_enabled" field.
|
||||
func (_u *GroupUpdateOne) SetPeakRateEnabled(v bool) *GroupUpdateOne {
|
||||
_u.mutation.SetPeakRateEnabled(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillablePeakRateEnabled sets the "peak_rate_enabled" field if the given value is not nil.
|
||||
func (_u *GroupUpdateOne) SetNillablePeakRateEnabled(v *bool) *GroupUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetPeakRateEnabled(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetPeakStart sets the "peak_start" field.
|
||||
func (_u *GroupUpdateOne) SetPeakStart(v string) *GroupUpdateOne {
|
||||
_u.mutation.SetPeakStart(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillablePeakStart sets the "peak_start" field if the given value is not nil.
|
||||
func (_u *GroupUpdateOne) SetNillablePeakStart(v *string) *GroupUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetPeakStart(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetPeakEnd sets the "peak_end" field.
|
||||
func (_u *GroupUpdateOne) SetPeakEnd(v string) *GroupUpdateOne {
|
||||
_u.mutation.SetPeakEnd(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillablePeakEnd sets the "peak_end" field if the given value is not nil.
|
||||
func (_u *GroupUpdateOne) SetNillablePeakEnd(v *string) *GroupUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetPeakEnd(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetPeakRateMultiplier sets the "peak_rate_multiplier" field.
|
||||
func (_u *GroupUpdateOne) SetPeakRateMultiplier(v float64) *GroupUpdateOne {
|
||||
_u.mutation.ResetPeakRateMultiplier()
|
||||
_u.mutation.SetPeakRateMultiplier(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillablePeakRateMultiplier sets the "peak_rate_multiplier" field if the given value is not nil.
|
||||
func (_u *GroupUpdateOne) SetNillablePeakRateMultiplier(v *float64) *GroupUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetPeakRateMultiplier(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddPeakRateMultiplier adds value to the "peak_rate_multiplier" field.
|
||||
func (_u *GroupUpdateOne) AddPeakRateMultiplier(v float64) *GroupUpdateOne {
|
||||
_u.mutation.AddPeakRateMultiplier(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetIsExclusive sets the "is_exclusive" field.
|
||||
func (_u *GroupUpdateOne) SetIsExclusive(v bool) *GroupUpdateOne {
|
||||
_u.mutation.SetIsExclusive(v)
|
||||
@@ -1702,6 +2112,20 @@ func (_u *GroupUpdateOne) SetNillableAllowImageGeneration(v *bool) *GroupUpdateO
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetAllowBatchImageGeneration sets the "allow_batch_image_generation" field.
|
||||
func (_u *GroupUpdateOne) SetAllowBatchImageGeneration(v bool) *GroupUpdateOne {
|
||||
_u.mutation.SetAllowBatchImageGeneration(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableAllowBatchImageGeneration sets the "allow_batch_image_generation" field if the given value is not nil.
|
||||
func (_u *GroupUpdateOne) SetNillableAllowBatchImageGeneration(v *bool) *GroupUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetAllowBatchImageGeneration(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetImageRateIndependent sets the "image_rate_independent" field.
|
||||
func (_u *GroupUpdateOne) SetImageRateIndependent(v bool) *GroupUpdateOne {
|
||||
_u.mutation.SetImageRateIndependent(v)
|
||||
@@ -1818,6 +2242,191 @@ func (_u *GroupUpdateOne) ClearImagePrice4k() *GroupUpdateOne {
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetBatchImageDiscountMultiplier sets the "batch_image_discount_multiplier" field.
|
||||
func (_u *GroupUpdateOne) SetBatchImageDiscountMultiplier(v float64) *GroupUpdateOne {
|
||||
_u.mutation.ResetBatchImageDiscountMultiplier()
|
||||
_u.mutation.SetBatchImageDiscountMultiplier(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableBatchImageDiscountMultiplier sets the "batch_image_discount_multiplier" field if the given value is not nil.
|
||||
func (_u *GroupUpdateOne) SetNillableBatchImageDiscountMultiplier(v *float64) *GroupUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetBatchImageDiscountMultiplier(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddBatchImageDiscountMultiplier adds value to the "batch_image_discount_multiplier" field.
|
||||
func (_u *GroupUpdateOne) AddBatchImageDiscountMultiplier(v float64) *GroupUpdateOne {
|
||||
_u.mutation.AddBatchImageDiscountMultiplier(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetBatchImageHoldMultiplier sets the "batch_image_hold_multiplier" field.
|
||||
func (_u *GroupUpdateOne) SetBatchImageHoldMultiplier(v float64) *GroupUpdateOne {
|
||||
_u.mutation.ResetBatchImageHoldMultiplier()
|
||||
_u.mutation.SetBatchImageHoldMultiplier(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableBatchImageHoldMultiplier sets the "batch_image_hold_multiplier" field if the given value is not nil.
|
||||
func (_u *GroupUpdateOne) SetNillableBatchImageHoldMultiplier(v *float64) *GroupUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetBatchImageHoldMultiplier(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddBatchImageHoldMultiplier adds value to the "batch_image_hold_multiplier" field.
|
||||
func (_u *GroupUpdateOne) AddBatchImageHoldMultiplier(v float64) *GroupUpdateOne {
|
||||
_u.mutation.AddBatchImageHoldMultiplier(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetVideoRateIndependent sets the "video_rate_independent" field.
|
||||
func (_u *GroupUpdateOne) SetVideoRateIndependent(v bool) *GroupUpdateOne {
|
||||
_u.mutation.SetVideoRateIndependent(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableVideoRateIndependent sets the "video_rate_independent" field if the given value is not nil.
|
||||
func (_u *GroupUpdateOne) SetNillableVideoRateIndependent(v *bool) *GroupUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetVideoRateIndependent(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetVideoRateMultiplier sets the "video_rate_multiplier" field.
|
||||
func (_u *GroupUpdateOne) SetVideoRateMultiplier(v float64) *GroupUpdateOne {
|
||||
_u.mutation.ResetVideoRateMultiplier()
|
||||
_u.mutation.SetVideoRateMultiplier(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableVideoRateMultiplier sets the "video_rate_multiplier" field if the given value is not nil.
|
||||
func (_u *GroupUpdateOne) SetNillableVideoRateMultiplier(v *float64) *GroupUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetVideoRateMultiplier(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddVideoRateMultiplier adds value to the "video_rate_multiplier" field.
|
||||
func (_u *GroupUpdateOne) AddVideoRateMultiplier(v float64) *GroupUpdateOne {
|
||||
_u.mutation.AddVideoRateMultiplier(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetVideoPrice480p sets the "video_price_480p" field.
|
||||
func (_u *GroupUpdateOne) SetVideoPrice480p(v float64) *GroupUpdateOne {
|
||||
_u.mutation.ResetVideoPrice480p()
|
||||
_u.mutation.SetVideoPrice480p(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableVideoPrice480p sets the "video_price_480p" field if the given value is not nil.
|
||||
func (_u *GroupUpdateOne) SetNillableVideoPrice480p(v *float64) *GroupUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetVideoPrice480p(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddVideoPrice480p adds value to the "video_price_480p" field.
|
||||
func (_u *GroupUpdateOne) AddVideoPrice480p(v float64) *GroupUpdateOne {
|
||||
_u.mutation.AddVideoPrice480p(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearVideoPrice480p clears the value of the "video_price_480p" field.
|
||||
func (_u *GroupUpdateOne) ClearVideoPrice480p() *GroupUpdateOne {
|
||||
_u.mutation.ClearVideoPrice480p()
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetVideoPrice720p sets the "video_price_720p" field.
|
||||
func (_u *GroupUpdateOne) SetVideoPrice720p(v float64) *GroupUpdateOne {
|
||||
_u.mutation.ResetVideoPrice720p()
|
||||
_u.mutation.SetVideoPrice720p(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableVideoPrice720p sets the "video_price_720p" field if the given value is not nil.
|
||||
func (_u *GroupUpdateOne) SetNillableVideoPrice720p(v *float64) *GroupUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetVideoPrice720p(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddVideoPrice720p adds value to the "video_price_720p" field.
|
||||
func (_u *GroupUpdateOne) AddVideoPrice720p(v float64) *GroupUpdateOne {
|
||||
_u.mutation.AddVideoPrice720p(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearVideoPrice720p clears the value of the "video_price_720p" field.
|
||||
func (_u *GroupUpdateOne) ClearVideoPrice720p() *GroupUpdateOne {
|
||||
_u.mutation.ClearVideoPrice720p()
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetVideoPrice1080p sets the "video_price_1080p" field.
|
||||
func (_u *GroupUpdateOne) SetVideoPrice1080p(v float64) *GroupUpdateOne {
|
||||
_u.mutation.ResetVideoPrice1080p()
|
||||
_u.mutation.SetVideoPrice1080p(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableVideoPrice1080p sets the "video_price_1080p" field if the given value is not nil.
|
||||
func (_u *GroupUpdateOne) SetNillableVideoPrice1080p(v *float64) *GroupUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetVideoPrice1080p(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddVideoPrice1080p adds value to the "video_price_1080p" field.
|
||||
func (_u *GroupUpdateOne) AddVideoPrice1080p(v float64) *GroupUpdateOne {
|
||||
_u.mutation.AddVideoPrice1080p(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearVideoPrice1080p clears the value of the "video_price_1080p" field.
|
||||
func (_u *GroupUpdateOne) ClearVideoPrice1080p() *GroupUpdateOne {
|
||||
_u.mutation.ClearVideoPrice1080p()
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetWebSearchPricePerCall sets the "web_search_price_per_call" field.
|
||||
func (_u *GroupUpdateOne) SetWebSearchPricePerCall(v float64) *GroupUpdateOne {
|
||||
_u.mutation.ResetWebSearchPricePerCall()
|
||||
_u.mutation.SetWebSearchPricePerCall(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableWebSearchPricePerCall sets the "web_search_price_per_call" field if the given value is not nil.
|
||||
func (_u *GroupUpdateOne) SetNillableWebSearchPricePerCall(v *float64) *GroupUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetWebSearchPricePerCall(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddWebSearchPricePerCall adds value to the "web_search_price_per_call" field.
|
||||
func (_u *GroupUpdateOne) AddWebSearchPricePerCall(v float64) *GroupUpdateOne {
|
||||
_u.mutation.AddWebSearchPricePerCall(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearWebSearchPricePerCall clears the value of the "web_search_price_per_call" field.
|
||||
func (_u *GroupUpdateOne) ClearWebSearchPricePerCall() *GroupUpdateOne {
|
||||
_u.mutation.ClearWebSearchPricePerCall()
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetClaudeCodeOnly sets the "claude_code_only" field.
|
||||
func (_u *GroupUpdateOne) SetClaudeCodeOnly(v bool) *GroupUpdateOne {
|
||||
_u.mutation.SetClaudeCodeOnly(v)
|
||||
@@ -2347,6 +2956,16 @@ func (_u *GroupUpdateOne) check() error {
|
||||
return &ValidationError{Name: "name", err: fmt.Errorf(`ent: validator failed for field "Group.name": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := _u.mutation.PeakStart(); ok {
|
||||
if err := group.PeakStartValidator(v); err != nil {
|
||||
return &ValidationError{Name: "peak_start", err: fmt.Errorf(`ent: validator failed for field "Group.peak_start": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := _u.mutation.PeakEnd(); ok {
|
||||
if err := group.PeakEndValidator(v); err != nil {
|
||||
return &ValidationError{Name: "peak_end", err: fmt.Errorf(`ent: validator failed for field "Group.peak_end": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := _u.mutation.Status(); ok {
|
||||
if err := group.StatusValidator(v); err != nil {
|
||||
return &ValidationError{Name: "status", err: fmt.Errorf(`ent: validator failed for field "Group.status": %w`, err)}
|
||||
@@ -2423,6 +3042,21 @@ func (_u *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error)
|
||||
if value, ok := _u.mutation.AddedRateMultiplier(); ok {
|
||||
_spec.AddField(group.FieldRateMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.PeakRateEnabled(); ok {
|
||||
_spec.SetField(group.FieldPeakRateEnabled, field.TypeBool, value)
|
||||
}
|
||||
if value, ok := _u.mutation.PeakStart(); ok {
|
||||
_spec.SetField(group.FieldPeakStart, field.TypeString, value)
|
||||
}
|
||||
if value, ok := _u.mutation.PeakEnd(); ok {
|
||||
_spec.SetField(group.FieldPeakEnd, field.TypeString, value)
|
||||
}
|
||||
if value, ok := _u.mutation.PeakRateMultiplier(); ok {
|
||||
_spec.SetField(group.FieldPeakRateMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedPeakRateMultiplier(); ok {
|
||||
_spec.AddField(group.FieldPeakRateMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.IsExclusive(); ok {
|
||||
_spec.SetField(group.FieldIsExclusive, field.TypeBool, value)
|
||||
}
|
||||
@@ -2471,6 +3105,9 @@ func (_u *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error)
|
||||
if value, ok := _u.mutation.AllowImageGeneration(); ok {
|
||||
_spec.SetField(group.FieldAllowImageGeneration, field.TypeBool, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AllowBatchImageGeneration(); ok {
|
||||
_spec.SetField(group.FieldAllowBatchImageGeneration, field.TypeBool, value)
|
||||
}
|
||||
if value, ok := _u.mutation.ImageRateIndependent(); ok {
|
||||
_spec.SetField(group.FieldImageRateIndependent, field.TypeBool, value)
|
||||
}
|
||||
@@ -2507,6 +3144,63 @@ func (_u *GroupUpdateOne) sqlSave(ctx context.Context) (_node *Group, err error)
|
||||
if _u.mutation.ImagePrice4kCleared() {
|
||||
_spec.ClearField(group.FieldImagePrice4k, field.TypeFloat64)
|
||||
}
|
||||
if value, ok := _u.mutation.BatchImageDiscountMultiplier(); ok {
|
||||
_spec.SetField(group.FieldBatchImageDiscountMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedBatchImageDiscountMultiplier(); ok {
|
||||
_spec.AddField(group.FieldBatchImageDiscountMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.BatchImageHoldMultiplier(); ok {
|
||||
_spec.SetField(group.FieldBatchImageHoldMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedBatchImageHoldMultiplier(); ok {
|
||||
_spec.AddField(group.FieldBatchImageHoldMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.VideoRateIndependent(); ok {
|
||||
_spec.SetField(group.FieldVideoRateIndependent, field.TypeBool, value)
|
||||
}
|
||||
if value, ok := _u.mutation.VideoRateMultiplier(); ok {
|
||||
_spec.SetField(group.FieldVideoRateMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedVideoRateMultiplier(); ok {
|
||||
_spec.AddField(group.FieldVideoRateMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.VideoPrice480p(); ok {
|
||||
_spec.SetField(group.FieldVideoPrice480p, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedVideoPrice480p(); ok {
|
||||
_spec.AddField(group.FieldVideoPrice480p, field.TypeFloat64, value)
|
||||
}
|
||||
if _u.mutation.VideoPrice480pCleared() {
|
||||
_spec.ClearField(group.FieldVideoPrice480p, field.TypeFloat64)
|
||||
}
|
||||
if value, ok := _u.mutation.VideoPrice720p(); ok {
|
||||
_spec.SetField(group.FieldVideoPrice720p, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedVideoPrice720p(); ok {
|
||||
_spec.AddField(group.FieldVideoPrice720p, field.TypeFloat64, value)
|
||||
}
|
||||
if _u.mutation.VideoPrice720pCleared() {
|
||||
_spec.ClearField(group.FieldVideoPrice720p, field.TypeFloat64)
|
||||
}
|
||||
if value, ok := _u.mutation.VideoPrice1080p(); ok {
|
||||
_spec.SetField(group.FieldVideoPrice1080p, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedVideoPrice1080p(); ok {
|
||||
_spec.AddField(group.FieldVideoPrice1080p, field.TypeFloat64, value)
|
||||
}
|
||||
if _u.mutation.VideoPrice1080pCleared() {
|
||||
_spec.ClearField(group.FieldVideoPrice1080p, field.TypeFloat64)
|
||||
}
|
||||
if value, ok := _u.mutation.WebSearchPricePerCall(); ok {
|
||||
_spec.SetField(group.FieldWebSearchPricePerCall, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedWebSearchPricePerCall(); ok {
|
||||
_spec.AddField(group.FieldWebSearchPricePerCall, field.TypeFloat64, value)
|
||||
}
|
||||
if _u.mutation.WebSearchPricePerCallCleared() {
|
||||
_spec.ClearField(group.FieldWebSearchPricePerCall, field.TypeFloat64)
|
||||
}
|
||||
if value, ok := _u.mutation.ClaudeCodeOnly(); ok {
|
||||
_spec.SetField(group.FieldClaudeCodeOnly, field.TypeBool, value)
|
||||
}
|
||||
|
||||
@@ -93,6 +93,42 @@ func (f AuthIdentityChannelFunc) Mutate(ctx context.Context, m ent.Mutation) (en
|
||||
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.AuthIdentityChannelMutation", m)
|
||||
}
|
||||
|
||||
// The BatchImageEventFunc type is an adapter to allow the use of ordinary
|
||||
// function as BatchImageEvent mutator.
|
||||
type BatchImageEventFunc func(context.Context, *ent.BatchImageEventMutation) (ent.Value, error)
|
||||
|
||||
// Mutate calls f(ctx, m).
|
||||
func (f BatchImageEventFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
|
||||
if mv, ok := m.(*ent.BatchImageEventMutation); ok {
|
||||
return f(ctx, mv)
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.BatchImageEventMutation", m)
|
||||
}
|
||||
|
||||
// The BatchImageItemFunc type is an adapter to allow the use of ordinary
|
||||
// function as BatchImageItem mutator.
|
||||
type BatchImageItemFunc func(context.Context, *ent.BatchImageItemMutation) (ent.Value, error)
|
||||
|
||||
// Mutate calls f(ctx, m).
|
||||
func (f BatchImageItemFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
|
||||
if mv, ok := m.(*ent.BatchImageItemMutation); ok {
|
||||
return f(ctx, mv)
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.BatchImageItemMutation", m)
|
||||
}
|
||||
|
||||
// The BatchImageJobFunc type is an adapter to allow the use of ordinary
|
||||
// function as BatchImageJob mutator.
|
||||
type BatchImageJobFunc func(context.Context, *ent.BatchImageJobMutation) (ent.Value, error)
|
||||
|
||||
// Mutate calls f(ctx, m).
|
||||
func (f BatchImageJobFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
|
||||
if mv, ok := m.(*ent.BatchImageJobMutation); ok {
|
||||
return f(ctx, mv)
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.BatchImageJobMutation", m)
|
||||
}
|
||||
|
||||
// The ChannelMonitorFunc type is an adapter to allow the use of ordinary
|
||||
// function as ChannelMonitor mutator.
|
||||
type ChannelMonitorFunc func(context.Context, *ent.ChannelMonitorMutation) (ent.Value, error)
|
||||
|
||||
@@ -15,6 +15,9 @@ import (
|
||||
"github.com/Wei-Shaw/sub2api/ent/apikey"
|
||||
"github.com/Wei-Shaw/sub2api/ent/authidentity"
|
||||
"github.com/Wei-Shaw/sub2api/ent/authidentitychannel"
|
||||
"github.com/Wei-Shaw/sub2api/ent/batchimageevent"
|
||||
"github.com/Wei-Shaw/sub2api/ent/batchimageitem"
|
||||
"github.com/Wei-Shaw/sub2api/ent/batchimagejob"
|
||||
"github.com/Wei-Shaw/sub2api/ent/channelmonitor"
|
||||
"github.com/Wei-Shaw/sub2api/ent/channelmonitordailyrollup"
|
||||
"github.com/Wei-Shaw/sub2api/ent/channelmonitorhistory"
|
||||
@@ -291,6 +294,87 @@ func (f TraverseAuthIdentityChannel) Traverse(ctx context.Context, q ent.Query)
|
||||
return fmt.Errorf("unexpected query type %T. expect *ent.AuthIdentityChannelQuery", q)
|
||||
}
|
||||
|
||||
// The BatchImageEventFunc type is an adapter to allow the use of ordinary function as a Querier.
|
||||
type BatchImageEventFunc func(context.Context, *ent.BatchImageEventQuery) (ent.Value, error)
|
||||
|
||||
// Query calls f(ctx, q).
|
||||
func (f BatchImageEventFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
|
||||
if q, ok := q.(*ent.BatchImageEventQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected query type %T. expect *ent.BatchImageEventQuery", q)
|
||||
}
|
||||
|
||||
// The TraverseBatchImageEvent type is an adapter to allow the use of ordinary function as Traverser.
|
||||
type TraverseBatchImageEvent func(context.Context, *ent.BatchImageEventQuery) error
|
||||
|
||||
// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
|
||||
func (f TraverseBatchImageEvent) Intercept(next ent.Querier) ent.Querier {
|
||||
return next
|
||||
}
|
||||
|
||||
// Traverse calls f(ctx, q).
|
||||
func (f TraverseBatchImageEvent) Traverse(ctx context.Context, q ent.Query) error {
|
||||
if q, ok := q.(*ent.BatchImageEventQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return fmt.Errorf("unexpected query type %T. expect *ent.BatchImageEventQuery", q)
|
||||
}
|
||||
|
||||
// The BatchImageItemFunc type is an adapter to allow the use of ordinary function as a Querier.
|
||||
type BatchImageItemFunc func(context.Context, *ent.BatchImageItemQuery) (ent.Value, error)
|
||||
|
||||
// Query calls f(ctx, q).
|
||||
func (f BatchImageItemFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
|
||||
if q, ok := q.(*ent.BatchImageItemQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected query type %T. expect *ent.BatchImageItemQuery", q)
|
||||
}
|
||||
|
||||
// The TraverseBatchImageItem type is an adapter to allow the use of ordinary function as Traverser.
|
||||
type TraverseBatchImageItem func(context.Context, *ent.BatchImageItemQuery) error
|
||||
|
||||
// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
|
||||
func (f TraverseBatchImageItem) Intercept(next ent.Querier) ent.Querier {
|
||||
return next
|
||||
}
|
||||
|
||||
// Traverse calls f(ctx, q).
|
||||
func (f TraverseBatchImageItem) Traverse(ctx context.Context, q ent.Query) error {
|
||||
if q, ok := q.(*ent.BatchImageItemQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return fmt.Errorf("unexpected query type %T. expect *ent.BatchImageItemQuery", q)
|
||||
}
|
||||
|
||||
// The BatchImageJobFunc type is an adapter to allow the use of ordinary function as a Querier.
|
||||
type BatchImageJobFunc func(context.Context, *ent.BatchImageJobQuery) (ent.Value, error)
|
||||
|
||||
// Query calls f(ctx, q).
|
||||
func (f BatchImageJobFunc) Query(ctx context.Context, q ent.Query) (ent.Value, error) {
|
||||
if q, ok := q.(*ent.BatchImageJobQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return nil, fmt.Errorf("unexpected query type %T. expect *ent.BatchImageJobQuery", q)
|
||||
}
|
||||
|
||||
// The TraverseBatchImageJob type is an adapter to allow the use of ordinary function as Traverser.
|
||||
type TraverseBatchImageJob func(context.Context, *ent.BatchImageJobQuery) error
|
||||
|
||||
// Intercept is a dummy implementation of Intercept that returns the next Querier in the pipeline.
|
||||
func (f TraverseBatchImageJob) Intercept(next ent.Querier) ent.Querier {
|
||||
return next
|
||||
}
|
||||
|
||||
// Traverse calls f(ctx, q).
|
||||
func (f TraverseBatchImageJob) Traverse(ctx context.Context, q ent.Query) error {
|
||||
if q, ok := q.(*ent.BatchImageJobQuery); ok {
|
||||
return f(ctx, q)
|
||||
}
|
||||
return fmt.Errorf("unexpected query type %T. expect *ent.BatchImageJobQuery", q)
|
||||
}
|
||||
|
||||
// The ChannelMonitorFunc type is an adapter to allow the use of ordinary function as a Querier.
|
||||
type ChannelMonitorFunc func(context.Context, *ent.ChannelMonitorQuery) (ent.Value, error)
|
||||
|
||||
@@ -1064,6 +1148,12 @@ func NewQuery(q ent.Query) (Query, error) {
|
||||
return &query[*ent.AuthIdentityQuery, predicate.AuthIdentity, authidentity.OrderOption]{typ: ent.TypeAuthIdentity, tq: q}, nil
|
||||
case *ent.AuthIdentityChannelQuery:
|
||||
return &query[*ent.AuthIdentityChannelQuery, predicate.AuthIdentityChannel, authidentitychannel.OrderOption]{typ: ent.TypeAuthIdentityChannel, tq: q}, nil
|
||||
case *ent.BatchImageEventQuery:
|
||||
return &query[*ent.BatchImageEventQuery, predicate.BatchImageEvent, batchimageevent.OrderOption]{typ: ent.TypeBatchImageEvent, tq: q}, nil
|
||||
case *ent.BatchImageItemQuery:
|
||||
return &query[*ent.BatchImageItemQuery, predicate.BatchImageItem, batchimageitem.OrderOption]{typ: ent.TypeBatchImageItem, tq: q}, nil
|
||||
case *ent.BatchImageJobQuery:
|
||||
return &query[*ent.BatchImageJobQuery, predicate.BatchImageJob, batchimagejob.OrderOption]{typ: ent.TypeBatchImageJob, tq: q}, nil
|
||||
case *ent.ChannelMonitorQuery:
|
||||
return &query[*ent.ChannelMonitorQuery, predicate.ChannelMonitor, channelmonitor.OrderOption]{typ: ent.TypeChannelMonitor, tq: q}, nil
|
||||
case *ent.ChannelMonitorDailyRollupQuery:
|
||||
|
||||
@@ -46,6 +46,16 @@ func TestPaymentOrdersOutTradeNoPartialUniqueIndex(t *testing.T) {
|
||||
require.Equal(t, (&entsql.IndexAnnotation{Where: "out_trade_no <> ''"}).Where, idx.Annotation.Where)
|
||||
}
|
||||
|
||||
func TestAccountsParentAccountForeignKey(t *testing.T) {
|
||||
fk := findForeignKeyByColumn(t, AccountsTable, "parent_account_id")
|
||||
require.Len(t, fk.Columns, 1)
|
||||
require.Equal(t, "parent_account_id", fk.Columns[0].Name)
|
||||
require.False(t, fk.Columns[0].Unique, "active-shadow uniqueness is enforced by the partial uq_accounts_spark_shadow_per_parent index")
|
||||
require.Len(t, fk.RefColumns, 1)
|
||||
require.Equal(t, "id", fk.RefColumns[0].Name)
|
||||
require.Equal(t, entschema.Restrict, fk.OnDelete)
|
||||
}
|
||||
|
||||
func findForeignKeyBySymbol(t *testing.T, table *entschema.Table, symbol string) *entschema.ForeignKey {
|
||||
t.Helper()
|
||||
|
||||
@@ -71,3 +81,18 @@ func findIndexByName(t *testing.T, table *entschema.Table, name string) *entsche
|
||||
require.Failf(t, "missing index", "table %s should include index %s", table.Name, name)
|
||||
return nil
|
||||
}
|
||||
|
||||
func findForeignKeyByColumn(t *testing.T, table *entschema.Table, column string) *entschema.ForeignKey {
|
||||
t.Helper()
|
||||
|
||||
for _, fk := range table.ForeignKeys {
|
||||
for _, col := range fk.Columns {
|
||||
if col.Name == column {
|
||||
return fk
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
require.Failf(t, "missing foreign key", "table %s should include foreign key for column %s", table.Name, column)
|
||||
return nil
|
||||
}
|
||||
|
||||
+250
-24
@@ -124,7 +124,9 @@ var (
|
||||
{Name: "session_window_start", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "session_window_end", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "session_window_status", Type: field.TypeString, Nullable: true, Size: 20},
|
||||
{Name: "quota_dimension", Type: field.TypeEnum, Enums: []string{"global", "spark"}, Default: "global"},
|
||||
{Name: "proxy_id", Type: field.TypeInt64, Nullable: true},
|
||||
{Name: "parent_account_id", Type: field.TypeInt64, Nullable: true},
|
||||
}
|
||||
// AccountsTable holds the schema information for the "accounts" table.
|
||||
AccountsTable = &schema.Table{
|
||||
@@ -134,10 +136,16 @@ var (
|
||||
ForeignKeys: []*schema.ForeignKey{
|
||||
{
|
||||
Symbol: "accounts_proxies_proxy",
|
||||
Columns: []*schema.Column{AccountsColumns[29]},
|
||||
Columns: []*schema.Column{AccountsColumns[30]},
|
||||
RefColumns: []*schema.Column{ProxiesColumns[0]},
|
||||
OnDelete: schema.SetNull,
|
||||
},
|
||||
{
|
||||
Symbol: "accounts_accounts_children",
|
||||
Columns: []*schema.Column{AccountsColumns[31]},
|
||||
RefColumns: []*schema.Column{AccountsColumns[0]},
|
||||
OnDelete: schema.Restrict,
|
||||
},
|
||||
},
|
||||
Indexes: []*schema.Index{
|
||||
{
|
||||
@@ -158,7 +166,7 @@ var (
|
||||
{
|
||||
Name: "account_proxy_id",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{AccountsColumns[29]},
|
||||
Columns: []*schema.Column{AccountsColumns[30]},
|
||||
},
|
||||
{
|
||||
Name: "account_priority",
|
||||
@@ -205,6 +213,11 @@ var (
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{AccountsColumns[3]},
|
||||
},
|
||||
{
|
||||
Name: "account_parent_account_id",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{AccountsColumns[31]},
|
||||
},
|
||||
},
|
||||
}
|
||||
// AccountGroupsColumns holds the columns for the "account_groups" table.
|
||||
@@ -422,13 +435,195 @@ var (
|
||||
},
|
||||
},
|
||||
}
|
||||
// BatchImageEventsColumns holds the columns for the "batch_image_events" table.
|
||||
BatchImageEventsColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt64, Increment: true},
|
||||
{Name: "job_id", Type: field.TypeString, Size: 64},
|
||||
{Name: "event_type", Type: field.TypeString, Size: 64},
|
||||
{Name: "payload", Type: field.TypeJSON, Nullable: true, SchemaType: map[string]string{"postgres": "jsonb"}},
|
||||
{Name: "event_hash", Type: field.TypeString, Nullable: true, Size: 128},
|
||||
{Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
}
|
||||
// BatchImageEventsTable holds the schema information for the "batch_image_events" table.
|
||||
BatchImageEventsTable = &schema.Table{
|
||||
Name: "batch_image_events",
|
||||
Columns: BatchImageEventsColumns,
|
||||
PrimaryKey: []*schema.Column{BatchImageEventsColumns[0]},
|
||||
Indexes: []*schema.Index{
|
||||
{
|
||||
Name: "batchimageevent_job_id_created_at",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{BatchImageEventsColumns[1], BatchImageEventsColumns[5]},
|
||||
},
|
||||
{
|
||||
Name: "batchimageevent_event_type",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{BatchImageEventsColumns[2]},
|
||||
},
|
||||
{
|
||||
Name: "batchimageevent_job_id_event_hash",
|
||||
Unique: true,
|
||||
Columns: []*schema.Column{BatchImageEventsColumns[1], BatchImageEventsColumns[4]},
|
||||
Annotation: &entsql.IndexAnnotation{
|
||||
Where: "event_hash IS NOT NULL AND event_hash <> ''",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
// BatchImageItemsColumns holds the columns for the "batch_image_items" table.
|
||||
BatchImageItemsColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt64, Increment: true},
|
||||
{Name: "job_id", Type: field.TypeString, Size: 64},
|
||||
{Name: "custom_id", Type: field.TypeString, Size: 255},
|
||||
{Name: "status", Type: field.TypeString, Size: 32},
|
||||
{Name: "request_hash", Type: field.TypeString, Nullable: true, Size: 128},
|
||||
{Name: "prompt_preview", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}},
|
||||
{Name: "provider_source_object", Type: field.TypeString, Nullable: true, Size: 1024},
|
||||
{Name: "source_line_number", Type: field.TypeInt, Nullable: true},
|
||||
{Name: "source_byte_offset", Type: field.TypeInt64, Nullable: true},
|
||||
{Name: "source_byte_length", Type: field.TypeInt64, Nullable: true},
|
||||
{Name: "mime_type", Type: field.TypeString, Nullable: true, Size: 128},
|
||||
{Name: "file_extension", Type: field.TypeString, Nullable: true, Size: 32},
|
||||
{Name: "image_count", Type: field.TypeInt, Default: 0},
|
||||
{Name: "error_code", Type: field.TypeString, Nullable: true, Size: 128},
|
||||
{Name: "error_message", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}},
|
||||
{Name: "billed_amount", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,10)"}},
|
||||
{Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "indexed_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
}
|
||||
// BatchImageItemsTable holds the schema information for the "batch_image_items" table.
|
||||
BatchImageItemsTable = &schema.Table{
|
||||
Name: "batch_image_items",
|
||||
Columns: BatchImageItemsColumns,
|
||||
PrimaryKey: []*schema.Column{BatchImageItemsColumns[0]},
|
||||
Indexes: []*schema.Index{
|
||||
{
|
||||
Name: "batchimageitem_job_id_custom_id",
|
||||
Unique: true,
|
||||
Columns: []*schema.Column{BatchImageItemsColumns[1], BatchImageItemsColumns[2]},
|
||||
},
|
||||
{
|
||||
Name: "batchimageitem_job_id_status",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{BatchImageItemsColumns[1], BatchImageItemsColumns[3]},
|
||||
},
|
||||
{
|
||||
Name: "batchimageitem_provider_source_object",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{BatchImageItemsColumns[6]},
|
||||
},
|
||||
},
|
||||
}
|
||||
// BatchImageJobsColumns holds the columns for the "batch_image_jobs" table.
|
||||
BatchImageJobsColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt64, Increment: true},
|
||||
{Name: "batch_id", Type: field.TypeString, Size: 64},
|
||||
{Name: "user_id", Type: field.TypeInt64},
|
||||
{Name: "api_key_id", Type: field.TypeInt64, Nullable: true},
|
||||
{Name: "account_id", Type: field.TypeInt64, Nullable: true},
|
||||
{Name: "provider", Type: field.TypeString, Size: 32},
|
||||
{Name: "model", Type: field.TypeString, Size: 128},
|
||||
{Name: "task_name", Type: field.TypeString, Size: 255, Default: ""},
|
||||
{Name: "status", Type: field.TypeString, Size: 32, Default: "created"},
|
||||
{Name: "provider_job_name", Type: field.TypeString, Nullable: true, Size: 512},
|
||||
{Name: "provider_input_ref", Type: field.TypeString, Nullable: true, Size: 1024},
|
||||
{Name: "provider_output_ref", Type: field.TypeString, Nullable: true, Size: 1024},
|
||||
{Name: "gcs_input_uri", Type: field.TypeString, Nullable: true, Size: 1024},
|
||||
{Name: "gcs_output_uri", Type: field.TypeString, Nullable: true, Size: 1024},
|
||||
{Name: "item_count", Type: field.TypeInt},
|
||||
{Name: "success_count", Type: field.TypeInt, Default: 0},
|
||||
{Name: "fail_count", Type: field.TypeInt, Default: 0},
|
||||
{Name: "cancelled_count", Type: field.TypeInt, Default: 0},
|
||||
{Name: "estimated_cost", Type: field.TypeFloat64, Default: 0, SchemaType: map[string]string{"postgres": "decimal(20,10)"}},
|
||||
{Name: "hold_amount", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,10)"}},
|
||||
{Name: "actual_cost", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,10)"}},
|
||||
{Name: "currency", Type: field.TypeString, Size: 16, Default: "USD"},
|
||||
{Name: "hold_id", Type: field.TypeString, Nullable: true, Size: 128},
|
||||
{Name: "idempotency_key", Type: field.TypeString, Nullable: true, Size: 255},
|
||||
{Name: "request_hash", Type: field.TypeString, Nullable: true, Size: 128},
|
||||
{Name: "manifest_hash", Type: field.TypeString, Nullable: true, Size: 128},
|
||||
{Name: "retry_count", Type: field.TypeInt, Default: 0},
|
||||
{Name: "version", Type: field.TypeInt, Default: 0},
|
||||
{Name: "output_expires_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "input_deleted_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "output_deleted_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "downloaded_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "user_deleted_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "last_error_code", Type: field.TypeString, Nullable: true, Size: 128},
|
||||
{Name: "last_error_message", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}},
|
||||
{Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "updated_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "submitted_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "started_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "finished_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "settled_at", Type: field.TypeTime, Nullable: true, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
}
|
||||
// BatchImageJobsTable holds the schema information for the "batch_image_jobs" table.
|
||||
BatchImageJobsTable = &schema.Table{
|
||||
Name: "batch_image_jobs",
|
||||
Columns: BatchImageJobsColumns,
|
||||
PrimaryKey: []*schema.Column{BatchImageJobsColumns[0]},
|
||||
Indexes: []*schema.Index{
|
||||
{
|
||||
Name: "batchimagejob_batch_id",
|
||||
Unique: true,
|
||||
Columns: []*schema.Column{BatchImageJobsColumns[1]},
|
||||
},
|
||||
{
|
||||
Name: "batchimagejob_user_id_created_at",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{BatchImageJobsColumns[2], BatchImageJobsColumns[35]},
|
||||
},
|
||||
{
|
||||
Name: "batchimagejob_status",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{BatchImageJobsColumns[8]},
|
||||
},
|
||||
{
|
||||
Name: "batchimagejob_provider_status",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{BatchImageJobsColumns[5], BatchImageJobsColumns[8]},
|
||||
},
|
||||
{
|
||||
Name: "batchimagejob_idempotency_key",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{BatchImageJobsColumns[23]},
|
||||
Annotation: &entsql.IndexAnnotation{
|
||||
Where: "idempotency_key IS NOT NULL AND idempotency_key <> ''",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "batchimagejob_manifest_hash",
|
||||
Unique: true,
|
||||
Columns: []*schema.Column{BatchImageJobsColumns[25]},
|
||||
Annotation: &entsql.IndexAnnotation{
|
||||
Where: "manifest_hash IS NOT NULL AND manifest_hash <> ''",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "batchimagejob_output_expires_at",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{BatchImageJobsColumns[28]},
|
||||
},
|
||||
{
|
||||
Name: "batchimagejob_downloaded_at",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{BatchImageJobsColumns[31]},
|
||||
},
|
||||
{
|
||||
Name: "batchimagejob_user_deleted_at",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{BatchImageJobsColumns[32]},
|
||||
},
|
||||
},
|
||||
}
|
||||
// ChannelMonitorsColumns holds the columns for the "channel_monitors" table.
|
||||
ChannelMonitorsColumns = []*schema.Column{
|
||||
{Name: "id", Type: field.TypeInt64, Increment: true},
|
||||
{Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "updated_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "name", Type: field.TypeString, Size: 100},
|
||||
{Name: "provider", Type: field.TypeEnum, Enums: []string{"openai", "anthropic", "gemini"}},
|
||||
{Name: "provider", Type: field.TypeEnum, Enums: []string{"openai", "anthropic", "gemini", "grok"}},
|
||||
{Name: "api_mode", Type: field.TypeString, Size: 32, Default: "chat_completions"},
|
||||
{Name: "endpoint", Type: field.TypeString, Size: 500},
|
||||
{Name: "api_key_encrypted", Type: field.TypeString},
|
||||
@@ -573,7 +768,7 @@ var (
|
||||
{Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "updated_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "name", Type: field.TypeString, Size: 100},
|
||||
{Name: "provider", Type: field.TypeEnum, Enums: []string{"openai", "anthropic", "gemini"}},
|
||||
{Name: "provider", Type: field.TypeEnum, Enums: []string{"openai", "anthropic", "gemini", "grok"}},
|
||||
{Name: "api_mode", Type: field.TypeString, Size: 32, Default: "chat_completions"},
|
||||
{Name: "description", Type: field.TypeString, Nullable: true, Size: 500, Default: ""},
|
||||
{Name: "extra_headers", Type: field.TypeJSON},
|
||||
@@ -644,6 +839,10 @@ var (
|
||||
{Name: "name", Type: field.TypeString, Size: 100},
|
||||
{Name: "description", Type: field.TypeString, Nullable: true, SchemaType: map[string]string{"postgres": "text"}},
|
||||
{Name: "rate_multiplier", Type: field.TypeFloat64, Default: 1, SchemaType: map[string]string{"postgres": "decimal(10,4)"}},
|
||||
{Name: "peak_rate_enabled", Type: field.TypeBool, Default: false},
|
||||
{Name: "peak_start", Type: field.TypeString, Size: 5, Default: ""},
|
||||
{Name: "peak_end", Type: field.TypeString, Size: 5, Default: ""},
|
||||
{Name: "peak_rate_multiplier", Type: field.TypeFloat64, Default: 1, SchemaType: map[string]string{"postgres": "decimal(10,4)"}},
|
||||
{Name: "is_exclusive", Type: field.TypeBool, Default: false},
|
||||
{Name: "status", Type: field.TypeString, Size: 20, Default: "active"},
|
||||
{Name: "platform", Type: field.TypeString, Size: 50, Default: "anthropic"},
|
||||
@@ -653,11 +852,20 @@ var (
|
||||
{Name: "monthly_limit_usd", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,8)"}},
|
||||
{Name: "default_validity_days", Type: field.TypeInt, Default: 30},
|
||||
{Name: "allow_image_generation", Type: field.TypeBool, Default: false},
|
||||
{Name: "allow_batch_image_generation", Type: field.TypeBool, Default: false},
|
||||
{Name: "image_rate_independent", Type: field.TypeBool, Default: false},
|
||||
{Name: "image_rate_multiplier", Type: field.TypeFloat64, Default: 1, SchemaType: map[string]string{"postgres": "decimal(10,4)"}},
|
||||
{Name: "image_price_1k", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,8)"}},
|
||||
{Name: "image_price_2k", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,8)"}},
|
||||
{Name: "image_price_4k", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,8)"}},
|
||||
{Name: "batch_image_discount_multiplier", Type: field.TypeFloat64, Default: 0.5, SchemaType: map[string]string{"postgres": "decimal(10,4)"}},
|
||||
{Name: "batch_image_hold_multiplier", Type: field.TypeFloat64, Default: 0.6, SchemaType: map[string]string{"postgres": "decimal(10,4)"}},
|
||||
{Name: "video_rate_independent", Type: field.TypeBool, Default: false},
|
||||
{Name: "video_rate_multiplier", Type: field.TypeFloat64, Default: 1, SchemaType: map[string]string{"postgres": "decimal(10,4)"}},
|
||||
{Name: "video_price_480p", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,8)"}},
|
||||
{Name: "video_price_720p", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,8)"}},
|
||||
{Name: "video_price_1080p", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,8)"}},
|
||||
{Name: "web_search_price_per_call", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(20,8)"}},
|
||||
{Name: "claude_code_only", Type: field.TypeBool, Default: false},
|
||||
{Name: "fallback_group_id", Type: field.TypeInt64, Nullable: true},
|
||||
{Name: "fallback_group_id_on_invalid_request", Type: field.TypeInt64, Nullable: true},
|
||||
@@ -683,22 +891,22 @@ var (
|
||||
{
|
||||
Name: "group_status",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{GroupsColumns[8]},
|
||||
Columns: []*schema.Column{GroupsColumns[12]},
|
||||
},
|
||||
{
|
||||
Name: "group_platform",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{GroupsColumns[9]},
|
||||
Columns: []*schema.Column{GroupsColumns[13]},
|
||||
},
|
||||
{
|
||||
Name: "group_subscription_type",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{GroupsColumns[10]},
|
||||
Columns: []*schema.Column{GroupsColumns[14]},
|
||||
},
|
||||
{
|
||||
Name: "group_is_exclusive",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{GroupsColumns[7]},
|
||||
Columns: []*schema.Column{GroupsColumns[11]},
|
||||
},
|
||||
{
|
||||
Name: "group_deleted_at",
|
||||
@@ -708,7 +916,7 @@ var (
|
||||
{
|
||||
Name: "group_sort_order",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{GroupsColumns[28]},
|
||||
Columns: []*schema.Column{GroupsColumns[41]},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1352,6 +1560,7 @@ var (
|
||||
{Name: "total_cost", Type: field.TypeFloat64, Default: 0, SchemaType: map[string]string{"postgres": "decimal(20,10)"}},
|
||||
{Name: "actual_cost", Type: field.TypeFloat64, Default: 0, SchemaType: map[string]string{"postgres": "decimal(20,10)"}},
|
||||
{Name: "rate_multiplier", Type: field.TypeFloat64, Default: 1, SchemaType: map[string]string{"postgres": "decimal(10,4)"}},
|
||||
{Name: "long_context_billing_applied", Type: field.TypeBool, Default: false},
|
||||
{Name: "account_rate_multiplier", Type: field.TypeFloat64, Nullable: true, SchemaType: map[string]string{"postgres": "decimal(10,4)"}},
|
||||
{Name: "billing_type", Type: field.TypeInt8, Default: 0},
|
||||
{Name: "stream", Type: field.TypeBool, Default: false},
|
||||
@@ -1365,6 +1574,9 @@ var (
|
||||
{Name: "image_output_size", Type: field.TypeString, Nullable: true, Size: 32},
|
||||
{Name: "image_size_source", Type: field.TypeString, Nullable: true, Size: 16},
|
||||
{Name: "image_size_breakdown", Type: field.TypeJSON, Nullable: true, SchemaType: map[string]string{"postgres": "jsonb"}},
|
||||
{Name: "video_count", Type: field.TypeInt, Default: 0},
|
||||
{Name: "video_resolution", Type: field.TypeString, Nullable: true, Size: 10},
|
||||
{Name: "video_duration_seconds", Type: field.TypeInt, Nullable: true},
|
||||
{Name: "cache_ttl_overridden", Type: field.TypeBool, Default: false},
|
||||
{Name: "created_at", Type: field.TypeTime, SchemaType: map[string]string{"postgres": "timestamptz"}},
|
||||
{Name: "api_key_id", Type: field.TypeInt64},
|
||||
@@ -1381,31 +1593,31 @@ var (
|
||||
ForeignKeys: []*schema.ForeignKey{
|
||||
{
|
||||
Symbol: "usage_logs_api_keys_usage_logs",
|
||||
Columns: []*schema.Column{UsageLogsColumns[37]},
|
||||
Columns: []*schema.Column{UsageLogsColumns[41]},
|
||||
RefColumns: []*schema.Column{APIKeysColumns[0]},
|
||||
OnDelete: schema.NoAction,
|
||||
},
|
||||
{
|
||||
Symbol: "usage_logs_accounts_usage_logs",
|
||||
Columns: []*schema.Column{UsageLogsColumns[38]},
|
||||
Columns: []*schema.Column{UsageLogsColumns[42]},
|
||||
RefColumns: []*schema.Column{AccountsColumns[0]},
|
||||
OnDelete: schema.NoAction,
|
||||
},
|
||||
{
|
||||
Symbol: "usage_logs_groups_usage_logs",
|
||||
Columns: []*schema.Column{UsageLogsColumns[39]},
|
||||
Columns: []*schema.Column{UsageLogsColumns[43]},
|
||||
RefColumns: []*schema.Column{GroupsColumns[0]},
|
||||
OnDelete: schema.SetNull,
|
||||
},
|
||||
{
|
||||
Symbol: "usage_logs_users_usage_logs",
|
||||
Columns: []*schema.Column{UsageLogsColumns[40]},
|
||||
Columns: []*schema.Column{UsageLogsColumns[44]},
|
||||
RefColumns: []*schema.Column{UsersColumns[0]},
|
||||
OnDelete: schema.NoAction,
|
||||
},
|
||||
{
|
||||
Symbol: "usage_logs_user_subscriptions_usage_logs",
|
||||
Columns: []*schema.Column{UsageLogsColumns[41]},
|
||||
Columns: []*schema.Column{UsageLogsColumns[45]},
|
||||
RefColumns: []*schema.Column{UserSubscriptionsColumns[0]},
|
||||
OnDelete: schema.SetNull,
|
||||
},
|
||||
@@ -1414,32 +1626,32 @@ var (
|
||||
{
|
||||
Name: "usagelog_user_id",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{UsageLogsColumns[40]},
|
||||
Columns: []*schema.Column{UsageLogsColumns[44]},
|
||||
},
|
||||
{
|
||||
Name: "usagelog_api_key_id",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{UsageLogsColumns[37]},
|
||||
Columns: []*schema.Column{UsageLogsColumns[41]},
|
||||
},
|
||||
{
|
||||
Name: "usagelog_account_id",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{UsageLogsColumns[38]},
|
||||
Columns: []*schema.Column{UsageLogsColumns[42]},
|
||||
},
|
||||
{
|
||||
Name: "usagelog_group_id",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{UsageLogsColumns[39]},
|
||||
Columns: []*schema.Column{UsageLogsColumns[43]},
|
||||
},
|
||||
{
|
||||
Name: "usagelog_subscription_id",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{UsageLogsColumns[41]},
|
||||
Columns: []*schema.Column{UsageLogsColumns[45]},
|
||||
},
|
||||
{
|
||||
Name: "usagelog_created_at",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{UsageLogsColumns[36]},
|
||||
Columns: []*schema.Column{UsageLogsColumns[40]},
|
||||
},
|
||||
{
|
||||
Name: "usagelog_model",
|
||||
@@ -1459,17 +1671,17 @@ var (
|
||||
{
|
||||
Name: "usagelog_user_id_created_at",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{UsageLogsColumns[40], UsageLogsColumns[36]},
|
||||
Columns: []*schema.Column{UsageLogsColumns[44], UsageLogsColumns[40]},
|
||||
},
|
||||
{
|
||||
Name: "usagelog_api_key_id_created_at",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{UsageLogsColumns[37], UsageLogsColumns[36]},
|
||||
Columns: []*schema.Column{UsageLogsColumns[41], UsageLogsColumns[40]},
|
||||
},
|
||||
{
|
||||
Name: "usagelog_group_id_created_at",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{UsageLogsColumns[39], UsageLogsColumns[36]},
|
||||
Columns: []*schema.Column{UsageLogsColumns[43], UsageLogsColumns[40]},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1483,6 +1695,7 @@ var (
|
||||
{Name: "password_hash", Type: field.TypeString, Size: 255},
|
||||
{Name: "role", Type: field.TypeString, Size: 20, Default: "user"},
|
||||
{Name: "balance", Type: field.TypeFloat64, Default: 0, SchemaType: map[string]string{"postgres": "decimal(20,8)"}},
|
||||
{Name: "frozen_balance", Type: field.TypeFloat64, Default: 0, SchemaType: map[string]string{"postgres": "decimal(20,8)"}},
|
||||
{Name: "concurrency", Type: field.TypeInt, Default: 5},
|
||||
{Name: "status", Type: field.TypeString, Size: 20, Default: "active"},
|
||||
{Name: "username", Type: field.TypeString, Size: 100, Default: ""},
|
||||
@@ -1509,7 +1722,7 @@ var (
|
||||
{
|
||||
Name: "user_status",
|
||||
Unique: false,
|
||||
Columns: []*schema.Column{UsersColumns[9]},
|
||||
Columns: []*schema.Column{UsersColumns[10]},
|
||||
},
|
||||
{
|
||||
Name: "user_deleted_at",
|
||||
@@ -1782,6 +1995,9 @@ var (
|
||||
AnnouncementReadsTable,
|
||||
AuthIdentitiesTable,
|
||||
AuthIdentityChannelsTable,
|
||||
BatchImageEventsTable,
|
||||
BatchImageItemsTable,
|
||||
BatchImageJobsTable,
|
||||
ChannelMonitorsTable,
|
||||
ChannelMonitorDailyRollupsTable,
|
||||
ChannelMonitorHistoriesTable,
|
||||
@@ -1820,6 +2036,7 @@ func init() {
|
||||
Table: "api_keys",
|
||||
}
|
||||
AccountsTable.ForeignKeys[0].RefTable = ProxiesTable
|
||||
AccountsTable.ForeignKeys[1].RefTable = AccountsTable
|
||||
AccountsTable.Annotation = &entsql.Annotation{
|
||||
Table: "accounts",
|
||||
}
|
||||
@@ -1844,6 +2061,15 @@ func init() {
|
||||
AuthIdentityChannelsTable.Annotation = &entsql.Annotation{
|
||||
Table: "auth_identity_channels",
|
||||
}
|
||||
BatchImageEventsTable.Annotation = &entsql.Annotation{
|
||||
Table: "batch_image_events",
|
||||
}
|
||||
BatchImageItemsTable.Annotation = &entsql.Annotation{
|
||||
Table: "batch_image_items",
|
||||
}
|
||||
BatchImageJobsTable.Annotation = &entsql.Annotation{
|
||||
Table: "batch_image_jobs",
|
||||
}
|
||||
ChannelMonitorsTable.ForeignKeys[0].RefTable = ChannelMonitorRequestTemplatesTable
|
||||
ChannelMonitorsTable.Annotation = &entsql.Annotation{
|
||||
Table: "channel_monitors",
|
||||
|
||||
+7278
-79
File diff suppressed because it is too large
Load Diff
@@ -27,6 +27,15 @@ type AuthIdentity func(*sql.Selector)
|
||||
// AuthIdentityChannel is the predicate function for authidentitychannel builders.
|
||||
type AuthIdentityChannel func(*sql.Selector)
|
||||
|
||||
// BatchImageEvent is the predicate function for batchimageevent builders.
|
||||
type BatchImageEvent func(*sql.Selector)
|
||||
|
||||
// BatchImageItem is the predicate function for batchimageitem builders.
|
||||
type BatchImageItem func(*sql.Selector)
|
||||
|
||||
// BatchImageJob is the predicate function for batchimagejob builders.
|
||||
type BatchImageJob func(*sql.Selector)
|
||||
|
||||
// ChannelMonitor is the predicate function for channelmonitor builders.
|
||||
type ChannelMonitor func(*sql.Selector)
|
||||
|
||||
|
||||
+267
-42
@@ -12,6 +12,9 @@ import (
|
||||
"github.com/Wei-Shaw/sub2api/ent/apikey"
|
||||
"github.com/Wei-Shaw/sub2api/ent/authidentity"
|
||||
"github.com/Wei-Shaw/sub2api/ent/authidentitychannel"
|
||||
"github.com/Wei-Shaw/sub2api/ent/batchimageevent"
|
||||
"github.com/Wei-Shaw/sub2api/ent/batchimageitem"
|
||||
"github.com/Wei-Shaw/sub2api/ent/batchimagejob"
|
||||
"github.com/Wei-Shaw/sub2api/ent/channelmonitor"
|
||||
"github.com/Wei-Shaw/sub2api/ent/channelmonitordailyrollup"
|
||||
"github.com/Wei-Shaw/sub2api/ent/channelmonitorhistory"
|
||||
@@ -432,6 +435,172 @@ func init() {
|
||||
authidentitychannelDescMetadata := authidentitychannelFields[6].Descriptor()
|
||||
// authidentitychannel.DefaultMetadata holds the default value on creation for the metadata field.
|
||||
authidentitychannel.DefaultMetadata = authidentitychannelDescMetadata.Default.(func() map[string]interface{})
|
||||
batchimageeventFields := schema.BatchImageEvent{}.Fields()
|
||||
_ = batchimageeventFields
|
||||
// batchimageeventDescJobID is the schema descriptor for job_id field.
|
||||
batchimageeventDescJobID := batchimageeventFields[0].Descriptor()
|
||||
// batchimageevent.JobIDValidator is a validator for the "job_id" field. It is called by the builders before save.
|
||||
batchimageevent.JobIDValidator = batchimageeventDescJobID.Validators[0].(func(string) error)
|
||||
// batchimageeventDescEventType is the schema descriptor for event_type field.
|
||||
batchimageeventDescEventType := batchimageeventFields[1].Descriptor()
|
||||
// batchimageevent.EventTypeValidator is a validator for the "event_type" field. It is called by the builders before save.
|
||||
batchimageevent.EventTypeValidator = batchimageeventDescEventType.Validators[0].(func(string) error)
|
||||
// batchimageeventDescEventHash is the schema descriptor for event_hash field.
|
||||
batchimageeventDescEventHash := batchimageeventFields[3].Descriptor()
|
||||
// batchimageevent.EventHashValidator is a validator for the "event_hash" field. It is called by the builders before save.
|
||||
batchimageevent.EventHashValidator = batchimageeventDescEventHash.Validators[0].(func(string) error)
|
||||
// batchimageeventDescCreatedAt is the schema descriptor for created_at field.
|
||||
batchimageeventDescCreatedAt := batchimageeventFields[4].Descriptor()
|
||||
// batchimageevent.DefaultCreatedAt holds the default value on creation for the created_at field.
|
||||
batchimageevent.DefaultCreatedAt = batchimageeventDescCreatedAt.Default.(func() time.Time)
|
||||
batchimageitemFields := schema.BatchImageItem{}.Fields()
|
||||
_ = batchimageitemFields
|
||||
// batchimageitemDescJobID is the schema descriptor for job_id field.
|
||||
batchimageitemDescJobID := batchimageitemFields[0].Descriptor()
|
||||
// batchimageitem.JobIDValidator is a validator for the "job_id" field. It is called by the builders before save.
|
||||
batchimageitem.JobIDValidator = batchimageitemDescJobID.Validators[0].(func(string) error)
|
||||
// batchimageitemDescCustomID is the schema descriptor for custom_id field.
|
||||
batchimageitemDescCustomID := batchimageitemFields[1].Descriptor()
|
||||
// batchimageitem.CustomIDValidator is a validator for the "custom_id" field. It is called by the builders before save.
|
||||
batchimageitem.CustomIDValidator = batchimageitemDescCustomID.Validators[0].(func(string) error)
|
||||
// batchimageitemDescStatus is the schema descriptor for status field.
|
||||
batchimageitemDescStatus := batchimageitemFields[2].Descriptor()
|
||||
// batchimageitem.StatusValidator is a validator for the "status" field. It is called by the builders before save.
|
||||
batchimageitem.StatusValidator = batchimageitemDescStatus.Validators[0].(func(string) error)
|
||||
// batchimageitemDescRequestHash is the schema descriptor for request_hash field.
|
||||
batchimageitemDescRequestHash := batchimageitemFields[3].Descriptor()
|
||||
// batchimageitem.RequestHashValidator is a validator for the "request_hash" field. It is called by the builders before save.
|
||||
batchimageitem.RequestHashValidator = batchimageitemDescRequestHash.Validators[0].(func(string) error)
|
||||
// batchimageitemDescProviderSourceObject is the schema descriptor for provider_source_object field.
|
||||
batchimageitemDescProviderSourceObject := batchimageitemFields[5].Descriptor()
|
||||
// batchimageitem.ProviderSourceObjectValidator is a validator for the "provider_source_object" field. It is called by the builders before save.
|
||||
batchimageitem.ProviderSourceObjectValidator = batchimageitemDescProviderSourceObject.Validators[0].(func(string) error)
|
||||
// batchimageitemDescMimeType is the schema descriptor for mime_type field.
|
||||
batchimageitemDescMimeType := batchimageitemFields[9].Descriptor()
|
||||
// batchimageitem.MimeTypeValidator is a validator for the "mime_type" field. It is called by the builders before save.
|
||||
batchimageitem.MimeTypeValidator = batchimageitemDescMimeType.Validators[0].(func(string) error)
|
||||
// batchimageitemDescFileExtension is the schema descriptor for file_extension field.
|
||||
batchimageitemDescFileExtension := batchimageitemFields[10].Descriptor()
|
||||
// batchimageitem.FileExtensionValidator is a validator for the "file_extension" field. It is called by the builders before save.
|
||||
batchimageitem.FileExtensionValidator = batchimageitemDescFileExtension.Validators[0].(func(string) error)
|
||||
// batchimageitemDescImageCount is the schema descriptor for image_count field.
|
||||
batchimageitemDescImageCount := batchimageitemFields[11].Descriptor()
|
||||
// batchimageitem.DefaultImageCount holds the default value on creation for the image_count field.
|
||||
batchimageitem.DefaultImageCount = batchimageitemDescImageCount.Default.(int)
|
||||
// batchimageitemDescErrorCode is the schema descriptor for error_code field.
|
||||
batchimageitemDescErrorCode := batchimageitemFields[12].Descriptor()
|
||||
// batchimageitem.ErrorCodeValidator is a validator for the "error_code" field. It is called by the builders before save.
|
||||
batchimageitem.ErrorCodeValidator = batchimageitemDescErrorCode.Validators[0].(func(string) error)
|
||||
// batchimageitemDescCreatedAt is the schema descriptor for created_at field.
|
||||
batchimageitemDescCreatedAt := batchimageitemFields[15].Descriptor()
|
||||
// batchimageitem.DefaultCreatedAt holds the default value on creation for the created_at field.
|
||||
batchimageitem.DefaultCreatedAt = batchimageitemDescCreatedAt.Default.(func() time.Time)
|
||||
batchimagejobFields := schema.BatchImageJob{}.Fields()
|
||||
_ = batchimagejobFields
|
||||
// batchimagejobDescBatchID is the schema descriptor for batch_id field.
|
||||
batchimagejobDescBatchID := batchimagejobFields[0].Descriptor()
|
||||
// batchimagejob.BatchIDValidator is a validator for the "batch_id" field. It is called by the builders before save.
|
||||
batchimagejob.BatchIDValidator = batchimagejobDescBatchID.Validators[0].(func(string) error)
|
||||
// batchimagejobDescProvider is the schema descriptor for provider field.
|
||||
batchimagejobDescProvider := batchimagejobFields[4].Descriptor()
|
||||
// batchimagejob.ProviderValidator is a validator for the "provider" field. It is called by the builders before save.
|
||||
batchimagejob.ProviderValidator = batchimagejobDescProvider.Validators[0].(func(string) error)
|
||||
// batchimagejobDescModel is the schema descriptor for model field.
|
||||
batchimagejobDescModel := batchimagejobFields[5].Descriptor()
|
||||
// batchimagejob.ModelValidator is a validator for the "model" field. It is called by the builders before save.
|
||||
batchimagejob.ModelValidator = batchimagejobDescModel.Validators[0].(func(string) error)
|
||||
// batchimagejobDescTaskName is the schema descriptor for task_name field.
|
||||
batchimagejobDescTaskName := batchimagejobFields[6].Descriptor()
|
||||
// batchimagejob.DefaultTaskName holds the default value on creation for the task_name field.
|
||||
batchimagejob.DefaultTaskName = batchimagejobDescTaskName.Default.(string)
|
||||
// batchimagejob.TaskNameValidator is a validator for the "task_name" field. It is called by the builders before save.
|
||||
batchimagejob.TaskNameValidator = batchimagejobDescTaskName.Validators[0].(func(string) error)
|
||||
// batchimagejobDescStatus is the schema descriptor for status field.
|
||||
batchimagejobDescStatus := batchimagejobFields[7].Descriptor()
|
||||
// batchimagejob.DefaultStatus holds the default value on creation for the status field.
|
||||
batchimagejob.DefaultStatus = batchimagejobDescStatus.Default.(string)
|
||||
// batchimagejob.StatusValidator is a validator for the "status" field. It is called by the builders before save.
|
||||
batchimagejob.StatusValidator = batchimagejobDescStatus.Validators[0].(func(string) error)
|
||||
// batchimagejobDescProviderJobName is the schema descriptor for provider_job_name field.
|
||||
batchimagejobDescProviderJobName := batchimagejobFields[8].Descriptor()
|
||||
// batchimagejob.ProviderJobNameValidator is a validator for the "provider_job_name" field. It is called by the builders before save.
|
||||
batchimagejob.ProviderJobNameValidator = batchimagejobDescProviderJobName.Validators[0].(func(string) error)
|
||||
// batchimagejobDescProviderInputRef is the schema descriptor for provider_input_ref field.
|
||||
batchimagejobDescProviderInputRef := batchimagejobFields[9].Descriptor()
|
||||
// batchimagejob.ProviderInputRefValidator is a validator for the "provider_input_ref" field. It is called by the builders before save.
|
||||
batchimagejob.ProviderInputRefValidator = batchimagejobDescProviderInputRef.Validators[0].(func(string) error)
|
||||
// batchimagejobDescProviderOutputRef is the schema descriptor for provider_output_ref field.
|
||||
batchimagejobDescProviderOutputRef := batchimagejobFields[10].Descriptor()
|
||||
// batchimagejob.ProviderOutputRefValidator is a validator for the "provider_output_ref" field. It is called by the builders before save.
|
||||
batchimagejob.ProviderOutputRefValidator = batchimagejobDescProviderOutputRef.Validators[0].(func(string) error)
|
||||
// batchimagejobDescGcsInputURI is the schema descriptor for gcs_input_uri field.
|
||||
batchimagejobDescGcsInputURI := batchimagejobFields[11].Descriptor()
|
||||
// batchimagejob.GcsInputURIValidator is a validator for the "gcs_input_uri" field. It is called by the builders before save.
|
||||
batchimagejob.GcsInputURIValidator = batchimagejobDescGcsInputURI.Validators[0].(func(string) error)
|
||||
// batchimagejobDescGcsOutputURI is the schema descriptor for gcs_output_uri field.
|
||||
batchimagejobDescGcsOutputURI := batchimagejobFields[12].Descriptor()
|
||||
// batchimagejob.GcsOutputURIValidator is a validator for the "gcs_output_uri" field. It is called by the builders before save.
|
||||
batchimagejob.GcsOutputURIValidator = batchimagejobDescGcsOutputURI.Validators[0].(func(string) error)
|
||||
// batchimagejobDescSuccessCount is the schema descriptor for success_count field.
|
||||
batchimagejobDescSuccessCount := batchimagejobFields[14].Descriptor()
|
||||
// batchimagejob.DefaultSuccessCount holds the default value on creation for the success_count field.
|
||||
batchimagejob.DefaultSuccessCount = batchimagejobDescSuccessCount.Default.(int)
|
||||
// batchimagejobDescFailCount is the schema descriptor for fail_count field.
|
||||
batchimagejobDescFailCount := batchimagejobFields[15].Descriptor()
|
||||
// batchimagejob.DefaultFailCount holds the default value on creation for the fail_count field.
|
||||
batchimagejob.DefaultFailCount = batchimagejobDescFailCount.Default.(int)
|
||||
// batchimagejobDescCancelledCount is the schema descriptor for cancelled_count field.
|
||||
batchimagejobDescCancelledCount := batchimagejobFields[16].Descriptor()
|
||||
// batchimagejob.DefaultCancelledCount holds the default value on creation for the cancelled_count field.
|
||||
batchimagejob.DefaultCancelledCount = batchimagejobDescCancelledCount.Default.(int)
|
||||
// batchimagejobDescEstimatedCost is the schema descriptor for estimated_cost field.
|
||||
batchimagejobDescEstimatedCost := batchimagejobFields[17].Descriptor()
|
||||
// batchimagejob.DefaultEstimatedCost holds the default value on creation for the estimated_cost field.
|
||||
batchimagejob.DefaultEstimatedCost = batchimagejobDescEstimatedCost.Default.(float64)
|
||||
// batchimagejobDescCurrency is the schema descriptor for currency field.
|
||||
batchimagejobDescCurrency := batchimagejobFields[20].Descriptor()
|
||||
// batchimagejob.DefaultCurrency holds the default value on creation for the currency field.
|
||||
batchimagejob.DefaultCurrency = batchimagejobDescCurrency.Default.(string)
|
||||
// batchimagejob.CurrencyValidator is a validator for the "currency" field. It is called by the builders before save.
|
||||
batchimagejob.CurrencyValidator = batchimagejobDescCurrency.Validators[0].(func(string) error)
|
||||
// batchimagejobDescHoldID is the schema descriptor for hold_id field.
|
||||
batchimagejobDescHoldID := batchimagejobFields[21].Descriptor()
|
||||
// batchimagejob.HoldIDValidator is a validator for the "hold_id" field. It is called by the builders before save.
|
||||
batchimagejob.HoldIDValidator = batchimagejobDescHoldID.Validators[0].(func(string) error)
|
||||
// batchimagejobDescIdempotencyKey is the schema descriptor for idempotency_key field.
|
||||
batchimagejobDescIdempotencyKey := batchimagejobFields[22].Descriptor()
|
||||
// batchimagejob.IdempotencyKeyValidator is a validator for the "idempotency_key" field. It is called by the builders before save.
|
||||
batchimagejob.IdempotencyKeyValidator = batchimagejobDescIdempotencyKey.Validators[0].(func(string) error)
|
||||
// batchimagejobDescRequestHash is the schema descriptor for request_hash field.
|
||||
batchimagejobDescRequestHash := batchimagejobFields[23].Descriptor()
|
||||
// batchimagejob.RequestHashValidator is a validator for the "request_hash" field. It is called by the builders before save.
|
||||
batchimagejob.RequestHashValidator = batchimagejobDescRequestHash.Validators[0].(func(string) error)
|
||||
// batchimagejobDescManifestHash is the schema descriptor for manifest_hash field.
|
||||
batchimagejobDescManifestHash := batchimagejobFields[24].Descriptor()
|
||||
// batchimagejob.ManifestHashValidator is a validator for the "manifest_hash" field. It is called by the builders before save.
|
||||
batchimagejob.ManifestHashValidator = batchimagejobDescManifestHash.Validators[0].(func(string) error)
|
||||
// batchimagejobDescRetryCount is the schema descriptor for retry_count field.
|
||||
batchimagejobDescRetryCount := batchimagejobFields[25].Descriptor()
|
||||
// batchimagejob.DefaultRetryCount holds the default value on creation for the retry_count field.
|
||||
batchimagejob.DefaultRetryCount = batchimagejobDescRetryCount.Default.(int)
|
||||
// batchimagejobDescVersion is the schema descriptor for version field.
|
||||
batchimagejobDescVersion := batchimagejobFields[26].Descriptor()
|
||||
// batchimagejob.DefaultVersion holds the default value on creation for the version field.
|
||||
batchimagejob.DefaultVersion = batchimagejobDescVersion.Default.(int)
|
||||
// batchimagejobDescLastErrorCode is the schema descriptor for last_error_code field.
|
||||
batchimagejobDescLastErrorCode := batchimagejobFields[32].Descriptor()
|
||||
// batchimagejob.LastErrorCodeValidator is a validator for the "last_error_code" field. It is called by the builders before save.
|
||||
batchimagejob.LastErrorCodeValidator = batchimagejobDescLastErrorCode.Validators[0].(func(string) error)
|
||||
// batchimagejobDescCreatedAt is the schema descriptor for created_at field.
|
||||
batchimagejobDescCreatedAt := batchimagejobFields[34].Descriptor()
|
||||
// batchimagejob.DefaultCreatedAt holds the default value on creation for the created_at field.
|
||||
batchimagejob.DefaultCreatedAt = batchimagejobDescCreatedAt.Default.(func() time.Time)
|
||||
// batchimagejobDescUpdatedAt is the schema descriptor for updated_at field.
|
||||
batchimagejobDescUpdatedAt := batchimagejobFields[35].Descriptor()
|
||||
// batchimagejob.DefaultUpdatedAt holds the default value on creation for the updated_at field.
|
||||
batchimagejob.DefaultUpdatedAt = batchimagejobDescUpdatedAt.Default.(func() time.Time)
|
||||
// batchimagejob.UpdateDefaultUpdatedAt holds the default value on update for the updated_at field.
|
||||
batchimagejob.UpdateDefaultUpdatedAt = batchimagejobDescUpdatedAt.UpdateDefault.(func() time.Time)
|
||||
channelmonitorMixin := schema.ChannelMonitor{}.Mixin()
|
||||
channelmonitorMixinFields0 := channelmonitorMixin[0].Fields()
|
||||
_ = channelmonitorMixinFields0
|
||||
@@ -796,92 +965,132 @@ func init() {
|
||||
groupDescRateMultiplier := groupFields[2].Descriptor()
|
||||
// group.DefaultRateMultiplier holds the default value on creation for the rate_multiplier field.
|
||||
group.DefaultRateMultiplier = groupDescRateMultiplier.Default.(float64)
|
||||
// groupDescPeakRateEnabled is the schema descriptor for peak_rate_enabled field.
|
||||
groupDescPeakRateEnabled := groupFields[3].Descriptor()
|
||||
// group.DefaultPeakRateEnabled holds the default value on creation for the peak_rate_enabled field.
|
||||
group.DefaultPeakRateEnabled = groupDescPeakRateEnabled.Default.(bool)
|
||||
// groupDescPeakStart is the schema descriptor for peak_start field.
|
||||
groupDescPeakStart := groupFields[4].Descriptor()
|
||||
// group.DefaultPeakStart holds the default value on creation for the peak_start field.
|
||||
group.DefaultPeakStart = groupDescPeakStart.Default.(string)
|
||||
// group.PeakStartValidator is a validator for the "peak_start" field. It is called by the builders before save.
|
||||
group.PeakStartValidator = groupDescPeakStart.Validators[0].(func(string) error)
|
||||
// groupDescPeakEnd is the schema descriptor for peak_end field.
|
||||
groupDescPeakEnd := groupFields[5].Descriptor()
|
||||
// group.DefaultPeakEnd holds the default value on creation for the peak_end field.
|
||||
group.DefaultPeakEnd = groupDescPeakEnd.Default.(string)
|
||||
// group.PeakEndValidator is a validator for the "peak_end" field. It is called by the builders before save.
|
||||
group.PeakEndValidator = groupDescPeakEnd.Validators[0].(func(string) error)
|
||||
// groupDescPeakRateMultiplier is the schema descriptor for peak_rate_multiplier field.
|
||||
groupDescPeakRateMultiplier := groupFields[6].Descriptor()
|
||||
// group.DefaultPeakRateMultiplier holds the default value on creation for the peak_rate_multiplier field.
|
||||
group.DefaultPeakRateMultiplier = groupDescPeakRateMultiplier.Default.(float64)
|
||||
// groupDescIsExclusive is the schema descriptor for is_exclusive field.
|
||||
groupDescIsExclusive := groupFields[3].Descriptor()
|
||||
groupDescIsExclusive := groupFields[7].Descriptor()
|
||||
// group.DefaultIsExclusive holds the default value on creation for the is_exclusive field.
|
||||
group.DefaultIsExclusive = groupDescIsExclusive.Default.(bool)
|
||||
// groupDescStatus is the schema descriptor for status field.
|
||||
groupDescStatus := groupFields[4].Descriptor()
|
||||
groupDescStatus := groupFields[8].Descriptor()
|
||||
// group.DefaultStatus holds the default value on creation for the status field.
|
||||
group.DefaultStatus = groupDescStatus.Default.(string)
|
||||
// group.StatusValidator is a validator for the "status" field. It is called by the builders before save.
|
||||
group.StatusValidator = groupDescStatus.Validators[0].(func(string) error)
|
||||
// groupDescPlatform is the schema descriptor for platform field.
|
||||
groupDescPlatform := groupFields[5].Descriptor()
|
||||
groupDescPlatform := groupFields[9].Descriptor()
|
||||
// group.DefaultPlatform holds the default value on creation for the platform field.
|
||||
group.DefaultPlatform = groupDescPlatform.Default.(string)
|
||||
// group.PlatformValidator is a validator for the "platform" field. It is called by the builders before save.
|
||||
group.PlatformValidator = groupDescPlatform.Validators[0].(func(string) error)
|
||||
// groupDescSubscriptionType is the schema descriptor for subscription_type field.
|
||||
groupDescSubscriptionType := groupFields[6].Descriptor()
|
||||
groupDescSubscriptionType := groupFields[10].Descriptor()
|
||||
// group.DefaultSubscriptionType holds the default value on creation for the subscription_type field.
|
||||
group.DefaultSubscriptionType = groupDescSubscriptionType.Default.(string)
|
||||
// group.SubscriptionTypeValidator is a validator for the "subscription_type" field. It is called by the builders before save.
|
||||
group.SubscriptionTypeValidator = groupDescSubscriptionType.Validators[0].(func(string) error)
|
||||
// groupDescDefaultValidityDays is the schema descriptor for default_validity_days field.
|
||||
groupDescDefaultValidityDays := groupFields[10].Descriptor()
|
||||
groupDescDefaultValidityDays := groupFields[14].Descriptor()
|
||||
// group.DefaultDefaultValidityDays holds the default value on creation for the default_validity_days field.
|
||||
group.DefaultDefaultValidityDays = groupDescDefaultValidityDays.Default.(int)
|
||||
// groupDescAllowImageGeneration is the schema descriptor for allow_image_generation field.
|
||||
groupDescAllowImageGeneration := groupFields[11].Descriptor()
|
||||
groupDescAllowImageGeneration := groupFields[15].Descriptor()
|
||||
// group.DefaultAllowImageGeneration holds the default value on creation for the allow_image_generation field.
|
||||
group.DefaultAllowImageGeneration = groupDescAllowImageGeneration.Default.(bool)
|
||||
// groupDescAllowBatchImageGeneration is the schema descriptor for allow_batch_image_generation field.
|
||||
groupDescAllowBatchImageGeneration := groupFields[16].Descriptor()
|
||||
// group.DefaultAllowBatchImageGeneration holds the default value on creation for the allow_batch_image_generation field.
|
||||
group.DefaultAllowBatchImageGeneration = groupDescAllowBatchImageGeneration.Default.(bool)
|
||||
// groupDescImageRateIndependent is the schema descriptor for image_rate_independent field.
|
||||
groupDescImageRateIndependent := groupFields[12].Descriptor()
|
||||
groupDescImageRateIndependent := groupFields[17].Descriptor()
|
||||
// group.DefaultImageRateIndependent holds the default value on creation for the image_rate_independent field.
|
||||
group.DefaultImageRateIndependent = groupDescImageRateIndependent.Default.(bool)
|
||||
// groupDescImageRateMultiplier is the schema descriptor for image_rate_multiplier field.
|
||||
groupDescImageRateMultiplier := groupFields[13].Descriptor()
|
||||
groupDescImageRateMultiplier := groupFields[18].Descriptor()
|
||||
// group.DefaultImageRateMultiplier holds the default value on creation for the image_rate_multiplier field.
|
||||
group.DefaultImageRateMultiplier = groupDescImageRateMultiplier.Default.(float64)
|
||||
// groupDescBatchImageDiscountMultiplier is the schema descriptor for batch_image_discount_multiplier field.
|
||||
groupDescBatchImageDiscountMultiplier := groupFields[22].Descriptor()
|
||||
// group.DefaultBatchImageDiscountMultiplier holds the default value on creation for the batch_image_discount_multiplier field.
|
||||
group.DefaultBatchImageDiscountMultiplier = groupDescBatchImageDiscountMultiplier.Default.(float64)
|
||||
// groupDescBatchImageHoldMultiplier is the schema descriptor for batch_image_hold_multiplier field.
|
||||
groupDescBatchImageHoldMultiplier := groupFields[23].Descriptor()
|
||||
// group.DefaultBatchImageHoldMultiplier holds the default value on creation for the batch_image_hold_multiplier field.
|
||||
group.DefaultBatchImageHoldMultiplier = groupDescBatchImageHoldMultiplier.Default.(float64)
|
||||
// groupDescVideoRateIndependent is the schema descriptor for video_rate_independent field.
|
||||
groupDescVideoRateIndependent := groupFields[24].Descriptor()
|
||||
// group.DefaultVideoRateIndependent holds the default value on creation for the video_rate_independent field.
|
||||
group.DefaultVideoRateIndependent = groupDescVideoRateIndependent.Default.(bool)
|
||||
// groupDescVideoRateMultiplier is the schema descriptor for video_rate_multiplier field.
|
||||
groupDescVideoRateMultiplier := groupFields[25].Descriptor()
|
||||
// group.DefaultVideoRateMultiplier holds the default value on creation for the video_rate_multiplier field.
|
||||
group.DefaultVideoRateMultiplier = groupDescVideoRateMultiplier.Default.(float64)
|
||||
// groupDescClaudeCodeOnly is the schema descriptor for claude_code_only field.
|
||||
groupDescClaudeCodeOnly := groupFields[17].Descriptor()
|
||||
groupDescClaudeCodeOnly := groupFields[30].Descriptor()
|
||||
// group.DefaultClaudeCodeOnly holds the default value on creation for the claude_code_only field.
|
||||
group.DefaultClaudeCodeOnly = groupDescClaudeCodeOnly.Default.(bool)
|
||||
// groupDescModelRoutingEnabled is the schema descriptor for model_routing_enabled field.
|
||||
groupDescModelRoutingEnabled := groupFields[21].Descriptor()
|
||||
groupDescModelRoutingEnabled := groupFields[34].Descriptor()
|
||||
// group.DefaultModelRoutingEnabled holds the default value on creation for the model_routing_enabled field.
|
||||
group.DefaultModelRoutingEnabled = groupDescModelRoutingEnabled.Default.(bool)
|
||||
// groupDescMcpXMLInject is the schema descriptor for mcp_xml_inject field.
|
||||
groupDescMcpXMLInject := groupFields[22].Descriptor()
|
||||
groupDescMcpXMLInject := groupFields[35].Descriptor()
|
||||
// group.DefaultMcpXMLInject holds the default value on creation for the mcp_xml_inject field.
|
||||
group.DefaultMcpXMLInject = groupDescMcpXMLInject.Default.(bool)
|
||||
// groupDescSupportedModelScopes is the schema descriptor for supported_model_scopes field.
|
||||
groupDescSupportedModelScopes := groupFields[23].Descriptor()
|
||||
groupDescSupportedModelScopes := groupFields[36].Descriptor()
|
||||
// group.DefaultSupportedModelScopes holds the default value on creation for the supported_model_scopes field.
|
||||
group.DefaultSupportedModelScopes = groupDescSupportedModelScopes.Default.([]string)
|
||||
// groupDescSortOrder is the schema descriptor for sort_order field.
|
||||
groupDescSortOrder := groupFields[24].Descriptor()
|
||||
groupDescSortOrder := groupFields[37].Descriptor()
|
||||
// group.DefaultSortOrder holds the default value on creation for the sort_order field.
|
||||
group.DefaultSortOrder = groupDescSortOrder.Default.(int)
|
||||
// groupDescAllowMessagesDispatch is the schema descriptor for allow_messages_dispatch field.
|
||||
groupDescAllowMessagesDispatch := groupFields[25].Descriptor()
|
||||
groupDescAllowMessagesDispatch := groupFields[38].Descriptor()
|
||||
// group.DefaultAllowMessagesDispatch holds the default value on creation for the allow_messages_dispatch field.
|
||||
group.DefaultAllowMessagesDispatch = groupDescAllowMessagesDispatch.Default.(bool)
|
||||
// groupDescRequireOauthOnly is the schema descriptor for require_oauth_only field.
|
||||
groupDescRequireOauthOnly := groupFields[26].Descriptor()
|
||||
groupDescRequireOauthOnly := groupFields[39].Descriptor()
|
||||
// group.DefaultRequireOauthOnly holds the default value on creation for the require_oauth_only field.
|
||||
group.DefaultRequireOauthOnly = groupDescRequireOauthOnly.Default.(bool)
|
||||
// groupDescRequirePrivacySet is the schema descriptor for require_privacy_set field.
|
||||
groupDescRequirePrivacySet := groupFields[27].Descriptor()
|
||||
groupDescRequirePrivacySet := groupFields[40].Descriptor()
|
||||
// group.DefaultRequirePrivacySet holds the default value on creation for the require_privacy_set field.
|
||||
group.DefaultRequirePrivacySet = groupDescRequirePrivacySet.Default.(bool)
|
||||
// groupDescDefaultMappedModel is the schema descriptor for default_mapped_model field.
|
||||
groupDescDefaultMappedModel := groupFields[28].Descriptor()
|
||||
groupDescDefaultMappedModel := groupFields[41].Descriptor()
|
||||
// group.DefaultDefaultMappedModel holds the default value on creation for the default_mapped_model field.
|
||||
group.DefaultDefaultMappedModel = groupDescDefaultMappedModel.Default.(string)
|
||||
// group.DefaultMappedModelValidator is a validator for the "default_mapped_model" field. It is called by the builders before save.
|
||||
group.DefaultMappedModelValidator = groupDescDefaultMappedModel.Validators[0].(func(string) error)
|
||||
// groupDescMessagesDispatchModelConfig is the schema descriptor for messages_dispatch_model_config field.
|
||||
groupDescMessagesDispatchModelConfig := groupFields[29].Descriptor()
|
||||
groupDescMessagesDispatchModelConfig := groupFields[42].Descriptor()
|
||||
// group.DefaultMessagesDispatchModelConfig holds the default value on creation for the messages_dispatch_model_config field.
|
||||
group.DefaultMessagesDispatchModelConfig = groupDescMessagesDispatchModelConfig.Default.(domain.OpenAIMessagesDispatchModelConfig)
|
||||
// groupDescModelsListConfig is the schema descriptor for models_list_config field.
|
||||
groupDescModelsListConfig := groupFields[30].Descriptor()
|
||||
groupDescModelsListConfig := groupFields[43].Descriptor()
|
||||
// group.DefaultModelsListConfig holds the default value on creation for the models_list_config field.
|
||||
group.DefaultModelsListConfig = groupDescModelsListConfig.Default.(domain.GroupModelsListConfig)
|
||||
// groupDescRpmLimit is the schema descriptor for rpm_limit field.
|
||||
groupDescRpmLimit := groupFields[31].Descriptor()
|
||||
groupDescRpmLimit := groupFields[44].Descriptor()
|
||||
// group.DefaultRpmLimit holds the default value on creation for the rpm_limit field.
|
||||
group.DefaultRpmLimit = groupDescRpmLimit.Default.(int)
|
||||
idempotencyrecordMixin := schema.IdempotencyRecord{}.Mixin()
|
||||
@@ -1731,48 +1940,60 @@ func init() {
|
||||
usagelogDescRateMultiplier := usagelogFields[25].Descriptor()
|
||||
// usagelog.DefaultRateMultiplier holds the default value on creation for the rate_multiplier field.
|
||||
usagelog.DefaultRateMultiplier = usagelogDescRateMultiplier.Default.(float64)
|
||||
// usagelogDescLongContextBillingApplied is the schema descriptor for long_context_billing_applied field.
|
||||
usagelogDescLongContextBillingApplied := usagelogFields[26].Descriptor()
|
||||
// usagelog.DefaultLongContextBillingApplied holds the default value on creation for the long_context_billing_applied field.
|
||||
usagelog.DefaultLongContextBillingApplied = usagelogDescLongContextBillingApplied.Default.(bool)
|
||||
// usagelogDescBillingType is the schema descriptor for billing_type field.
|
||||
usagelogDescBillingType := usagelogFields[27].Descriptor()
|
||||
usagelogDescBillingType := usagelogFields[28].Descriptor()
|
||||
// usagelog.DefaultBillingType holds the default value on creation for the billing_type field.
|
||||
usagelog.DefaultBillingType = usagelogDescBillingType.Default.(int8)
|
||||
// usagelogDescStream is the schema descriptor for stream field.
|
||||
usagelogDescStream := usagelogFields[28].Descriptor()
|
||||
usagelogDescStream := usagelogFields[29].Descriptor()
|
||||
// usagelog.DefaultStream holds the default value on creation for the stream field.
|
||||
usagelog.DefaultStream = usagelogDescStream.Default.(bool)
|
||||
// usagelogDescUserAgent is the schema descriptor for user_agent field.
|
||||
usagelogDescUserAgent := usagelogFields[31].Descriptor()
|
||||
usagelogDescUserAgent := usagelogFields[32].Descriptor()
|
||||
// usagelog.UserAgentValidator is a validator for the "user_agent" field. It is called by the builders before save.
|
||||
usagelog.UserAgentValidator = usagelogDescUserAgent.Validators[0].(func(string) error)
|
||||
// usagelogDescIPAddress is the schema descriptor for ip_address field.
|
||||
usagelogDescIPAddress := usagelogFields[32].Descriptor()
|
||||
usagelogDescIPAddress := usagelogFields[33].Descriptor()
|
||||
// usagelog.IPAddressValidator is a validator for the "ip_address" field. It is called by the builders before save.
|
||||
usagelog.IPAddressValidator = usagelogDescIPAddress.Validators[0].(func(string) error)
|
||||
// usagelogDescImageCount is the schema descriptor for image_count field.
|
||||
usagelogDescImageCount := usagelogFields[33].Descriptor()
|
||||
usagelogDescImageCount := usagelogFields[34].Descriptor()
|
||||
// usagelog.DefaultImageCount holds the default value on creation for the image_count field.
|
||||
usagelog.DefaultImageCount = usagelogDescImageCount.Default.(int)
|
||||
// usagelogDescImageSize is the schema descriptor for image_size field.
|
||||
usagelogDescImageSize := usagelogFields[34].Descriptor()
|
||||
usagelogDescImageSize := usagelogFields[35].Descriptor()
|
||||
// usagelog.ImageSizeValidator is a validator for the "image_size" field. It is called by the builders before save.
|
||||
usagelog.ImageSizeValidator = usagelogDescImageSize.Validators[0].(func(string) error)
|
||||
// usagelogDescImageInputSize is the schema descriptor for image_input_size field.
|
||||
usagelogDescImageInputSize := usagelogFields[35].Descriptor()
|
||||
usagelogDescImageInputSize := usagelogFields[36].Descriptor()
|
||||
// usagelog.ImageInputSizeValidator is a validator for the "image_input_size" field. It is called by the builders before save.
|
||||
usagelog.ImageInputSizeValidator = usagelogDescImageInputSize.Validators[0].(func(string) error)
|
||||
// usagelogDescImageOutputSize is the schema descriptor for image_output_size field.
|
||||
usagelogDescImageOutputSize := usagelogFields[36].Descriptor()
|
||||
usagelogDescImageOutputSize := usagelogFields[37].Descriptor()
|
||||
// usagelog.ImageOutputSizeValidator is a validator for the "image_output_size" field. It is called by the builders before save.
|
||||
usagelog.ImageOutputSizeValidator = usagelogDescImageOutputSize.Validators[0].(func(string) error)
|
||||
// usagelogDescImageSizeSource is the schema descriptor for image_size_source field.
|
||||
usagelogDescImageSizeSource := usagelogFields[37].Descriptor()
|
||||
usagelogDescImageSizeSource := usagelogFields[38].Descriptor()
|
||||
// usagelog.ImageSizeSourceValidator is a validator for the "image_size_source" field. It is called by the builders before save.
|
||||
usagelog.ImageSizeSourceValidator = usagelogDescImageSizeSource.Validators[0].(func(string) error)
|
||||
// usagelogDescVideoCount is the schema descriptor for video_count field.
|
||||
usagelogDescVideoCount := usagelogFields[40].Descriptor()
|
||||
// usagelog.DefaultVideoCount holds the default value on creation for the video_count field.
|
||||
usagelog.DefaultVideoCount = usagelogDescVideoCount.Default.(int)
|
||||
// usagelogDescVideoResolution is the schema descriptor for video_resolution field.
|
||||
usagelogDescVideoResolution := usagelogFields[41].Descriptor()
|
||||
// usagelog.VideoResolutionValidator is a validator for the "video_resolution" field. It is called by the builders before save.
|
||||
usagelog.VideoResolutionValidator = usagelogDescVideoResolution.Validators[0].(func(string) error)
|
||||
// usagelogDescCacheTTLOverridden is the schema descriptor for cache_ttl_overridden field.
|
||||
usagelogDescCacheTTLOverridden := usagelogFields[39].Descriptor()
|
||||
usagelogDescCacheTTLOverridden := usagelogFields[43].Descriptor()
|
||||
// usagelog.DefaultCacheTTLOverridden holds the default value on creation for the cache_ttl_overridden field.
|
||||
usagelog.DefaultCacheTTLOverridden = usagelogDescCacheTTLOverridden.Default.(bool)
|
||||
// usagelogDescCreatedAt is the schema descriptor for created_at field.
|
||||
usagelogDescCreatedAt := usagelogFields[40].Descriptor()
|
||||
usagelogDescCreatedAt := usagelogFields[44].Descriptor()
|
||||
// usagelog.DefaultCreatedAt holds the default value on creation for the created_at field.
|
||||
usagelog.DefaultCreatedAt = usagelogDescCreatedAt.Default.(func() time.Time)
|
||||
userMixin := schema.User{}.Mixin()
|
||||
@@ -1840,54 +2061,58 @@ func init() {
|
||||
userDescBalance := userFields[3].Descriptor()
|
||||
// user.DefaultBalance holds the default value on creation for the balance field.
|
||||
user.DefaultBalance = userDescBalance.Default.(float64)
|
||||
// userDescFrozenBalance is the schema descriptor for frozen_balance field.
|
||||
userDescFrozenBalance := userFields[4].Descriptor()
|
||||
// user.DefaultFrozenBalance holds the default value on creation for the frozen_balance field.
|
||||
user.DefaultFrozenBalance = userDescFrozenBalance.Default.(float64)
|
||||
// userDescConcurrency is the schema descriptor for concurrency field.
|
||||
userDescConcurrency := userFields[4].Descriptor()
|
||||
userDescConcurrency := userFields[5].Descriptor()
|
||||
// user.DefaultConcurrency holds the default value on creation for the concurrency field.
|
||||
user.DefaultConcurrency = userDescConcurrency.Default.(int)
|
||||
// userDescStatus is the schema descriptor for status field.
|
||||
userDescStatus := userFields[5].Descriptor()
|
||||
userDescStatus := userFields[6].Descriptor()
|
||||
// user.DefaultStatus holds the default value on creation for the status field.
|
||||
user.DefaultStatus = userDescStatus.Default.(string)
|
||||
// user.StatusValidator is a validator for the "status" field. It is called by the builders before save.
|
||||
user.StatusValidator = userDescStatus.Validators[0].(func(string) error)
|
||||
// userDescUsername is the schema descriptor for username field.
|
||||
userDescUsername := userFields[6].Descriptor()
|
||||
userDescUsername := userFields[7].Descriptor()
|
||||
// user.DefaultUsername holds the default value on creation for the username field.
|
||||
user.DefaultUsername = userDescUsername.Default.(string)
|
||||
// user.UsernameValidator is a validator for the "username" field. It is called by the builders before save.
|
||||
user.UsernameValidator = userDescUsername.Validators[0].(func(string) error)
|
||||
// userDescNotes is the schema descriptor for notes field.
|
||||
userDescNotes := userFields[7].Descriptor()
|
||||
userDescNotes := userFields[8].Descriptor()
|
||||
// user.DefaultNotes holds the default value on creation for the notes field.
|
||||
user.DefaultNotes = userDescNotes.Default.(string)
|
||||
// userDescTotpEnabled is the schema descriptor for totp_enabled field.
|
||||
userDescTotpEnabled := userFields[9].Descriptor()
|
||||
userDescTotpEnabled := userFields[10].Descriptor()
|
||||
// user.DefaultTotpEnabled holds the default value on creation for the totp_enabled field.
|
||||
user.DefaultTotpEnabled = userDescTotpEnabled.Default.(bool)
|
||||
// userDescSignupSource is the schema descriptor for signup_source field.
|
||||
userDescSignupSource := userFields[11].Descriptor()
|
||||
userDescSignupSource := userFields[12].Descriptor()
|
||||
// user.DefaultSignupSource holds the default value on creation for the signup_source field.
|
||||
user.DefaultSignupSource = userDescSignupSource.Default.(string)
|
||||
// user.SignupSourceValidator is a validator for the "signup_source" field. It is called by the builders before save.
|
||||
user.SignupSourceValidator = userDescSignupSource.Validators[0].(func(string) error)
|
||||
// userDescBalanceNotifyEnabled is the schema descriptor for balance_notify_enabled field.
|
||||
userDescBalanceNotifyEnabled := userFields[14].Descriptor()
|
||||
userDescBalanceNotifyEnabled := userFields[15].Descriptor()
|
||||
// user.DefaultBalanceNotifyEnabled holds the default value on creation for the balance_notify_enabled field.
|
||||
user.DefaultBalanceNotifyEnabled = userDescBalanceNotifyEnabled.Default.(bool)
|
||||
// userDescBalanceNotifyThresholdType is the schema descriptor for balance_notify_threshold_type field.
|
||||
userDescBalanceNotifyThresholdType := userFields[15].Descriptor()
|
||||
userDescBalanceNotifyThresholdType := userFields[16].Descriptor()
|
||||
// user.DefaultBalanceNotifyThresholdType holds the default value on creation for the balance_notify_threshold_type field.
|
||||
user.DefaultBalanceNotifyThresholdType = userDescBalanceNotifyThresholdType.Default.(string)
|
||||
// userDescBalanceNotifyExtraEmails is the schema descriptor for balance_notify_extra_emails field.
|
||||
userDescBalanceNotifyExtraEmails := userFields[17].Descriptor()
|
||||
userDescBalanceNotifyExtraEmails := userFields[18].Descriptor()
|
||||
// user.DefaultBalanceNotifyExtraEmails holds the default value on creation for the balance_notify_extra_emails field.
|
||||
user.DefaultBalanceNotifyExtraEmails = userDescBalanceNotifyExtraEmails.Default.(string)
|
||||
// userDescTotalRecharged is the schema descriptor for total_recharged field.
|
||||
userDescTotalRecharged := userFields[18].Descriptor()
|
||||
userDescTotalRecharged := userFields[19].Descriptor()
|
||||
// user.DefaultTotalRecharged holds the default value on creation for the total_recharged field.
|
||||
user.DefaultTotalRecharged = userDescTotalRecharged.Default.(float64)
|
||||
// userDescRpmLimit is the schema descriptor for rpm_limit field.
|
||||
userDescRpmLimit := userFields[19].Descriptor()
|
||||
userDescRpmLimit := userFields[20].Descriptor()
|
||||
// user.DefaultRpmLimit holds the default value on creation for the rpm_limit field.
|
||||
user.DefaultRpmLimit = userDescRpmLimit.Default.(int)
|
||||
userallowedgroupFields := schema.UserAllowedGroup{}.Fields()
|
||||
|
||||
@@ -196,6 +196,11 @@ func (Account) Fields() []ent.Field {
|
||||
Optional().
|
||||
Nillable().
|
||||
MaxLen(20),
|
||||
|
||||
field.Int64("parent_account_id").Optional().Nillable().
|
||||
Comment("Parent account id for a linked spark shadow (NULL = normal)."),
|
||||
field.Enum("quota_dimension").Values("global", "spark").Default("global").
|
||||
Comment("'global' (default) or 'spark' (shadow reads codex_bengalfox)."),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,6 +217,14 @@ func (Account) Edges() []ent.Edge {
|
||||
edge.To("proxy", Proxy.Type).
|
||||
Field("proxy_id").
|
||||
Unique(),
|
||||
// children/parent: linked spark shadow relationship.
|
||||
// parent_account_id is nullable, and the active one-shadow-per-parent rule
|
||||
// is enforced by the partial unique index in migration 154a.
|
||||
edge.To("children", Account.Type).
|
||||
Annotations(entsql.OnDelete(entsql.Restrict)).
|
||||
From("parent").
|
||||
Field("parent_account_id").
|
||||
Unique(),
|
||||
// usage_logs: 该账户的使用日志
|
||||
edge.To("usage_logs", UsageLog.Type),
|
||||
}
|
||||
@@ -235,5 +248,6 @@ func (Account) Indexes() []ent.Index {
|
||||
index.Fields("platform", "priority"),
|
||||
index.Fields("priority", "status"),
|
||||
index.Fields("deleted_at"), // 软删除查询优化
|
||||
index.Fields("parent_account_id"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect"
|
||||
"entgo.io/ent/dialect/entsql"
|
||||
"entgo.io/ent/schema"
|
||||
"entgo.io/ent/schema/field"
|
||||
"entgo.io/ent/schema/index"
|
||||
)
|
||||
|
||||
// BatchImageEvent records append-only operational events for batch image jobs.
|
||||
type BatchImageEvent struct {
|
||||
ent.Schema
|
||||
}
|
||||
|
||||
func (BatchImageEvent) Annotations() []schema.Annotation {
|
||||
return []schema.Annotation{
|
||||
entsql.Annotation{Table: "batch_image_events"},
|
||||
}
|
||||
}
|
||||
|
||||
func (BatchImageEvent) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
field.String("job_id").MaxLen(64),
|
||||
field.String("event_type").MaxLen(64),
|
||||
field.JSON("payload", map[string]any{}).
|
||||
Optional().
|
||||
SchemaType(map[string]string{dialect.Postgres: "jsonb"}),
|
||||
field.String("event_hash").Optional().Nillable().MaxLen(128),
|
||||
field.Time("created_at").Immutable().Default(time.Now).SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
|
||||
}
|
||||
}
|
||||
|
||||
func (BatchImageEvent) Indexes() []ent.Index {
|
||||
return []ent.Index{
|
||||
index.Fields("job_id", "created_at"),
|
||||
index.Fields("event_type"),
|
||||
index.Fields("job_id", "event_hash").Unique().Annotations(entsql.IndexWhere("event_hash IS NOT NULL AND event_hash <> ''")),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect"
|
||||
"entgo.io/ent/dialect/entsql"
|
||||
"entgo.io/ent/schema"
|
||||
"entgo.io/ent/schema/field"
|
||||
"entgo.io/ent/schema/index"
|
||||
)
|
||||
|
||||
// BatchImageItem holds indexed output rows for a batch image job.
|
||||
type BatchImageItem struct {
|
||||
ent.Schema
|
||||
}
|
||||
|
||||
func (BatchImageItem) Annotations() []schema.Annotation {
|
||||
return []schema.Annotation{
|
||||
entsql.Annotation{Table: "batch_image_items"},
|
||||
}
|
||||
}
|
||||
|
||||
func (BatchImageItem) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
field.String("job_id").MaxLen(64),
|
||||
field.String("custom_id").MaxLen(255),
|
||||
field.String("status").MaxLen(32),
|
||||
field.String("request_hash").Optional().Nillable().MaxLen(128),
|
||||
field.String("prompt_preview").Optional().Nillable().SchemaType(map[string]string{dialect.Postgres: "text"}),
|
||||
field.String("provider_source_object").Optional().Nillable().MaxLen(1024),
|
||||
field.Int("source_line_number").Optional().Nillable(),
|
||||
field.Int64("source_byte_offset").Optional().Nillable(),
|
||||
field.Int64("source_byte_length").Optional().Nillable(),
|
||||
field.String("mime_type").Optional().Nillable().MaxLen(128),
|
||||
field.String("file_extension").Optional().Nillable().MaxLen(32),
|
||||
field.Int("image_count").Default(0),
|
||||
field.String("error_code").Optional().Nillable().MaxLen(128),
|
||||
field.String("error_message").Optional().Nillable().SchemaType(map[string]string{dialect.Postgres: "text"}),
|
||||
field.Float("billed_amount").Optional().Nillable().SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}),
|
||||
field.Time("created_at").Immutable().Default(time.Now).SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
|
||||
field.Time("indexed_at").Optional().Nillable().SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
|
||||
}
|
||||
}
|
||||
|
||||
func (BatchImageItem) Indexes() []ent.Index {
|
||||
return []ent.Index{
|
||||
index.Fields("job_id", "custom_id").Unique(),
|
||||
index.Fields("job_id", "status"),
|
||||
index.Fields("provider_source_object"),
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"entgo.io/ent"
|
||||
"entgo.io/ent/dialect"
|
||||
"entgo.io/ent/dialect/entsql"
|
||||
"entgo.io/ent/schema"
|
||||
"entgo.io/ent/schema/field"
|
||||
"entgo.io/ent/schema/index"
|
||||
)
|
||||
|
||||
// BatchImageJob holds the schema definition for asynchronous image batch jobs.
|
||||
//
|
||||
// 删除策略:账务源保留
|
||||
// 这张表是批量生图任务的账务和状态源;用户侧删除仅通过 user_deleted_at
|
||||
// 从列表隐藏,输出清理通过 output_deleted 状态和删除时间字段表达。
|
||||
type BatchImageJob struct {
|
||||
ent.Schema
|
||||
}
|
||||
|
||||
func (BatchImageJob) Annotations() []schema.Annotation {
|
||||
return []schema.Annotation{
|
||||
entsql.Annotation{Table: "batch_image_jobs"},
|
||||
}
|
||||
}
|
||||
|
||||
func (BatchImageJob) Fields() []ent.Field {
|
||||
return []ent.Field{
|
||||
field.String("batch_id").MaxLen(64).Immutable(),
|
||||
field.Int64("user_id"),
|
||||
field.Int64("api_key_id").Optional().Nillable(),
|
||||
field.Int64("account_id").Optional().Nillable(),
|
||||
field.String("provider").MaxLen(32),
|
||||
field.String("model").MaxLen(128),
|
||||
field.String("task_name").MaxLen(255).Default(""),
|
||||
field.String("status").MaxLen(32).Default("created"),
|
||||
field.String("provider_job_name").Optional().Nillable().MaxLen(512),
|
||||
field.String("provider_input_ref").Optional().Nillable().MaxLen(1024),
|
||||
field.String("provider_output_ref").Optional().Nillable().MaxLen(1024),
|
||||
field.String("gcs_input_uri").Optional().Nillable().MaxLen(1024),
|
||||
field.String("gcs_output_uri").Optional().Nillable().MaxLen(1024),
|
||||
field.Int("item_count"),
|
||||
field.Int("success_count").Default(0),
|
||||
field.Int("fail_count").Default(0),
|
||||
field.Int("cancelled_count").Default(0),
|
||||
field.Float("estimated_cost").SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}).Default(0),
|
||||
field.Float("hold_amount").Optional().Nillable().SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}),
|
||||
field.Float("actual_cost").Optional().Nillable().SchemaType(map[string]string{dialect.Postgres: "decimal(20,10)"}),
|
||||
field.String("currency").MaxLen(16).Default("USD"),
|
||||
field.String("hold_id").Optional().Nillable().MaxLen(128),
|
||||
field.String("idempotency_key").Optional().Nillable().MaxLen(255),
|
||||
field.String("request_hash").Optional().Nillable().MaxLen(128),
|
||||
field.String("manifest_hash").Optional().Nillable().MaxLen(128),
|
||||
field.Int("retry_count").Default(0),
|
||||
field.Int("version").Default(0),
|
||||
field.Time("output_expires_at").Optional().Nillable().SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
|
||||
field.Time("input_deleted_at").Optional().Nillable().SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
|
||||
field.Time("output_deleted_at").Optional().Nillable().SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
|
||||
field.Time("downloaded_at").Optional().Nillable().SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
|
||||
field.Time("user_deleted_at").Optional().Nillable().SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
|
||||
field.String("last_error_code").Optional().Nillable().MaxLen(128),
|
||||
field.String("last_error_message").Optional().Nillable().SchemaType(map[string]string{dialect.Postgres: "text"}),
|
||||
field.Time("created_at").Immutable().Default(time.Now).SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
|
||||
field.Time("updated_at").Default(time.Now).UpdateDefault(time.Now).SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
|
||||
field.Time("submitted_at").Optional().Nillable().SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
|
||||
field.Time("started_at").Optional().Nillable().SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
|
||||
field.Time("finished_at").Optional().Nillable().SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
|
||||
field.Time("settled_at").Optional().Nillable().SchemaType(map[string]string{dialect.Postgres: "timestamptz"}),
|
||||
}
|
||||
}
|
||||
|
||||
func (BatchImageJob) Indexes() []ent.Index {
|
||||
return []ent.Index{
|
||||
index.Fields("batch_id").Unique(),
|
||||
index.Fields("user_id", "created_at"),
|
||||
index.Fields("status"),
|
||||
index.Fields("provider", "status"),
|
||||
index.Fields("idempotency_key").Annotations(entsql.IndexWhere("idempotency_key IS NOT NULL AND idempotency_key <> ''")),
|
||||
index.Fields("manifest_hash").Unique().Annotations(entsql.IndexWhere("manifest_hash IS NOT NULL AND manifest_hash <> ''")),
|
||||
index.Fields("output_expires_at"),
|
||||
index.Fields("downloaded_at"),
|
||||
index.Fields("user_deleted_at"),
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,7 @@ func (ChannelMonitor) Fields() []ent.Field {
|
||||
NotEmpty().
|
||||
MaxLen(100),
|
||||
field.Enum("provider").
|
||||
Values("openai", "anthropic", "gemini"),
|
||||
Values("openai", "anthropic", "gemini", "grok"),
|
||||
field.String("api_mode").
|
||||
Default("chat_completions").
|
||||
MaxLen(32).
|
||||
|
||||
@@ -39,7 +39,7 @@ func (ChannelMonitorRequestTemplate) Fields() []ent.Field {
|
||||
NotEmpty().
|
||||
MaxLen(100),
|
||||
field.Enum("provider").
|
||||
Values("openai", "anthropic", "gemini"),
|
||||
Values("openai", "anthropic", "gemini", "grok"),
|
||||
field.String("api_mode").
|
||||
Default("chat_completions").
|
||||
MaxLen(32).
|
||||
|
||||
@@ -45,6 +45,22 @@ func (Group) Fields() []ent.Field {
|
||||
field.Float("rate_multiplier").
|
||||
SchemaType(map[string]string{dialect.Postgres: "decimal(10,4)"}).
|
||||
Default(1.0),
|
||||
// 高峰时段倍率(added by migration 158)
|
||||
field.Bool("peak_rate_enabled").
|
||||
Default(false).
|
||||
Comment("是否启用高峰时段倍率"),
|
||||
field.String("peak_start").
|
||||
MaxLen(5).
|
||||
Default("").
|
||||
Comment("高峰开始时间 HH:MM(含),如 14:00;空表示未配置;不支持跨天"),
|
||||
field.String("peak_end").
|
||||
MaxLen(5).
|
||||
Default("").
|
||||
Comment("高峰结束时间 HH:MM(不含),必须大于 peak_start;不支持跨天,如 22:00-02:00"),
|
||||
field.Float("peak_rate_multiplier").
|
||||
SchemaType(map[string]string{dialect.Postgres: "decimal(10,4)"}).
|
||||
Default(1.0).
|
||||
Comment("高峰时段叠加倍率,仅在 peak_rate_enabled 且处于 [peak_start, peak_end) 时乘入文本倍率"),
|
||||
field.Bool("is_exclusive").
|
||||
Default(false),
|
||||
field.String("status").
|
||||
@@ -77,6 +93,9 @@ func (Group) Fields() []ent.Field {
|
||||
field.Bool("allow_image_generation").
|
||||
Default(false).
|
||||
Comment("是否允许该分组使用图片生成能力"),
|
||||
field.Bool("allow_batch_image_generation").
|
||||
Default(false).
|
||||
Comment("是否允许该分组使用批量图片生成能力"),
|
||||
field.Bool("image_rate_independent").
|
||||
Default(false).
|
||||
Comment("图片生成是否使用独立倍率;false 表示共享分组有效倍率"),
|
||||
@@ -96,6 +115,38 @@ func (Group) Fields() []ent.Field {
|
||||
Optional().
|
||||
Nillable().
|
||||
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}),
|
||||
field.Float("batch_image_discount_multiplier").
|
||||
SchemaType(map[string]string{dialect.Postgres: "decimal(10,4)"}).
|
||||
Default(0.5).
|
||||
Comment("批量图片生成折扣倍率,最终单价会乘以该值;0 表示免费"),
|
||||
field.Float("batch_image_hold_multiplier").
|
||||
SchemaType(map[string]string{dialect.Postgres: "decimal(10,4)"}).
|
||||
Default(0.6).
|
||||
Comment("批量图片生成冻结价格比例,按普通生图原价乘以该比例冻结,结算后释放差额"),
|
||||
field.Bool("video_rate_independent").
|
||||
Default(false).
|
||||
Comment("视频生成是否使用独立倍率;false 表示共享分组有效倍率"),
|
||||
field.Float("video_rate_multiplier").
|
||||
SchemaType(map[string]string{dialect.Postgres: "decimal(10,4)"}).
|
||||
Default(1.0).
|
||||
Comment("视频生成独立倍率,仅 video_rate_independent=true 时生效"),
|
||||
field.Float("video_price_480p").
|
||||
Optional().
|
||||
Nillable().
|
||||
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}),
|
||||
field.Float("video_price_720p").
|
||||
Optional().
|
||||
Nillable().
|
||||
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}),
|
||||
field.Float("video_price_1080p").
|
||||
Optional().
|
||||
Nillable().
|
||||
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}),
|
||||
field.Float("web_search_price_per_call").
|
||||
Optional().
|
||||
Nillable().
|
||||
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}).
|
||||
Comment("Codex alpha/search 网页搜索单次价格(USD/次);nil 表示使用默认价 0.01(官方 $10/1000 次)"),
|
||||
|
||||
// Claude Code 客户端限制 (added by migration 029)
|
||||
field.Bool("claude_code_only").
|
||||
|
||||
@@ -100,6 +100,9 @@ func (UsageLog) Fields() []ent.Field {
|
||||
field.Float("rate_multiplier").
|
||||
Default(1).
|
||||
SchemaType(map[string]string{dialect.Postgres: "decimal(10,4)"}),
|
||||
field.Bool("long_context_billing_applied").
|
||||
Default(false).
|
||||
Comment("Whether long-context pricing changed token prices for this request"),
|
||||
|
||||
// account_rate_multiplier: 账号计费倍率快照(NULL 表示按 1.0 处理)
|
||||
field.Float("account_rate_multiplier").
|
||||
@@ -149,6 +152,20 @@ func (UsageLog) Fields() []ent.Field {
|
||||
field.JSON("image_size_breakdown", map[string]int{}).
|
||||
Optional().
|
||||
SchemaType(map[string]string{dialect.Postgres: "jsonb"}),
|
||||
|
||||
// 视频生成字段(Grok 视频按秒计费;billing_mode 走 token/其他模式时这些列仍标记视频用量)
|
||||
field.Int("video_count").
|
||||
Default(0).
|
||||
Comment("视频生成数量;>0 表示本行是视频生成用量"),
|
||||
field.String("video_resolution").
|
||||
MaxLen(10).
|
||||
Optional().
|
||||
Nillable().
|
||||
Comment("计费用视频分辨率 480p/720p/1080p"),
|
||||
field.Int("video_duration_seconds").
|
||||
Optional().
|
||||
Nillable().
|
||||
Comment("提交时请求的视频时长(秒),按秒计费的乘数"),
|
||||
// Cache TTL Override 标记(管理员强制替换了缓存 TTL 计费)
|
||||
field.Bool("cache_ttl_overridden").
|
||||
Default(false),
|
||||
|
||||
@@ -49,6 +49,9 @@ func (User) Fields() []ent.Field {
|
||||
field.Float("balance").
|
||||
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}).
|
||||
Default(0),
|
||||
field.Float("frozen_balance").
|
||||
SchemaType(map[string]string{dialect.Postgres: "decimal(20,8)"}).
|
||||
Default(0),
|
||||
field.Int("concurrency").
|
||||
Default(5),
|
||||
field.String("status").
|
||||
|
||||
@@ -28,6 +28,12 @@ type Tx struct {
|
||||
AuthIdentity *AuthIdentityClient
|
||||
// AuthIdentityChannel is the client for interacting with the AuthIdentityChannel builders.
|
||||
AuthIdentityChannel *AuthIdentityChannelClient
|
||||
// BatchImageEvent is the client for interacting with the BatchImageEvent builders.
|
||||
BatchImageEvent *BatchImageEventClient
|
||||
// BatchImageItem is the client for interacting with the BatchImageItem builders.
|
||||
BatchImageItem *BatchImageItemClient
|
||||
// BatchImageJob is the client for interacting with the BatchImageJob builders.
|
||||
BatchImageJob *BatchImageJobClient
|
||||
// ChannelMonitor is the client for interacting with the ChannelMonitor builders.
|
||||
ChannelMonitor *ChannelMonitorClient
|
||||
// ChannelMonitorDailyRollup is the client for interacting with the ChannelMonitorDailyRollup builders.
|
||||
@@ -222,6 +228,9 @@ func (tx *Tx) init() {
|
||||
tx.AnnouncementRead = NewAnnouncementReadClient(tx.config)
|
||||
tx.AuthIdentity = NewAuthIdentityClient(tx.config)
|
||||
tx.AuthIdentityChannel = NewAuthIdentityChannelClient(tx.config)
|
||||
tx.BatchImageEvent = NewBatchImageEventClient(tx.config)
|
||||
tx.BatchImageItem = NewBatchImageItemClient(tx.config)
|
||||
tx.BatchImageJob = NewBatchImageJobClient(tx.config)
|
||||
tx.ChannelMonitor = NewChannelMonitorClient(tx.config)
|
||||
tx.ChannelMonitorDailyRollup = NewChannelMonitorDailyRollupClient(tx.config)
|
||||
tx.ChannelMonitorHistory = NewChannelMonitorHistoryClient(tx.config)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package ent
|
||||
|
||||
import "context"
|
||||
|
||||
// WithoutTx 返回一个剥离了所附 *Tx 的 ctx 副本,使调用方可以在基础 client
|
||||
// (autocommit)上执行 best-effort、非关键的副作用,而不加入——也就不会毒化——
|
||||
// 外层事务。
|
||||
//
|
||||
// Postgres 语义:事务内任一语句失败即把整个事务标记为 aborted,后续语句全部被拒,
|
||||
// 直到 ROLLBACK。因此对 fail-open 的副作用(如注册时的默认平台配额快照)必须做事务
|
||||
// 隔离,否则一条无关紧要的写入失败会连累调用方的关键事务。
|
||||
func WithoutTx(ctx context.Context) context.Context {
|
||||
if TxFromContext(ctx) == nil {
|
||||
return ctx
|
||||
}
|
||||
return context.WithValue(ctx, txCtxKey{}, (*Tx)(nil))
|
||||
}
|
||||
+53
-3
@@ -75,6 +75,8 @@ type UsageLog struct {
|
||||
ActualCost float64 `json:"actual_cost,omitempty"`
|
||||
// RateMultiplier holds the value of the "rate_multiplier" field.
|
||||
RateMultiplier float64 `json:"rate_multiplier,omitempty"`
|
||||
// Whether long-context pricing changed token prices for this request
|
||||
LongContextBillingApplied bool `json:"long_context_billing_applied,omitempty"`
|
||||
// AccountRateMultiplier holds the value of the "account_rate_multiplier" field.
|
||||
AccountRateMultiplier *float64 `json:"account_rate_multiplier,omitempty"`
|
||||
// BillingType holds the value of the "billing_type" field.
|
||||
@@ -101,6 +103,12 @@ type UsageLog struct {
|
||||
ImageSizeSource *string `json:"image_size_source,omitempty"`
|
||||
// ImageSizeBreakdown holds the value of the "image_size_breakdown" field.
|
||||
ImageSizeBreakdown map[string]int `json:"image_size_breakdown,omitempty"`
|
||||
// 视频生成数量;>0 表示本行是视频生成用量
|
||||
VideoCount int `json:"video_count,omitempty"`
|
||||
// 计费用视频分辨率 480p/720p/1080p
|
||||
VideoResolution *string `json:"video_resolution,omitempty"`
|
||||
// 提交时请求的视频时长(秒),按秒计费的乘数
|
||||
VideoDurationSeconds *int `json:"video_duration_seconds,omitempty"`
|
||||
// CacheTTLOverridden holds the value of the "cache_ttl_overridden" field.
|
||||
CacheTTLOverridden bool `json:"cache_ttl_overridden,omitempty"`
|
||||
// CreatedAt holds the value of the "created_at" field.
|
||||
@@ -190,13 +198,13 @@ func (*UsageLog) scanValues(columns []string) ([]any, error) {
|
||||
switch columns[i] {
|
||||
case usagelog.FieldImageSizeBreakdown:
|
||||
values[i] = new([]byte)
|
||||
case usagelog.FieldStream, usagelog.FieldCacheTTLOverridden:
|
||||
case usagelog.FieldLongContextBillingApplied, usagelog.FieldStream, usagelog.FieldCacheTTLOverridden:
|
||||
values[i] = new(sql.NullBool)
|
||||
case usagelog.FieldInputCost, usagelog.FieldOutputCost, usagelog.FieldCacheCreationCost, usagelog.FieldCacheReadCost, usagelog.FieldTotalCost, usagelog.FieldActualCost, usagelog.FieldRateMultiplier, usagelog.FieldAccountRateMultiplier:
|
||||
values[i] = new(sql.NullFloat64)
|
||||
case usagelog.FieldID, usagelog.FieldUserID, usagelog.FieldAPIKeyID, usagelog.FieldAccountID, usagelog.FieldChannelID, usagelog.FieldGroupID, usagelog.FieldSubscriptionID, usagelog.FieldInputTokens, usagelog.FieldOutputTokens, usagelog.FieldCacheCreationTokens, usagelog.FieldCacheReadTokens, usagelog.FieldCacheCreation5mTokens, usagelog.FieldCacheCreation1hTokens, usagelog.FieldBillingType, usagelog.FieldDurationMs, usagelog.FieldFirstTokenMs, usagelog.FieldImageCount:
|
||||
case usagelog.FieldID, usagelog.FieldUserID, usagelog.FieldAPIKeyID, usagelog.FieldAccountID, usagelog.FieldChannelID, usagelog.FieldGroupID, usagelog.FieldSubscriptionID, usagelog.FieldInputTokens, usagelog.FieldOutputTokens, usagelog.FieldCacheCreationTokens, usagelog.FieldCacheReadTokens, usagelog.FieldCacheCreation5mTokens, usagelog.FieldCacheCreation1hTokens, usagelog.FieldBillingType, usagelog.FieldDurationMs, usagelog.FieldFirstTokenMs, usagelog.FieldImageCount, usagelog.FieldVideoCount, usagelog.FieldVideoDurationSeconds:
|
||||
values[i] = new(sql.NullInt64)
|
||||
case usagelog.FieldRequestID, usagelog.FieldModel, usagelog.FieldRequestedModel, usagelog.FieldUpstreamModel, usagelog.FieldModelMappingChain, usagelog.FieldBillingTier, usagelog.FieldBillingMode, usagelog.FieldUserAgent, usagelog.FieldIPAddress, usagelog.FieldImageSize, usagelog.FieldImageInputSize, usagelog.FieldImageOutputSize, usagelog.FieldImageSizeSource:
|
||||
case usagelog.FieldRequestID, usagelog.FieldModel, usagelog.FieldRequestedModel, usagelog.FieldUpstreamModel, usagelog.FieldModelMappingChain, usagelog.FieldBillingTier, usagelog.FieldBillingMode, usagelog.FieldUserAgent, usagelog.FieldIPAddress, usagelog.FieldImageSize, usagelog.FieldImageInputSize, usagelog.FieldImageOutputSize, usagelog.FieldImageSizeSource, usagelog.FieldVideoResolution:
|
||||
values[i] = new(sql.NullString)
|
||||
case usagelog.FieldCreatedAt:
|
||||
values[i] = new(sql.NullTime)
|
||||
@@ -385,6 +393,12 @@ func (_m *UsageLog) assignValues(columns []string, values []any) error {
|
||||
} else if value.Valid {
|
||||
_m.RateMultiplier = value.Float64
|
||||
}
|
||||
case usagelog.FieldLongContextBillingApplied:
|
||||
if value, ok := values[i].(*sql.NullBool); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field long_context_billing_applied", values[i])
|
||||
} else if value.Valid {
|
||||
_m.LongContextBillingApplied = value.Bool
|
||||
}
|
||||
case usagelog.FieldAccountRateMultiplier:
|
||||
if value, ok := values[i].(*sql.NullFloat64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field account_rate_multiplier", values[i])
|
||||
@@ -474,6 +488,26 @@ func (_m *UsageLog) assignValues(columns []string, values []any) error {
|
||||
return fmt.Errorf("unmarshal field image_size_breakdown: %w", err)
|
||||
}
|
||||
}
|
||||
case usagelog.FieldVideoCount:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field video_count", values[i])
|
||||
} else if value.Valid {
|
||||
_m.VideoCount = int(value.Int64)
|
||||
}
|
||||
case usagelog.FieldVideoResolution:
|
||||
if value, ok := values[i].(*sql.NullString); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field video_resolution", values[i])
|
||||
} else if value.Valid {
|
||||
_m.VideoResolution = new(string)
|
||||
*_m.VideoResolution = value.String
|
||||
}
|
||||
case usagelog.FieldVideoDurationSeconds:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field video_duration_seconds", values[i])
|
||||
} else if value.Valid {
|
||||
_m.VideoDurationSeconds = new(int)
|
||||
*_m.VideoDurationSeconds = int(value.Int64)
|
||||
}
|
||||
case usagelog.FieldCacheTTLOverridden:
|
||||
if value, ok := values[i].(*sql.NullBool); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field cache_ttl_overridden", values[i])
|
||||
@@ -641,6 +675,9 @@ func (_m *UsageLog) String() string {
|
||||
builder.WriteString("rate_multiplier=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.RateMultiplier))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("long_context_billing_applied=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.LongContextBillingApplied))
|
||||
builder.WriteString(", ")
|
||||
if v := _m.AccountRateMultiplier; v != nil {
|
||||
builder.WriteString("account_rate_multiplier=")
|
||||
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||
@@ -698,6 +735,19 @@ func (_m *UsageLog) String() string {
|
||||
builder.WriteString("image_size_breakdown=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.ImageSizeBreakdown))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("video_count=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.VideoCount))
|
||||
builder.WriteString(", ")
|
||||
if v := _m.VideoResolution; v != nil {
|
||||
builder.WriteString("video_resolution=")
|
||||
builder.WriteString(*v)
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
if v := _m.VideoDurationSeconds; v != nil {
|
||||
builder.WriteString("video_duration_seconds=")
|
||||
builder.WriteString(fmt.Sprintf("%v", *v))
|
||||
}
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("cache_ttl_overridden=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.CacheTTLOverridden))
|
||||
builder.WriteString(", ")
|
||||
|
||||
@@ -66,6 +66,8 @@ const (
|
||||
FieldActualCost = "actual_cost"
|
||||
// FieldRateMultiplier holds the string denoting the rate_multiplier field in the database.
|
||||
FieldRateMultiplier = "rate_multiplier"
|
||||
// FieldLongContextBillingApplied holds the string denoting the long_context_billing_applied field in the database.
|
||||
FieldLongContextBillingApplied = "long_context_billing_applied"
|
||||
// FieldAccountRateMultiplier holds the string denoting the account_rate_multiplier field in the database.
|
||||
FieldAccountRateMultiplier = "account_rate_multiplier"
|
||||
// FieldBillingType holds the string denoting the billing_type field in the database.
|
||||
@@ -92,6 +94,12 @@ const (
|
||||
FieldImageSizeSource = "image_size_source"
|
||||
// FieldImageSizeBreakdown holds the string denoting the image_size_breakdown field in the database.
|
||||
FieldImageSizeBreakdown = "image_size_breakdown"
|
||||
// FieldVideoCount holds the string denoting the video_count field in the database.
|
||||
FieldVideoCount = "video_count"
|
||||
// FieldVideoResolution holds the string denoting the video_resolution field in the database.
|
||||
FieldVideoResolution = "video_resolution"
|
||||
// FieldVideoDurationSeconds holds the string denoting the video_duration_seconds field in the database.
|
||||
FieldVideoDurationSeconds = "video_duration_seconds"
|
||||
// FieldCacheTTLOverridden holds the string denoting the cache_ttl_overridden field in the database.
|
||||
FieldCacheTTLOverridden = "cache_ttl_overridden"
|
||||
// FieldCreatedAt holds the string denoting the created_at field in the database.
|
||||
@@ -174,6 +182,7 @@ var Columns = []string{
|
||||
FieldTotalCost,
|
||||
FieldActualCost,
|
||||
FieldRateMultiplier,
|
||||
FieldLongContextBillingApplied,
|
||||
FieldAccountRateMultiplier,
|
||||
FieldBillingType,
|
||||
FieldStream,
|
||||
@@ -187,6 +196,9 @@ var Columns = []string{
|
||||
FieldImageOutputSize,
|
||||
FieldImageSizeSource,
|
||||
FieldImageSizeBreakdown,
|
||||
FieldVideoCount,
|
||||
FieldVideoResolution,
|
||||
FieldVideoDurationSeconds,
|
||||
FieldCacheTTLOverridden,
|
||||
FieldCreatedAt,
|
||||
}
|
||||
@@ -242,6 +254,8 @@ var (
|
||||
DefaultActualCost float64
|
||||
// DefaultRateMultiplier holds the default value on creation for the "rate_multiplier" field.
|
||||
DefaultRateMultiplier float64
|
||||
// DefaultLongContextBillingApplied holds the default value on creation for the "long_context_billing_applied" field.
|
||||
DefaultLongContextBillingApplied bool
|
||||
// DefaultBillingType holds the default value on creation for the "billing_type" field.
|
||||
DefaultBillingType int8
|
||||
// DefaultStream holds the default value on creation for the "stream" field.
|
||||
@@ -260,6 +274,10 @@ var (
|
||||
ImageOutputSizeValidator func(string) error
|
||||
// ImageSizeSourceValidator is a validator for the "image_size_source" field. It is called by the builders before save.
|
||||
ImageSizeSourceValidator func(string) error
|
||||
// DefaultVideoCount holds the default value on creation for the "video_count" field.
|
||||
DefaultVideoCount int
|
||||
// VideoResolutionValidator is a validator for the "video_resolution" field. It is called by the builders before save.
|
||||
VideoResolutionValidator func(string) error
|
||||
// DefaultCacheTTLOverridden holds the default value on creation for the "cache_ttl_overridden" field.
|
||||
DefaultCacheTTLOverridden bool
|
||||
// DefaultCreatedAt holds the default value on creation for the "created_at" field.
|
||||
@@ -404,6 +422,11 @@ func ByRateMultiplier(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldRateMultiplier, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByLongContextBillingApplied orders the results by the long_context_billing_applied field.
|
||||
func ByLongContextBillingApplied(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldLongContextBillingApplied, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByAccountRateMultiplier orders the results by the account_rate_multiplier field.
|
||||
func ByAccountRateMultiplier(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldAccountRateMultiplier, opts...).ToFunc()
|
||||
@@ -464,6 +487,21 @@ func ByImageSizeSource(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldImageSizeSource, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByVideoCount orders the results by the video_count field.
|
||||
func ByVideoCount(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldVideoCount, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByVideoResolution orders the results by the video_resolution field.
|
||||
func ByVideoResolution(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldVideoResolution, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByVideoDurationSeconds orders the results by the video_duration_seconds field.
|
||||
func ByVideoDurationSeconds(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldVideoDurationSeconds, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByCacheTTLOverridden orders the results by the cache_ttl_overridden field.
|
||||
func ByCacheTTLOverridden(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldCacheTTLOverridden, opts...).ToFunc()
|
||||
|
||||
@@ -185,6 +185,11 @@ func RateMultiplier(v float64) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldEQ(FieldRateMultiplier, v))
|
||||
}
|
||||
|
||||
// LongContextBillingApplied applies equality check predicate on the "long_context_billing_applied" field. It's identical to LongContextBillingAppliedEQ.
|
||||
func LongContextBillingApplied(v bool) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldEQ(FieldLongContextBillingApplied, v))
|
||||
}
|
||||
|
||||
// AccountRateMultiplier applies equality check predicate on the "account_rate_multiplier" field. It's identical to AccountRateMultiplierEQ.
|
||||
func AccountRateMultiplier(v float64) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldEQ(FieldAccountRateMultiplier, v))
|
||||
@@ -245,6 +250,21 @@ func ImageSizeSource(v string) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldEQ(FieldImageSizeSource, v))
|
||||
}
|
||||
|
||||
// VideoCount applies equality check predicate on the "video_count" field. It's identical to VideoCountEQ.
|
||||
func VideoCount(v int) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldEQ(FieldVideoCount, v))
|
||||
}
|
||||
|
||||
// VideoResolution applies equality check predicate on the "video_resolution" field. It's identical to VideoResolutionEQ.
|
||||
func VideoResolution(v string) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldEQ(FieldVideoResolution, v))
|
||||
}
|
||||
|
||||
// VideoDurationSeconds applies equality check predicate on the "video_duration_seconds" field. It's identical to VideoDurationSecondsEQ.
|
||||
func VideoDurationSeconds(v int) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldEQ(FieldVideoDurationSeconds, v))
|
||||
}
|
||||
|
||||
// CacheTTLOverridden applies equality check predicate on the "cache_ttl_overridden" field. It's identical to CacheTTLOverriddenEQ.
|
||||
func CacheTTLOverridden(v bool) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldEQ(FieldCacheTTLOverridden, v))
|
||||
@@ -1450,6 +1470,16 @@ func RateMultiplierLTE(v float64) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldLTE(FieldRateMultiplier, v))
|
||||
}
|
||||
|
||||
// LongContextBillingAppliedEQ applies the EQ predicate on the "long_context_billing_applied" field.
|
||||
func LongContextBillingAppliedEQ(v bool) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldEQ(FieldLongContextBillingApplied, v))
|
||||
}
|
||||
|
||||
// LongContextBillingAppliedNEQ applies the NEQ predicate on the "long_context_billing_applied" field.
|
||||
func LongContextBillingAppliedNEQ(v bool) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldNEQ(FieldLongContextBillingApplied, v))
|
||||
}
|
||||
|
||||
// AccountRateMultiplierEQ applies the EQ predicate on the "account_rate_multiplier" field.
|
||||
func AccountRateMultiplierEQ(v float64) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldEQ(FieldAccountRateMultiplier, v))
|
||||
@@ -2150,6 +2180,171 @@ func ImageSizeBreakdownNotNil() predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldNotNull(FieldImageSizeBreakdown))
|
||||
}
|
||||
|
||||
// VideoCountEQ applies the EQ predicate on the "video_count" field.
|
||||
func VideoCountEQ(v int) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldEQ(FieldVideoCount, v))
|
||||
}
|
||||
|
||||
// VideoCountNEQ applies the NEQ predicate on the "video_count" field.
|
||||
func VideoCountNEQ(v int) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldNEQ(FieldVideoCount, v))
|
||||
}
|
||||
|
||||
// VideoCountIn applies the In predicate on the "video_count" field.
|
||||
func VideoCountIn(vs ...int) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldIn(FieldVideoCount, vs...))
|
||||
}
|
||||
|
||||
// VideoCountNotIn applies the NotIn predicate on the "video_count" field.
|
||||
func VideoCountNotIn(vs ...int) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldNotIn(FieldVideoCount, vs...))
|
||||
}
|
||||
|
||||
// VideoCountGT applies the GT predicate on the "video_count" field.
|
||||
func VideoCountGT(v int) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldGT(FieldVideoCount, v))
|
||||
}
|
||||
|
||||
// VideoCountGTE applies the GTE predicate on the "video_count" field.
|
||||
func VideoCountGTE(v int) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldGTE(FieldVideoCount, v))
|
||||
}
|
||||
|
||||
// VideoCountLT applies the LT predicate on the "video_count" field.
|
||||
func VideoCountLT(v int) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldLT(FieldVideoCount, v))
|
||||
}
|
||||
|
||||
// VideoCountLTE applies the LTE predicate on the "video_count" field.
|
||||
func VideoCountLTE(v int) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldLTE(FieldVideoCount, v))
|
||||
}
|
||||
|
||||
// VideoResolutionEQ applies the EQ predicate on the "video_resolution" field.
|
||||
func VideoResolutionEQ(v string) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldEQ(FieldVideoResolution, v))
|
||||
}
|
||||
|
||||
// VideoResolutionNEQ applies the NEQ predicate on the "video_resolution" field.
|
||||
func VideoResolutionNEQ(v string) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldNEQ(FieldVideoResolution, v))
|
||||
}
|
||||
|
||||
// VideoResolutionIn applies the In predicate on the "video_resolution" field.
|
||||
func VideoResolutionIn(vs ...string) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldIn(FieldVideoResolution, vs...))
|
||||
}
|
||||
|
||||
// VideoResolutionNotIn applies the NotIn predicate on the "video_resolution" field.
|
||||
func VideoResolutionNotIn(vs ...string) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldNotIn(FieldVideoResolution, vs...))
|
||||
}
|
||||
|
||||
// VideoResolutionGT applies the GT predicate on the "video_resolution" field.
|
||||
func VideoResolutionGT(v string) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldGT(FieldVideoResolution, v))
|
||||
}
|
||||
|
||||
// VideoResolutionGTE applies the GTE predicate on the "video_resolution" field.
|
||||
func VideoResolutionGTE(v string) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldGTE(FieldVideoResolution, v))
|
||||
}
|
||||
|
||||
// VideoResolutionLT applies the LT predicate on the "video_resolution" field.
|
||||
func VideoResolutionLT(v string) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldLT(FieldVideoResolution, v))
|
||||
}
|
||||
|
||||
// VideoResolutionLTE applies the LTE predicate on the "video_resolution" field.
|
||||
func VideoResolutionLTE(v string) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldLTE(FieldVideoResolution, v))
|
||||
}
|
||||
|
||||
// VideoResolutionContains applies the Contains predicate on the "video_resolution" field.
|
||||
func VideoResolutionContains(v string) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldContains(FieldVideoResolution, v))
|
||||
}
|
||||
|
||||
// VideoResolutionHasPrefix applies the HasPrefix predicate on the "video_resolution" field.
|
||||
func VideoResolutionHasPrefix(v string) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldHasPrefix(FieldVideoResolution, v))
|
||||
}
|
||||
|
||||
// VideoResolutionHasSuffix applies the HasSuffix predicate on the "video_resolution" field.
|
||||
func VideoResolutionHasSuffix(v string) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldHasSuffix(FieldVideoResolution, v))
|
||||
}
|
||||
|
||||
// VideoResolutionIsNil applies the IsNil predicate on the "video_resolution" field.
|
||||
func VideoResolutionIsNil() predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldIsNull(FieldVideoResolution))
|
||||
}
|
||||
|
||||
// VideoResolutionNotNil applies the NotNil predicate on the "video_resolution" field.
|
||||
func VideoResolutionNotNil() predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldNotNull(FieldVideoResolution))
|
||||
}
|
||||
|
||||
// VideoResolutionEqualFold applies the EqualFold predicate on the "video_resolution" field.
|
||||
func VideoResolutionEqualFold(v string) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldEqualFold(FieldVideoResolution, v))
|
||||
}
|
||||
|
||||
// VideoResolutionContainsFold applies the ContainsFold predicate on the "video_resolution" field.
|
||||
func VideoResolutionContainsFold(v string) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldContainsFold(FieldVideoResolution, v))
|
||||
}
|
||||
|
||||
// VideoDurationSecondsEQ applies the EQ predicate on the "video_duration_seconds" field.
|
||||
func VideoDurationSecondsEQ(v int) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldEQ(FieldVideoDurationSeconds, v))
|
||||
}
|
||||
|
||||
// VideoDurationSecondsNEQ applies the NEQ predicate on the "video_duration_seconds" field.
|
||||
func VideoDurationSecondsNEQ(v int) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldNEQ(FieldVideoDurationSeconds, v))
|
||||
}
|
||||
|
||||
// VideoDurationSecondsIn applies the In predicate on the "video_duration_seconds" field.
|
||||
func VideoDurationSecondsIn(vs ...int) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldIn(FieldVideoDurationSeconds, vs...))
|
||||
}
|
||||
|
||||
// VideoDurationSecondsNotIn applies the NotIn predicate on the "video_duration_seconds" field.
|
||||
func VideoDurationSecondsNotIn(vs ...int) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldNotIn(FieldVideoDurationSeconds, vs...))
|
||||
}
|
||||
|
||||
// VideoDurationSecondsGT applies the GT predicate on the "video_duration_seconds" field.
|
||||
func VideoDurationSecondsGT(v int) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldGT(FieldVideoDurationSeconds, v))
|
||||
}
|
||||
|
||||
// VideoDurationSecondsGTE applies the GTE predicate on the "video_duration_seconds" field.
|
||||
func VideoDurationSecondsGTE(v int) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldGTE(FieldVideoDurationSeconds, v))
|
||||
}
|
||||
|
||||
// VideoDurationSecondsLT applies the LT predicate on the "video_duration_seconds" field.
|
||||
func VideoDurationSecondsLT(v int) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldLT(FieldVideoDurationSeconds, v))
|
||||
}
|
||||
|
||||
// VideoDurationSecondsLTE applies the LTE predicate on the "video_duration_seconds" field.
|
||||
func VideoDurationSecondsLTE(v int) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldLTE(FieldVideoDurationSeconds, v))
|
||||
}
|
||||
|
||||
// VideoDurationSecondsIsNil applies the IsNil predicate on the "video_duration_seconds" field.
|
||||
func VideoDurationSecondsIsNil() predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldIsNull(FieldVideoDurationSeconds))
|
||||
}
|
||||
|
||||
// VideoDurationSecondsNotNil applies the NotNil predicate on the "video_duration_seconds" field.
|
||||
func VideoDurationSecondsNotNil() predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldNotNull(FieldVideoDurationSeconds))
|
||||
}
|
||||
|
||||
// CacheTTLOverriddenEQ applies the EQ predicate on the "cache_ttl_overridden" field.
|
||||
func CacheTTLOverriddenEQ(v bool) predicate.UsageLog {
|
||||
return predicate.UsageLog(sql.FieldEQ(FieldCacheTTLOverridden, v))
|
||||
|
||||
@@ -351,6 +351,20 @@ func (_c *UsageLogCreate) SetNillableRateMultiplier(v *float64) *UsageLogCreate
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetLongContextBillingApplied sets the "long_context_billing_applied" field.
|
||||
func (_c *UsageLogCreate) SetLongContextBillingApplied(v bool) *UsageLogCreate {
|
||||
_c.mutation.SetLongContextBillingApplied(v)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetNillableLongContextBillingApplied sets the "long_context_billing_applied" field if the given value is not nil.
|
||||
func (_c *UsageLogCreate) SetNillableLongContextBillingApplied(v *bool) *UsageLogCreate {
|
||||
if v != nil {
|
||||
_c.SetLongContextBillingApplied(*v)
|
||||
}
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetAccountRateMultiplier sets the "account_rate_multiplier" field.
|
||||
func (_c *UsageLogCreate) SetAccountRateMultiplier(v float64) *UsageLogCreate {
|
||||
_c.mutation.SetAccountRateMultiplier(v)
|
||||
@@ -525,6 +539,48 @@ func (_c *UsageLogCreate) SetImageSizeBreakdown(v map[string]int) *UsageLogCreat
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetVideoCount sets the "video_count" field.
|
||||
func (_c *UsageLogCreate) SetVideoCount(v int) *UsageLogCreate {
|
||||
_c.mutation.SetVideoCount(v)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetNillableVideoCount sets the "video_count" field if the given value is not nil.
|
||||
func (_c *UsageLogCreate) SetNillableVideoCount(v *int) *UsageLogCreate {
|
||||
if v != nil {
|
||||
_c.SetVideoCount(*v)
|
||||
}
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetVideoResolution sets the "video_resolution" field.
|
||||
func (_c *UsageLogCreate) SetVideoResolution(v string) *UsageLogCreate {
|
||||
_c.mutation.SetVideoResolution(v)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetNillableVideoResolution sets the "video_resolution" field if the given value is not nil.
|
||||
func (_c *UsageLogCreate) SetNillableVideoResolution(v *string) *UsageLogCreate {
|
||||
if v != nil {
|
||||
_c.SetVideoResolution(*v)
|
||||
}
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetVideoDurationSeconds sets the "video_duration_seconds" field.
|
||||
func (_c *UsageLogCreate) SetVideoDurationSeconds(v int) *UsageLogCreate {
|
||||
_c.mutation.SetVideoDurationSeconds(v)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetNillableVideoDurationSeconds sets the "video_duration_seconds" field if the given value is not nil.
|
||||
func (_c *UsageLogCreate) SetNillableVideoDurationSeconds(v *int) *UsageLogCreate {
|
||||
if v != nil {
|
||||
_c.SetVideoDurationSeconds(*v)
|
||||
}
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetCacheTTLOverridden sets the "cache_ttl_overridden" field.
|
||||
func (_c *UsageLogCreate) SetCacheTTLOverridden(v bool) *UsageLogCreate {
|
||||
_c.mutation.SetCacheTTLOverridden(v)
|
||||
@@ -665,6 +721,10 @@ func (_c *UsageLogCreate) defaults() {
|
||||
v := usagelog.DefaultRateMultiplier
|
||||
_c.mutation.SetRateMultiplier(v)
|
||||
}
|
||||
if _, ok := _c.mutation.LongContextBillingApplied(); !ok {
|
||||
v := usagelog.DefaultLongContextBillingApplied
|
||||
_c.mutation.SetLongContextBillingApplied(v)
|
||||
}
|
||||
if _, ok := _c.mutation.BillingType(); !ok {
|
||||
v := usagelog.DefaultBillingType
|
||||
_c.mutation.SetBillingType(v)
|
||||
@@ -677,6 +737,10 @@ func (_c *UsageLogCreate) defaults() {
|
||||
v := usagelog.DefaultImageCount
|
||||
_c.mutation.SetImageCount(v)
|
||||
}
|
||||
if _, ok := _c.mutation.VideoCount(); !ok {
|
||||
v := usagelog.DefaultVideoCount
|
||||
_c.mutation.SetVideoCount(v)
|
||||
}
|
||||
if _, ok := _c.mutation.CacheTTLOverridden(); !ok {
|
||||
v := usagelog.DefaultCacheTTLOverridden
|
||||
_c.mutation.SetCacheTTLOverridden(v)
|
||||
@@ -778,6 +842,9 @@ func (_c *UsageLogCreate) check() error {
|
||||
if _, ok := _c.mutation.RateMultiplier(); !ok {
|
||||
return &ValidationError{Name: "rate_multiplier", err: errors.New(`ent: missing required field "UsageLog.rate_multiplier"`)}
|
||||
}
|
||||
if _, ok := _c.mutation.LongContextBillingApplied(); !ok {
|
||||
return &ValidationError{Name: "long_context_billing_applied", err: errors.New(`ent: missing required field "UsageLog.long_context_billing_applied"`)}
|
||||
}
|
||||
if _, ok := _c.mutation.BillingType(); !ok {
|
||||
return &ValidationError{Name: "billing_type", err: errors.New(`ent: missing required field "UsageLog.billing_type"`)}
|
||||
}
|
||||
@@ -817,6 +884,14 @@ func (_c *UsageLogCreate) check() error {
|
||||
return &ValidationError{Name: "image_size_source", err: fmt.Errorf(`ent: validator failed for field "UsageLog.image_size_source": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := _c.mutation.VideoCount(); !ok {
|
||||
return &ValidationError{Name: "video_count", err: errors.New(`ent: missing required field "UsageLog.video_count"`)}
|
||||
}
|
||||
if v, ok := _c.mutation.VideoResolution(); ok {
|
||||
if err := usagelog.VideoResolutionValidator(v); err != nil {
|
||||
return &ValidationError{Name: "video_resolution", err: fmt.Errorf(`ent: validator failed for field "UsageLog.video_resolution": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _, ok := _c.mutation.CacheTTLOverridden(); !ok {
|
||||
return &ValidationError{Name: "cache_ttl_overridden", err: errors.New(`ent: missing required field "UsageLog.cache_ttl_overridden"`)}
|
||||
}
|
||||
@@ -943,6 +1018,10 @@ func (_c *UsageLogCreate) createSpec() (*UsageLog, *sqlgraph.CreateSpec) {
|
||||
_spec.SetField(usagelog.FieldRateMultiplier, field.TypeFloat64, value)
|
||||
_node.RateMultiplier = value
|
||||
}
|
||||
if value, ok := _c.mutation.LongContextBillingApplied(); ok {
|
||||
_spec.SetField(usagelog.FieldLongContextBillingApplied, field.TypeBool, value)
|
||||
_node.LongContextBillingApplied = value
|
||||
}
|
||||
if value, ok := _c.mutation.AccountRateMultiplier(); ok {
|
||||
_spec.SetField(usagelog.FieldAccountRateMultiplier, field.TypeFloat64, value)
|
||||
_node.AccountRateMultiplier = &value
|
||||
@@ -995,6 +1074,18 @@ func (_c *UsageLogCreate) createSpec() (*UsageLog, *sqlgraph.CreateSpec) {
|
||||
_spec.SetField(usagelog.FieldImageSizeBreakdown, field.TypeJSON, value)
|
||||
_node.ImageSizeBreakdown = value
|
||||
}
|
||||
if value, ok := _c.mutation.VideoCount(); ok {
|
||||
_spec.SetField(usagelog.FieldVideoCount, field.TypeInt, value)
|
||||
_node.VideoCount = value
|
||||
}
|
||||
if value, ok := _c.mutation.VideoResolution(); ok {
|
||||
_spec.SetField(usagelog.FieldVideoResolution, field.TypeString, value)
|
||||
_node.VideoResolution = &value
|
||||
}
|
||||
if value, ok := _c.mutation.VideoDurationSeconds(); ok {
|
||||
_spec.SetField(usagelog.FieldVideoDurationSeconds, field.TypeInt, value)
|
||||
_node.VideoDurationSeconds = &value
|
||||
}
|
||||
if value, ok := _c.mutation.CacheTTLOverridden(); ok {
|
||||
_spec.SetField(usagelog.FieldCacheTTLOverridden, field.TypeBool, value)
|
||||
_node.CacheTTLOverridden = value
|
||||
@@ -1584,6 +1675,18 @@ func (u *UsageLogUpsert) AddRateMultiplier(v float64) *UsageLogUpsert {
|
||||
return u
|
||||
}
|
||||
|
||||
// SetLongContextBillingApplied sets the "long_context_billing_applied" field.
|
||||
func (u *UsageLogUpsert) SetLongContextBillingApplied(v bool) *UsageLogUpsert {
|
||||
u.Set(usagelog.FieldLongContextBillingApplied, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateLongContextBillingApplied sets the "long_context_billing_applied" field to the value that was provided on create.
|
||||
func (u *UsageLogUpsert) UpdateLongContextBillingApplied() *UsageLogUpsert {
|
||||
u.SetExcluded(usagelog.FieldLongContextBillingApplied)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetAccountRateMultiplier sets the "account_rate_multiplier" field.
|
||||
func (u *UsageLogUpsert) SetAccountRateMultiplier(v float64) *UsageLogUpsert {
|
||||
u.Set(usagelog.FieldAccountRateMultiplier, v)
|
||||
@@ -1830,6 +1933,66 @@ func (u *UsageLogUpsert) ClearImageSizeBreakdown() *UsageLogUpsert {
|
||||
return u
|
||||
}
|
||||
|
||||
// SetVideoCount sets the "video_count" field.
|
||||
func (u *UsageLogUpsert) SetVideoCount(v int) *UsageLogUpsert {
|
||||
u.Set(usagelog.FieldVideoCount, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateVideoCount sets the "video_count" field to the value that was provided on create.
|
||||
func (u *UsageLogUpsert) UpdateVideoCount() *UsageLogUpsert {
|
||||
u.SetExcluded(usagelog.FieldVideoCount)
|
||||
return u
|
||||
}
|
||||
|
||||
// AddVideoCount adds v to the "video_count" field.
|
||||
func (u *UsageLogUpsert) AddVideoCount(v int) *UsageLogUpsert {
|
||||
u.Add(usagelog.FieldVideoCount, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetVideoResolution sets the "video_resolution" field.
|
||||
func (u *UsageLogUpsert) SetVideoResolution(v string) *UsageLogUpsert {
|
||||
u.Set(usagelog.FieldVideoResolution, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateVideoResolution sets the "video_resolution" field to the value that was provided on create.
|
||||
func (u *UsageLogUpsert) UpdateVideoResolution() *UsageLogUpsert {
|
||||
u.SetExcluded(usagelog.FieldVideoResolution)
|
||||
return u
|
||||
}
|
||||
|
||||
// ClearVideoResolution clears the value of the "video_resolution" field.
|
||||
func (u *UsageLogUpsert) ClearVideoResolution() *UsageLogUpsert {
|
||||
u.SetNull(usagelog.FieldVideoResolution)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetVideoDurationSeconds sets the "video_duration_seconds" field.
|
||||
func (u *UsageLogUpsert) SetVideoDurationSeconds(v int) *UsageLogUpsert {
|
||||
u.Set(usagelog.FieldVideoDurationSeconds, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateVideoDurationSeconds sets the "video_duration_seconds" field to the value that was provided on create.
|
||||
func (u *UsageLogUpsert) UpdateVideoDurationSeconds() *UsageLogUpsert {
|
||||
u.SetExcluded(usagelog.FieldVideoDurationSeconds)
|
||||
return u
|
||||
}
|
||||
|
||||
// AddVideoDurationSeconds adds v to the "video_duration_seconds" field.
|
||||
func (u *UsageLogUpsert) AddVideoDurationSeconds(v int) *UsageLogUpsert {
|
||||
u.Add(usagelog.FieldVideoDurationSeconds, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// ClearVideoDurationSeconds clears the value of the "video_duration_seconds" field.
|
||||
func (u *UsageLogUpsert) ClearVideoDurationSeconds() *UsageLogUpsert {
|
||||
u.SetNull(usagelog.FieldVideoDurationSeconds)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetCacheTTLOverridden sets the "cache_ttl_overridden" field.
|
||||
func (u *UsageLogUpsert) SetCacheTTLOverridden(v bool) *UsageLogUpsert {
|
||||
u.Set(usagelog.FieldCacheTTLOverridden, v)
|
||||
@@ -2405,6 +2568,20 @@ func (u *UsageLogUpsertOne) UpdateRateMultiplier() *UsageLogUpsertOne {
|
||||
})
|
||||
}
|
||||
|
||||
// SetLongContextBillingApplied sets the "long_context_billing_applied" field.
|
||||
func (u *UsageLogUpsertOne) SetLongContextBillingApplied(v bool) *UsageLogUpsertOne {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.SetLongContextBillingApplied(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateLongContextBillingApplied sets the "long_context_billing_applied" field to the value that was provided on create.
|
||||
func (u *UsageLogUpsertOne) UpdateLongContextBillingApplied() *UsageLogUpsertOne {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.UpdateLongContextBillingApplied()
|
||||
})
|
||||
}
|
||||
|
||||
// SetAccountRateMultiplier sets the "account_rate_multiplier" field.
|
||||
func (u *UsageLogUpsertOne) SetAccountRateMultiplier(v float64) *UsageLogUpsertOne {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
@@ -2692,6 +2869,76 @@ func (u *UsageLogUpsertOne) ClearImageSizeBreakdown() *UsageLogUpsertOne {
|
||||
})
|
||||
}
|
||||
|
||||
// SetVideoCount sets the "video_count" field.
|
||||
func (u *UsageLogUpsertOne) SetVideoCount(v int) *UsageLogUpsertOne {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.SetVideoCount(v)
|
||||
})
|
||||
}
|
||||
|
||||
// AddVideoCount adds v to the "video_count" field.
|
||||
func (u *UsageLogUpsertOne) AddVideoCount(v int) *UsageLogUpsertOne {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.AddVideoCount(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateVideoCount sets the "video_count" field to the value that was provided on create.
|
||||
func (u *UsageLogUpsertOne) UpdateVideoCount() *UsageLogUpsertOne {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.UpdateVideoCount()
|
||||
})
|
||||
}
|
||||
|
||||
// SetVideoResolution sets the "video_resolution" field.
|
||||
func (u *UsageLogUpsertOne) SetVideoResolution(v string) *UsageLogUpsertOne {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.SetVideoResolution(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateVideoResolution sets the "video_resolution" field to the value that was provided on create.
|
||||
func (u *UsageLogUpsertOne) UpdateVideoResolution() *UsageLogUpsertOne {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.UpdateVideoResolution()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearVideoResolution clears the value of the "video_resolution" field.
|
||||
func (u *UsageLogUpsertOne) ClearVideoResolution() *UsageLogUpsertOne {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.ClearVideoResolution()
|
||||
})
|
||||
}
|
||||
|
||||
// SetVideoDurationSeconds sets the "video_duration_seconds" field.
|
||||
func (u *UsageLogUpsertOne) SetVideoDurationSeconds(v int) *UsageLogUpsertOne {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.SetVideoDurationSeconds(v)
|
||||
})
|
||||
}
|
||||
|
||||
// AddVideoDurationSeconds adds v to the "video_duration_seconds" field.
|
||||
func (u *UsageLogUpsertOne) AddVideoDurationSeconds(v int) *UsageLogUpsertOne {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.AddVideoDurationSeconds(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateVideoDurationSeconds sets the "video_duration_seconds" field to the value that was provided on create.
|
||||
func (u *UsageLogUpsertOne) UpdateVideoDurationSeconds() *UsageLogUpsertOne {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.UpdateVideoDurationSeconds()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearVideoDurationSeconds clears the value of the "video_duration_seconds" field.
|
||||
func (u *UsageLogUpsertOne) ClearVideoDurationSeconds() *UsageLogUpsertOne {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.ClearVideoDurationSeconds()
|
||||
})
|
||||
}
|
||||
|
||||
// SetCacheTTLOverridden sets the "cache_ttl_overridden" field.
|
||||
func (u *UsageLogUpsertOne) SetCacheTTLOverridden(v bool) *UsageLogUpsertOne {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
@@ -3435,6 +3682,20 @@ func (u *UsageLogUpsertBulk) UpdateRateMultiplier() *UsageLogUpsertBulk {
|
||||
})
|
||||
}
|
||||
|
||||
// SetLongContextBillingApplied sets the "long_context_billing_applied" field.
|
||||
func (u *UsageLogUpsertBulk) SetLongContextBillingApplied(v bool) *UsageLogUpsertBulk {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.SetLongContextBillingApplied(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateLongContextBillingApplied sets the "long_context_billing_applied" field to the value that was provided on create.
|
||||
func (u *UsageLogUpsertBulk) UpdateLongContextBillingApplied() *UsageLogUpsertBulk {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.UpdateLongContextBillingApplied()
|
||||
})
|
||||
}
|
||||
|
||||
// SetAccountRateMultiplier sets the "account_rate_multiplier" field.
|
||||
func (u *UsageLogUpsertBulk) SetAccountRateMultiplier(v float64) *UsageLogUpsertBulk {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
@@ -3722,6 +3983,76 @@ func (u *UsageLogUpsertBulk) ClearImageSizeBreakdown() *UsageLogUpsertBulk {
|
||||
})
|
||||
}
|
||||
|
||||
// SetVideoCount sets the "video_count" field.
|
||||
func (u *UsageLogUpsertBulk) SetVideoCount(v int) *UsageLogUpsertBulk {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.SetVideoCount(v)
|
||||
})
|
||||
}
|
||||
|
||||
// AddVideoCount adds v to the "video_count" field.
|
||||
func (u *UsageLogUpsertBulk) AddVideoCount(v int) *UsageLogUpsertBulk {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.AddVideoCount(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateVideoCount sets the "video_count" field to the value that was provided on create.
|
||||
func (u *UsageLogUpsertBulk) UpdateVideoCount() *UsageLogUpsertBulk {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.UpdateVideoCount()
|
||||
})
|
||||
}
|
||||
|
||||
// SetVideoResolution sets the "video_resolution" field.
|
||||
func (u *UsageLogUpsertBulk) SetVideoResolution(v string) *UsageLogUpsertBulk {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.SetVideoResolution(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateVideoResolution sets the "video_resolution" field to the value that was provided on create.
|
||||
func (u *UsageLogUpsertBulk) UpdateVideoResolution() *UsageLogUpsertBulk {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.UpdateVideoResolution()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearVideoResolution clears the value of the "video_resolution" field.
|
||||
func (u *UsageLogUpsertBulk) ClearVideoResolution() *UsageLogUpsertBulk {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.ClearVideoResolution()
|
||||
})
|
||||
}
|
||||
|
||||
// SetVideoDurationSeconds sets the "video_duration_seconds" field.
|
||||
func (u *UsageLogUpsertBulk) SetVideoDurationSeconds(v int) *UsageLogUpsertBulk {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.SetVideoDurationSeconds(v)
|
||||
})
|
||||
}
|
||||
|
||||
// AddVideoDurationSeconds adds v to the "video_duration_seconds" field.
|
||||
func (u *UsageLogUpsertBulk) AddVideoDurationSeconds(v int) *UsageLogUpsertBulk {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.AddVideoDurationSeconds(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateVideoDurationSeconds sets the "video_duration_seconds" field to the value that was provided on create.
|
||||
func (u *UsageLogUpsertBulk) UpdateVideoDurationSeconds() *UsageLogUpsertBulk {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.UpdateVideoDurationSeconds()
|
||||
})
|
||||
}
|
||||
|
||||
// ClearVideoDurationSeconds clears the value of the "video_duration_seconds" field.
|
||||
func (u *UsageLogUpsertBulk) ClearVideoDurationSeconds() *UsageLogUpsertBulk {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
s.ClearVideoDurationSeconds()
|
||||
})
|
||||
}
|
||||
|
||||
// SetCacheTTLOverridden sets the "cache_ttl_overridden" field.
|
||||
func (u *UsageLogUpsertBulk) SetCacheTTLOverridden(v bool) *UsageLogUpsertBulk {
|
||||
return u.Update(func(s *UsageLogUpsert) {
|
||||
|
||||
@@ -542,6 +542,20 @@ func (_u *UsageLogUpdate) AddRateMultiplier(v float64) *UsageLogUpdate {
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetLongContextBillingApplied sets the "long_context_billing_applied" field.
|
||||
func (_u *UsageLogUpdate) SetLongContextBillingApplied(v bool) *UsageLogUpdate {
|
||||
_u.mutation.SetLongContextBillingApplied(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableLongContextBillingApplied sets the "long_context_billing_applied" field if the given value is not nil.
|
||||
func (_u *UsageLogUpdate) SetNillableLongContextBillingApplied(v *bool) *UsageLogUpdate {
|
||||
if v != nil {
|
||||
_u.SetLongContextBillingApplied(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetAccountRateMultiplier sets the "account_rate_multiplier" field.
|
||||
func (_u *UsageLogUpdate) SetAccountRateMultiplier(v float64) *UsageLogUpdate {
|
||||
_u.mutation.ResetAccountRateMultiplier()
|
||||
@@ -811,6 +825,74 @@ func (_u *UsageLogUpdate) ClearImageSizeBreakdown() *UsageLogUpdate {
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetVideoCount sets the "video_count" field.
|
||||
func (_u *UsageLogUpdate) SetVideoCount(v int) *UsageLogUpdate {
|
||||
_u.mutation.ResetVideoCount()
|
||||
_u.mutation.SetVideoCount(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableVideoCount sets the "video_count" field if the given value is not nil.
|
||||
func (_u *UsageLogUpdate) SetNillableVideoCount(v *int) *UsageLogUpdate {
|
||||
if v != nil {
|
||||
_u.SetVideoCount(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddVideoCount adds value to the "video_count" field.
|
||||
func (_u *UsageLogUpdate) AddVideoCount(v int) *UsageLogUpdate {
|
||||
_u.mutation.AddVideoCount(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetVideoResolution sets the "video_resolution" field.
|
||||
func (_u *UsageLogUpdate) SetVideoResolution(v string) *UsageLogUpdate {
|
||||
_u.mutation.SetVideoResolution(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableVideoResolution sets the "video_resolution" field if the given value is not nil.
|
||||
func (_u *UsageLogUpdate) SetNillableVideoResolution(v *string) *UsageLogUpdate {
|
||||
if v != nil {
|
||||
_u.SetVideoResolution(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearVideoResolution clears the value of the "video_resolution" field.
|
||||
func (_u *UsageLogUpdate) ClearVideoResolution() *UsageLogUpdate {
|
||||
_u.mutation.ClearVideoResolution()
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetVideoDurationSeconds sets the "video_duration_seconds" field.
|
||||
func (_u *UsageLogUpdate) SetVideoDurationSeconds(v int) *UsageLogUpdate {
|
||||
_u.mutation.ResetVideoDurationSeconds()
|
||||
_u.mutation.SetVideoDurationSeconds(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableVideoDurationSeconds sets the "video_duration_seconds" field if the given value is not nil.
|
||||
func (_u *UsageLogUpdate) SetNillableVideoDurationSeconds(v *int) *UsageLogUpdate {
|
||||
if v != nil {
|
||||
_u.SetVideoDurationSeconds(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddVideoDurationSeconds adds value to the "video_duration_seconds" field.
|
||||
func (_u *UsageLogUpdate) AddVideoDurationSeconds(v int) *UsageLogUpdate {
|
||||
_u.mutation.AddVideoDurationSeconds(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearVideoDurationSeconds clears the value of the "video_duration_seconds" field.
|
||||
func (_u *UsageLogUpdate) ClearVideoDurationSeconds() *UsageLogUpdate {
|
||||
_u.mutation.ClearVideoDurationSeconds()
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetCacheTTLOverridden sets the "cache_ttl_overridden" field.
|
||||
func (_u *UsageLogUpdate) SetCacheTTLOverridden(v bool) *UsageLogUpdate {
|
||||
_u.mutation.SetCacheTTLOverridden(v)
|
||||
@@ -979,6 +1061,11 @@ func (_u *UsageLogUpdate) check() error {
|
||||
return &ValidationError{Name: "image_size_source", err: fmt.Errorf(`ent: validator failed for field "UsageLog.image_size_source": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := _u.mutation.VideoResolution(); ok {
|
||||
if err := usagelog.VideoResolutionValidator(v); err != nil {
|
||||
return &ValidationError{Name: "video_resolution", err: fmt.Errorf(`ent: validator failed for field "UsageLog.video_resolution": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _u.mutation.UserCleared() && len(_u.mutation.UserIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "UsageLog.user"`)
|
||||
}
|
||||
@@ -1126,6 +1213,9 @@ func (_u *UsageLogUpdate) sqlSave(ctx context.Context) (_node int, err error) {
|
||||
if value, ok := _u.mutation.AddedRateMultiplier(); ok {
|
||||
_spec.AddField(usagelog.FieldRateMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.LongContextBillingApplied(); ok {
|
||||
_spec.SetField(usagelog.FieldLongContextBillingApplied, field.TypeBool, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AccountRateMultiplier(); ok {
|
||||
_spec.SetField(usagelog.FieldAccountRateMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
@@ -1210,6 +1300,27 @@ func (_u *UsageLogUpdate) sqlSave(ctx context.Context) (_node int, err error) {
|
||||
if _u.mutation.ImageSizeBreakdownCleared() {
|
||||
_spec.ClearField(usagelog.FieldImageSizeBreakdown, field.TypeJSON)
|
||||
}
|
||||
if value, ok := _u.mutation.VideoCount(); ok {
|
||||
_spec.SetField(usagelog.FieldVideoCount, field.TypeInt, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedVideoCount(); ok {
|
||||
_spec.AddField(usagelog.FieldVideoCount, field.TypeInt, value)
|
||||
}
|
||||
if value, ok := _u.mutation.VideoResolution(); ok {
|
||||
_spec.SetField(usagelog.FieldVideoResolution, field.TypeString, value)
|
||||
}
|
||||
if _u.mutation.VideoResolutionCleared() {
|
||||
_spec.ClearField(usagelog.FieldVideoResolution, field.TypeString)
|
||||
}
|
||||
if value, ok := _u.mutation.VideoDurationSeconds(); ok {
|
||||
_spec.SetField(usagelog.FieldVideoDurationSeconds, field.TypeInt, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedVideoDurationSeconds(); ok {
|
||||
_spec.AddField(usagelog.FieldVideoDurationSeconds, field.TypeInt, value)
|
||||
}
|
||||
if _u.mutation.VideoDurationSecondsCleared() {
|
||||
_spec.ClearField(usagelog.FieldVideoDurationSeconds, field.TypeInt)
|
||||
}
|
||||
if value, ok := _u.mutation.CacheTTLOverridden(); ok {
|
||||
_spec.SetField(usagelog.FieldCacheTTLOverridden, field.TypeBool, value)
|
||||
}
|
||||
@@ -1888,6 +1999,20 @@ func (_u *UsageLogUpdateOne) AddRateMultiplier(v float64) *UsageLogUpdateOne {
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetLongContextBillingApplied sets the "long_context_billing_applied" field.
|
||||
func (_u *UsageLogUpdateOne) SetLongContextBillingApplied(v bool) *UsageLogUpdateOne {
|
||||
_u.mutation.SetLongContextBillingApplied(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableLongContextBillingApplied sets the "long_context_billing_applied" field if the given value is not nil.
|
||||
func (_u *UsageLogUpdateOne) SetNillableLongContextBillingApplied(v *bool) *UsageLogUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetLongContextBillingApplied(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetAccountRateMultiplier sets the "account_rate_multiplier" field.
|
||||
func (_u *UsageLogUpdateOne) SetAccountRateMultiplier(v float64) *UsageLogUpdateOne {
|
||||
_u.mutation.ResetAccountRateMultiplier()
|
||||
@@ -2157,6 +2282,74 @@ func (_u *UsageLogUpdateOne) ClearImageSizeBreakdown() *UsageLogUpdateOne {
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetVideoCount sets the "video_count" field.
|
||||
func (_u *UsageLogUpdateOne) SetVideoCount(v int) *UsageLogUpdateOne {
|
||||
_u.mutation.ResetVideoCount()
|
||||
_u.mutation.SetVideoCount(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableVideoCount sets the "video_count" field if the given value is not nil.
|
||||
func (_u *UsageLogUpdateOne) SetNillableVideoCount(v *int) *UsageLogUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetVideoCount(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddVideoCount adds value to the "video_count" field.
|
||||
func (_u *UsageLogUpdateOne) AddVideoCount(v int) *UsageLogUpdateOne {
|
||||
_u.mutation.AddVideoCount(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetVideoResolution sets the "video_resolution" field.
|
||||
func (_u *UsageLogUpdateOne) SetVideoResolution(v string) *UsageLogUpdateOne {
|
||||
_u.mutation.SetVideoResolution(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableVideoResolution sets the "video_resolution" field if the given value is not nil.
|
||||
func (_u *UsageLogUpdateOne) SetNillableVideoResolution(v *string) *UsageLogUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetVideoResolution(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearVideoResolution clears the value of the "video_resolution" field.
|
||||
func (_u *UsageLogUpdateOne) ClearVideoResolution() *UsageLogUpdateOne {
|
||||
_u.mutation.ClearVideoResolution()
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetVideoDurationSeconds sets the "video_duration_seconds" field.
|
||||
func (_u *UsageLogUpdateOne) SetVideoDurationSeconds(v int) *UsageLogUpdateOne {
|
||||
_u.mutation.ResetVideoDurationSeconds()
|
||||
_u.mutation.SetVideoDurationSeconds(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableVideoDurationSeconds sets the "video_duration_seconds" field if the given value is not nil.
|
||||
func (_u *UsageLogUpdateOne) SetNillableVideoDurationSeconds(v *int) *UsageLogUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetVideoDurationSeconds(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddVideoDurationSeconds adds value to the "video_duration_seconds" field.
|
||||
func (_u *UsageLogUpdateOne) AddVideoDurationSeconds(v int) *UsageLogUpdateOne {
|
||||
_u.mutation.AddVideoDurationSeconds(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// ClearVideoDurationSeconds clears the value of the "video_duration_seconds" field.
|
||||
func (_u *UsageLogUpdateOne) ClearVideoDurationSeconds() *UsageLogUpdateOne {
|
||||
_u.mutation.ClearVideoDurationSeconds()
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetCacheTTLOverridden sets the "cache_ttl_overridden" field.
|
||||
func (_u *UsageLogUpdateOne) SetCacheTTLOverridden(v bool) *UsageLogUpdateOne {
|
||||
_u.mutation.SetCacheTTLOverridden(v)
|
||||
@@ -2338,6 +2531,11 @@ func (_u *UsageLogUpdateOne) check() error {
|
||||
return &ValidationError{Name: "image_size_source", err: fmt.Errorf(`ent: validator failed for field "UsageLog.image_size_source": %w`, err)}
|
||||
}
|
||||
}
|
||||
if v, ok := _u.mutation.VideoResolution(); ok {
|
||||
if err := usagelog.VideoResolutionValidator(v); err != nil {
|
||||
return &ValidationError{Name: "video_resolution", err: fmt.Errorf(`ent: validator failed for field "UsageLog.video_resolution": %w`, err)}
|
||||
}
|
||||
}
|
||||
if _u.mutation.UserCleared() && len(_u.mutation.UserIDs()) > 0 {
|
||||
return errors.New(`ent: clearing a required unique edge "UsageLog.user"`)
|
||||
}
|
||||
@@ -2502,6 +2700,9 @@ func (_u *UsageLogUpdateOne) sqlSave(ctx context.Context) (_node *UsageLog, err
|
||||
if value, ok := _u.mutation.AddedRateMultiplier(); ok {
|
||||
_spec.AddField(usagelog.FieldRateMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.LongContextBillingApplied(); ok {
|
||||
_spec.SetField(usagelog.FieldLongContextBillingApplied, field.TypeBool, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AccountRateMultiplier(); ok {
|
||||
_spec.SetField(usagelog.FieldAccountRateMultiplier, field.TypeFloat64, value)
|
||||
}
|
||||
@@ -2586,6 +2787,27 @@ func (_u *UsageLogUpdateOne) sqlSave(ctx context.Context) (_node *UsageLog, err
|
||||
if _u.mutation.ImageSizeBreakdownCleared() {
|
||||
_spec.ClearField(usagelog.FieldImageSizeBreakdown, field.TypeJSON)
|
||||
}
|
||||
if value, ok := _u.mutation.VideoCount(); ok {
|
||||
_spec.SetField(usagelog.FieldVideoCount, field.TypeInt, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedVideoCount(); ok {
|
||||
_spec.AddField(usagelog.FieldVideoCount, field.TypeInt, value)
|
||||
}
|
||||
if value, ok := _u.mutation.VideoResolution(); ok {
|
||||
_spec.SetField(usagelog.FieldVideoResolution, field.TypeString, value)
|
||||
}
|
||||
if _u.mutation.VideoResolutionCleared() {
|
||||
_spec.ClearField(usagelog.FieldVideoResolution, field.TypeString)
|
||||
}
|
||||
if value, ok := _u.mutation.VideoDurationSeconds(); ok {
|
||||
_spec.SetField(usagelog.FieldVideoDurationSeconds, field.TypeInt, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedVideoDurationSeconds(); ok {
|
||||
_spec.AddField(usagelog.FieldVideoDurationSeconds, field.TypeInt, value)
|
||||
}
|
||||
if _u.mutation.VideoDurationSecondsCleared() {
|
||||
_spec.ClearField(usagelog.FieldVideoDurationSeconds, field.TypeInt)
|
||||
}
|
||||
if value, ok := _u.mutation.CacheTTLOverridden(); ok {
|
||||
_spec.SetField(usagelog.FieldCacheTTLOverridden, field.TypeBool, value)
|
||||
}
|
||||
|
||||
+12
-1
@@ -31,6 +31,8 @@ type User struct {
|
||||
Role string `json:"role,omitempty"`
|
||||
// Balance holds the value of the "balance" field.
|
||||
Balance float64 `json:"balance,omitempty"`
|
||||
// FrozenBalance holds the value of the "frozen_balance" field.
|
||||
FrozenBalance float64 `json:"frozen_balance,omitempty"`
|
||||
// Concurrency holds the value of the "concurrency" field.
|
||||
Concurrency int `json:"concurrency,omitempty"`
|
||||
// Status holds the value of the "status" field.
|
||||
@@ -237,7 +239,7 @@ func (*User) scanValues(columns []string) ([]any, error) {
|
||||
switch columns[i] {
|
||||
case user.FieldTotpEnabled, user.FieldBalanceNotifyEnabled:
|
||||
values[i] = new(sql.NullBool)
|
||||
case user.FieldBalance, user.FieldBalanceNotifyThreshold, user.FieldTotalRecharged:
|
||||
case user.FieldBalance, user.FieldFrozenBalance, user.FieldBalanceNotifyThreshold, user.FieldTotalRecharged:
|
||||
values[i] = new(sql.NullFloat64)
|
||||
case user.FieldID, user.FieldConcurrency, user.FieldRpmLimit:
|
||||
values[i] = new(sql.NullInt64)
|
||||
@@ -309,6 +311,12 @@ func (_m *User) assignValues(columns []string, values []any) error {
|
||||
} else if value.Valid {
|
||||
_m.Balance = value.Float64
|
||||
}
|
||||
case user.FieldFrozenBalance:
|
||||
if value, ok := values[i].(*sql.NullFloat64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field frozen_balance", values[i])
|
||||
} else if value.Valid {
|
||||
_m.FrozenBalance = value.Float64
|
||||
}
|
||||
case user.FieldConcurrency:
|
||||
if value, ok := values[i].(*sql.NullInt64); !ok {
|
||||
return fmt.Errorf("unexpected type %T for field concurrency", values[i])
|
||||
@@ -539,6 +547,9 @@ func (_m *User) String() string {
|
||||
builder.WriteString("balance=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.Balance))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("frozen_balance=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.FrozenBalance))
|
||||
builder.WriteString(", ")
|
||||
builder.WriteString("concurrency=")
|
||||
builder.WriteString(fmt.Sprintf("%v", _m.Concurrency))
|
||||
builder.WriteString(", ")
|
||||
|
||||
@@ -29,6 +29,8 @@ const (
|
||||
FieldRole = "role"
|
||||
// FieldBalance holds the string denoting the balance field in the database.
|
||||
FieldBalance = "balance"
|
||||
// FieldFrozenBalance holds the string denoting the frozen_balance field in the database.
|
||||
FieldFrozenBalance = "frozen_balance"
|
||||
// FieldConcurrency holds the string denoting the concurrency field in the database.
|
||||
FieldConcurrency = "concurrency"
|
||||
// FieldStatus holds the string denoting the status field in the database.
|
||||
@@ -199,6 +201,7 @@ var Columns = []string{
|
||||
FieldPasswordHash,
|
||||
FieldRole,
|
||||
FieldBalance,
|
||||
FieldFrozenBalance,
|
||||
FieldConcurrency,
|
||||
FieldStatus,
|
||||
FieldUsername,
|
||||
@@ -257,6 +260,8 @@ var (
|
||||
RoleValidator func(string) error
|
||||
// DefaultBalance holds the default value on creation for the "balance" field.
|
||||
DefaultBalance float64
|
||||
// DefaultFrozenBalance holds the default value on creation for the "frozen_balance" field.
|
||||
DefaultFrozenBalance float64
|
||||
// DefaultConcurrency holds the default value on creation for the "concurrency" field.
|
||||
DefaultConcurrency int
|
||||
// DefaultStatus holds the default value on creation for the "status" field.
|
||||
@@ -330,6 +335,11 @@ func ByBalance(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldBalance, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByFrozenBalance orders the results by the frozen_balance field.
|
||||
func ByFrozenBalance(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldFrozenBalance, opts...).ToFunc()
|
||||
}
|
||||
|
||||
// ByConcurrency orders the results by the concurrency field.
|
||||
func ByConcurrency(opts ...sql.OrderTermOption) OrderOption {
|
||||
return sql.OrderByField(FieldConcurrency, opts...).ToFunc()
|
||||
|
||||
@@ -90,6 +90,11 @@ func Balance(v float64) predicate.User {
|
||||
return predicate.User(sql.FieldEQ(FieldBalance, v))
|
||||
}
|
||||
|
||||
// FrozenBalance applies equality check predicate on the "frozen_balance" field. It's identical to FrozenBalanceEQ.
|
||||
func FrozenBalance(v float64) predicate.User {
|
||||
return predicate.User(sql.FieldEQ(FieldFrozenBalance, v))
|
||||
}
|
||||
|
||||
// Concurrency applies equality check predicate on the "concurrency" field. It's identical to ConcurrencyEQ.
|
||||
func Concurrency(v int) predicate.User {
|
||||
return predicate.User(sql.FieldEQ(FieldConcurrency, v))
|
||||
@@ -535,6 +540,46 @@ func BalanceLTE(v float64) predicate.User {
|
||||
return predicate.User(sql.FieldLTE(FieldBalance, v))
|
||||
}
|
||||
|
||||
// FrozenBalanceEQ applies the EQ predicate on the "frozen_balance" field.
|
||||
func FrozenBalanceEQ(v float64) predicate.User {
|
||||
return predicate.User(sql.FieldEQ(FieldFrozenBalance, v))
|
||||
}
|
||||
|
||||
// FrozenBalanceNEQ applies the NEQ predicate on the "frozen_balance" field.
|
||||
func FrozenBalanceNEQ(v float64) predicate.User {
|
||||
return predicate.User(sql.FieldNEQ(FieldFrozenBalance, v))
|
||||
}
|
||||
|
||||
// FrozenBalanceIn applies the In predicate on the "frozen_balance" field.
|
||||
func FrozenBalanceIn(vs ...float64) predicate.User {
|
||||
return predicate.User(sql.FieldIn(FieldFrozenBalance, vs...))
|
||||
}
|
||||
|
||||
// FrozenBalanceNotIn applies the NotIn predicate on the "frozen_balance" field.
|
||||
func FrozenBalanceNotIn(vs ...float64) predicate.User {
|
||||
return predicate.User(sql.FieldNotIn(FieldFrozenBalance, vs...))
|
||||
}
|
||||
|
||||
// FrozenBalanceGT applies the GT predicate on the "frozen_balance" field.
|
||||
func FrozenBalanceGT(v float64) predicate.User {
|
||||
return predicate.User(sql.FieldGT(FieldFrozenBalance, v))
|
||||
}
|
||||
|
||||
// FrozenBalanceGTE applies the GTE predicate on the "frozen_balance" field.
|
||||
func FrozenBalanceGTE(v float64) predicate.User {
|
||||
return predicate.User(sql.FieldGTE(FieldFrozenBalance, v))
|
||||
}
|
||||
|
||||
// FrozenBalanceLT applies the LT predicate on the "frozen_balance" field.
|
||||
func FrozenBalanceLT(v float64) predicate.User {
|
||||
return predicate.User(sql.FieldLT(FieldFrozenBalance, v))
|
||||
}
|
||||
|
||||
// FrozenBalanceLTE applies the LTE predicate on the "frozen_balance" field.
|
||||
func FrozenBalanceLTE(v float64) predicate.User {
|
||||
return predicate.User(sql.FieldLTE(FieldFrozenBalance, v))
|
||||
}
|
||||
|
||||
// ConcurrencyEQ applies the EQ predicate on the "concurrency" field.
|
||||
func ConcurrencyEQ(v int) predicate.User {
|
||||
return predicate.User(sql.FieldEQ(FieldConcurrency, v))
|
||||
|
||||
@@ -116,6 +116,20 @@ func (_c *UserCreate) SetNillableBalance(v *float64) *UserCreate {
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetFrozenBalance sets the "frozen_balance" field.
|
||||
func (_c *UserCreate) SetFrozenBalance(v float64) *UserCreate {
|
||||
_c.mutation.SetFrozenBalance(v)
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetNillableFrozenBalance sets the "frozen_balance" field if the given value is not nil.
|
||||
func (_c *UserCreate) SetNillableFrozenBalance(v *float64) *UserCreate {
|
||||
if v != nil {
|
||||
_c.SetFrozenBalance(*v)
|
||||
}
|
||||
return _c
|
||||
}
|
||||
|
||||
// SetConcurrency sets the "concurrency" field.
|
||||
func (_c *UserCreate) SetConcurrency(v int) *UserCreate {
|
||||
_c.mutation.SetConcurrency(v)
|
||||
@@ -594,6 +608,10 @@ func (_c *UserCreate) defaults() error {
|
||||
v := user.DefaultBalance
|
||||
_c.mutation.SetBalance(v)
|
||||
}
|
||||
if _, ok := _c.mutation.FrozenBalance(); !ok {
|
||||
v := user.DefaultFrozenBalance
|
||||
_c.mutation.SetFrozenBalance(v)
|
||||
}
|
||||
if _, ok := _c.mutation.Concurrency(); !ok {
|
||||
v := user.DefaultConcurrency
|
||||
_c.mutation.SetConcurrency(v)
|
||||
@@ -676,6 +694,9 @@ func (_c *UserCreate) check() error {
|
||||
if _, ok := _c.mutation.Balance(); !ok {
|
||||
return &ValidationError{Name: "balance", err: errors.New(`ent: missing required field "User.balance"`)}
|
||||
}
|
||||
if _, ok := _c.mutation.FrozenBalance(); !ok {
|
||||
return &ValidationError{Name: "frozen_balance", err: errors.New(`ent: missing required field "User.frozen_balance"`)}
|
||||
}
|
||||
if _, ok := _c.mutation.Concurrency(); !ok {
|
||||
return &ValidationError{Name: "concurrency", err: errors.New(`ent: missing required field "User.concurrency"`)}
|
||||
}
|
||||
@@ -779,6 +800,10 @@ func (_c *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) {
|
||||
_spec.SetField(user.FieldBalance, field.TypeFloat64, value)
|
||||
_node.Balance = value
|
||||
}
|
||||
if value, ok := _c.mutation.FrozenBalance(); ok {
|
||||
_spec.SetField(user.FieldFrozenBalance, field.TypeFloat64, value)
|
||||
_node.FrozenBalance = value
|
||||
}
|
||||
if value, ok := _c.mutation.Concurrency(); ok {
|
||||
_spec.SetField(user.FieldConcurrency, field.TypeInt, value)
|
||||
_node.Concurrency = value
|
||||
@@ -1191,6 +1216,24 @@ func (u *UserUpsert) AddBalance(v float64) *UserUpsert {
|
||||
return u
|
||||
}
|
||||
|
||||
// SetFrozenBalance sets the "frozen_balance" field.
|
||||
func (u *UserUpsert) SetFrozenBalance(v float64) *UserUpsert {
|
||||
u.Set(user.FieldFrozenBalance, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// UpdateFrozenBalance sets the "frozen_balance" field to the value that was provided on create.
|
||||
func (u *UserUpsert) UpdateFrozenBalance() *UserUpsert {
|
||||
u.SetExcluded(user.FieldFrozenBalance)
|
||||
return u
|
||||
}
|
||||
|
||||
// AddFrozenBalance adds v to the "frozen_balance" field.
|
||||
func (u *UserUpsert) AddFrozenBalance(v float64) *UserUpsert {
|
||||
u.Add(user.FieldFrozenBalance, v)
|
||||
return u
|
||||
}
|
||||
|
||||
// SetConcurrency sets the "concurrency" field.
|
||||
func (u *UserUpsert) SetConcurrency(v int) *UserUpsert {
|
||||
u.Set(user.FieldConcurrency, v)
|
||||
@@ -1580,6 +1623,27 @@ func (u *UserUpsertOne) UpdateBalance() *UserUpsertOne {
|
||||
})
|
||||
}
|
||||
|
||||
// SetFrozenBalance sets the "frozen_balance" field.
|
||||
func (u *UserUpsertOne) SetFrozenBalance(v float64) *UserUpsertOne {
|
||||
return u.Update(func(s *UserUpsert) {
|
||||
s.SetFrozenBalance(v)
|
||||
})
|
||||
}
|
||||
|
||||
// AddFrozenBalance adds v to the "frozen_balance" field.
|
||||
func (u *UserUpsertOne) AddFrozenBalance(v float64) *UserUpsertOne {
|
||||
return u.Update(func(s *UserUpsert) {
|
||||
s.AddFrozenBalance(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateFrozenBalance sets the "frozen_balance" field to the value that was provided on create.
|
||||
func (u *UserUpsertOne) UpdateFrozenBalance() *UserUpsertOne {
|
||||
return u.Update(func(s *UserUpsert) {
|
||||
s.UpdateFrozenBalance()
|
||||
})
|
||||
}
|
||||
|
||||
// SetConcurrency sets the "concurrency" field.
|
||||
func (u *UserUpsertOne) SetConcurrency(v int) *UserUpsertOne {
|
||||
return u.Update(func(s *UserUpsert) {
|
||||
@@ -2176,6 +2240,27 @@ func (u *UserUpsertBulk) UpdateBalance() *UserUpsertBulk {
|
||||
})
|
||||
}
|
||||
|
||||
// SetFrozenBalance sets the "frozen_balance" field.
|
||||
func (u *UserUpsertBulk) SetFrozenBalance(v float64) *UserUpsertBulk {
|
||||
return u.Update(func(s *UserUpsert) {
|
||||
s.SetFrozenBalance(v)
|
||||
})
|
||||
}
|
||||
|
||||
// AddFrozenBalance adds v to the "frozen_balance" field.
|
||||
func (u *UserUpsertBulk) AddFrozenBalance(v float64) *UserUpsertBulk {
|
||||
return u.Update(func(s *UserUpsert) {
|
||||
s.AddFrozenBalance(v)
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateFrozenBalance sets the "frozen_balance" field to the value that was provided on create.
|
||||
func (u *UserUpsertBulk) UpdateFrozenBalance() *UserUpsertBulk {
|
||||
return u.Update(func(s *UserUpsert) {
|
||||
s.UpdateFrozenBalance()
|
||||
})
|
||||
}
|
||||
|
||||
// SetConcurrency sets the "concurrency" field.
|
||||
func (u *UserUpsertBulk) SetConcurrency(v int) *UserUpsertBulk {
|
||||
return u.Update(func(s *UserUpsert) {
|
||||
|
||||
@@ -129,6 +129,27 @@ func (_u *UserUpdate) AddBalance(v float64) *UserUpdate {
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetFrozenBalance sets the "frozen_balance" field.
|
||||
func (_u *UserUpdate) SetFrozenBalance(v float64) *UserUpdate {
|
||||
_u.mutation.ResetFrozenBalance()
|
||||
_u.mutation.SetFrozenBalance(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableFrozenBalance sets the "frozen_balance" field if the given value is not nil.
|
||||
func (_u *UserUpdate) SetNillableFrozenBalance(v *float64) *UserUpdate {
|
||||
if v != nil {
|
||||
_u.SetFrozenBalance(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddFrozenBalance adds value to the "frozen_balance" field.
|
||||
func (_u *UserUpdate) AddFrozenBalance(v float64) *UserUpdate {
|
||||
_u.mutation.AddFrozenBalance(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetConcurrency sets the "concurrency" field.
|
||||
func (_u *UserUpdate) SetConcurrency(v int) *UserUpdate {
|
||||
_u.mutation.ResetConcurrency()
|
||||
@@ -997,6 +1018,12 @@ func (_u *UserUpdate) sqlSave(ctx context.Context) (_node int, err error) {
|
||||
if value, ok := _u.mutation.AddedBalance(); ok {
|
||||
_spec.AddField(user.FieldBalance, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.FrozenBalance(); ok {
|
||||
_spec.SetField(user.FieldFrozenBalance, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedFrozenBalance(); ok {
|
||||
_spec.AddField(user.FieldFrozenBalance, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.Concurrency(); ok {
|
||||
_spec.SetField(user.FieldConcurrency, field.TypeInt, value)
|
||||
}
|
||||
@@ -1778,6 +1805,27 @@ func (_u *UserUpdateOne) AddBalance(v float64) *UserUpdateOne {
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetFrozenBalance sets the "frozen_balance" field.
|
||||
func (_u *UserUpdateOne) SetFrozenBalance(v float64) *UserUpdateOne {
|
||||
_u.mutation.ResetFrozenBalance()
|
||||
_u.mutation.SetFrozenBalance(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetNillableFrozenBalance sets the "frozen_balance" field if the given value is not nil.
|
||||
func (_u *UserUpdateOne) SetNillableFrozenBalance(v *float64) *UserUpdateOne {
|
||||
if v != nil {
|
||||
_u.SetFrozenBalance(*v)
|
||||
}
|
||||
return _u
|
||||
}
|
||||
|
||||
// AddFrozenBalance adds value to the "frozen_balance" field.
|
||||
func (_u *UserUpdateOne) AddFrozenBalance(v float64) *UserUpdateOne {
|
||||
_u.mutation.AddFrozenBalance(v)
|
||||
return _u
|
||||
}
|
||||
|
||||
// SetConcurrency sets the "concurrency" field.
|
||||
func (_u *UserUpdateOne) SetConcurrency(v int) *UserUpdateOne {
|
||||
_u.mutation.ResetConcurrency()
|
||||
@@ -2676,6 +2724,12 @@ func (_u *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error) {
|
||||
if value, ok := _u.mutation.AddedBalance(); ok {
|
||||
_spec.AddField(user.FieldBalance, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.FrozenBalance(); ok {
|
||||
_spec.SetField(user.FieldFrozenBalance, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.AddedFrozenBalance(); ok {
|
||||
_spec.AddField(user.FieldFrozenBalance, field.TypeFloat64, value)
|
||||
}
|
||||
if value, ok := _u.mutation.Concurrency(); ok {
|
||||
_spec.SetField(user.FieldConcurrency, field.TypeInt, value)
|
||||
}
|
||||
|
||||
+15
-13
@@ -1,6 +1,6 @@
|
||||
module github.com/Wei-Shaw/sub2api
|
||||
|
||||
go 1.26.4
|
||||
go 1.26.5
|
||||
|
||||
require (
|
||||
entgo.io/ent v0.14.5
|
||||
@@ -8,11 +8,10 @@ require (
|
||||
github.com/alicebob/miniredis/v2 v2.38.0
|
||||
github.com/alitto/pond/v2 v2.6.2
|
||||
github.com/andybalholm/brotli v1.2.0
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.3
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.5
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.10
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.10
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.96.2
|
||||
github.com/aws/smithy-go v1.24.2
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3
|
||||
github.com/cespare/xxhash/v2 v2.3.0
|
||||
github.com/coder/websocket v1.8.14
|
||||
github.com/dgraph-io/ristretto v0.2.0
|
||||
@@ -39,11 +38,13 @@ require (
|
||||
github.com/testcontainers/testcontainers-go/modules/redis v0.40.0
|
||||
github.com/tidwall/gjson v1.18.0
|
||||
github.com/tidwall/sjson v1.2.5
|
||||
github.com/tiktoken-go/tokenizer v0.8.0
|
||||
github.com/wechatpay-apiv3/wechatpay-go v0.2.21
|
||||
github.com/zeromicro/go-zero v1.9.4
|
||||
go.uber.org/zap v1.24.0
|
||||
golang.org/x/crypto v0.51.0
|
||||
golang.org/x/image v0.39.0
|
||||
golang.org/x/mod v0.35.0
|
||||
golang.org/x/net v0.55.0
|
||||
golang.org/x/sync v0.20.0
|
||||
golang.org/x/term v0.43.0
|
||||
@@ -59,20 +60,21 @@ require (
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.18 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.18 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.10 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.18 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.15 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.7 // indirect
|
||||
github.com/aws/smithy-go v1.24.2 // indirect
|
||||
github.com/bmatcuk/doublestar v1.3.4 // indirect
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
||||
github.com/bytedance/sonic v1.9.1 // indirect
|
||||
@@ -86,6 +88,7 @@ require (
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/dlclark/regexp2/v2 v2.1.0 // indirect
|
||||
github.com/docker/docker v28.5.1+incompatible // indirect
|
||||
github.com/docker/go-connections v0.6.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
@@ -174,7 +177,6 @@ require (
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect
|
||||
golang.org/x/mod v0.35.0 // indirect
|
||||
golang.org/x/sys v0.45.0 // indirect
|
||||
golang.org/x/text v0.37.0 // indirect
|
||||
golang.org/x/tools v0.44.0 // indirect
|
||||
|
||||
+24
-36
@@ -24,34 +24,34 @@ github.com/andybalholm/brotli v1.2.0 h1:ukwgCxwYrmACq68yiUqwIWnGY0cTPox/M94sVwTo
|
||||
github.com/andybalholm/brotli v1.2.0/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.3 h1:4kQ/fa22KjDt13QCy1+bYADvdgcxpfH18f0zP542kZA=
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.3/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.5 h1:zWFmPmgw4sveAYi1mRqG+E/g0461cJ5M4bJ8/nc6d3Q=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.5/go.mod h1:nVUlMLVV8ycXSb7mSkcNu9e3v/1TJq2RTlrPwhYWr5c=
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.5 h1:dj5kopbwUsVUVFgO4Fi5BIT3t4WyqIDjGKCangnV/yY=
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.5/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 h1:eBMB84YGghSocM7PsjmmPffTa+1FBUeNvGvFou6V/4o=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8/go.mod h1:lyw7GFp3qENLh7kwzf7iMzAxDn+NzjXEAGjKS2UOKqI=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.10 h1:9DMthfO6XWZYLfzZglAgW5Fyou2nRI5CuV44sTedKBI=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.10/go.mod h1:2rUIOnA2JaiqYmSKYmRJlcMWy6qTj1vuRFscppSBMcw=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.10 h1:EEhmEUFCE1Yhl7vDhNOI5OCL/iKMdkkYFTRpZXNw7m8=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.10/go.mod h1:RnnlFCAlxQCkN2Q379B67USkBMu1PipEEiibzYN5UTE=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.18 h1:Ii4s+Sq3yDfaMLpjrJsqD6SmG/Wq/P5L/hw2qa78UAY=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.18/go.mod h1:6x81qnY++ovptLE6nWQeWrpXxbnlIex+4H4eYYGcqfc=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18 h1:F43zk1vemYIqPAwhjTjYIz0irU2EY7sOb/F5eJ3HuyM=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.18/go.mod h1:w1jdlZXrGKaJcNoL+Nnrj+k5wlpGXqnNrKoP22HvAug=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18 h1:xCeWVjj0ki0l3nruoyP2slHsGArMxeiiaoPN5QZH6YQ=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.18/go.mod h1:r/eLGuGCBw6l36ZRWiw6PaZwPXb6YOj+i/7MizNl5/k=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 h1:Rgg6wvjjtX8bNHcvi9OnXWwcE0a2vGpbwmtICOsvcf4=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21/go.mod h1:A/kJFst/nm//cyqonihbdpQZwiUhhzpqTsdbhDdRF9c=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 h1:PEgGVtPoB6NTpPrBgqSE5hE/o47Ij9qk/SEZFbUOe9A=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21/go.mod h1:p+hz+PRAYlY3zcpJhPwXlLC4C+kqn70WIHwnzAfs6ps=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.18 h1:eZioDaZGJ0tMM4gzmkNIO2aAoQd+je7Ug7TkvAzlmkU=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.18/go.mod h1:CCXwUKAJdoWr6/NcxZ+zsiPr6oH/Q5aTooRGYieAyj4=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5 h1:CeY9LUdur+Dxoeldqoun6y4WtJ3RQtzk0JMP2gfUay0=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.5/go.mod h1:AZLZf2fMaahW5s/wMRciu1sYbdsikT/UHwbUjOdEVTc=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.10 h1:fJvQ5mIBVfKtiyx0AHY6HeWcRX5LGANLpq8SVR+Uazs=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.10/go.mod h1:Kzm5e6OmNH8VMkgK9t+ry5jEih4Y8whqs+1hrkxim1I=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18 h1:LTRCYFlnnKFlKsyIQxKhJuDuA3ZkrDQMRYm6rXiHlLY=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.18/go.mod h1:XhwkgGG6bHSd00nO/mexWTcTjgd6PjuvWQMqSn2UaEk=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.18 h1:/A/xDuZAVD2BpsS2fftFRo/NoEKQJ8YTnJDEHBy2Gtg=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.18/go.mod h1:hWe9b4f+djUQGmyiGEeOnZv69dtMSgpDRIvNMvuvzvY=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.96.2 h1:M1A9AjcFwlxTLuf0Faj88L8Iqw0n/AJHjpZTQzMMsSc=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.96.2/go.mod h1:KsdTV6Q9WKUZm2mNJnUFmIoXfZux91M3sr/a4REX8e0=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 h1:rWyie/PxDRIdhNf4DzRk0lvjVOqFJuNnO8WwaIRVxzQ=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22/go.mod h1:zd/JsJ4P7oGfUhXn1VyLqaRZwPmZwg44Jf2dS84Dm3Y=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 h1:JRaIgADQS/U6uXDqlPiefP32yXTda7Kqfx+LgspooZM=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13/go.mod h1:CEuVn5WqOMilYl+tbccq8+N2ieCy0gVn3OtRb0vBNNM=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 h1:c31//R3xgIJMSC8S6hEVq+38DcvUlgFY0FM6mSI5oto=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21/go.mod h1:r6+pf23ouCB718FUxaqzZdbpYFyDtehyZcmP5KL9FkA=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 h1:ZlvrNcHSFFWURB8avufQq9gFsheUgjVD9536obIknfM=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21/go.mod h1:cv3TNhVrssKR0O/xxLJVRfd2oazSnZnkUeTf6ctUwfQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3 h1:HwxWTbTrIHm5qY+CAEur0s/figc3qwvLWsNkF4RPToo=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3/go.mod h1:uoA43SdFwacedBfSgfFSjjCvYe8aYBS7EnU5GZ/YKMM=
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.6 h1:MzORe+J94I+hYu2a6XmV5yC9huoTv8NRcCrUNedDypQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.6/go.mod h1:hXzcHLARD7GeWnifd8j9RWqtfIgxj4/cAtIVIK7hg8g=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.11 h1:7oGD8KPfBOJGXiCoRKrrrQkbvCp8N++u36hrLMPey6o=
|
||||
@@ -108,6 +108,8 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/dlclark/regexp2/v2 v2.1.0 h1:jHXRmHRZGbuQzDZjMlCAXOvQb75iv3HyLDzXGj5H1AY=
|
||||
github.com/dlclark/regexp2/v2 v2.1.0/go.mod h1:Bz5TMy5d8fPK0ximH0Yi9KvsRHNnvXqUx9XG6a4wB+I=
|
||||
github.com/docker/docker v28.5.1+incompatible h1:Bm8DchhSD2J6PsFzxC35TZo4TLGR2PdW/E69rU45NhM=
|
||||
github.com/docker/docker v28.5.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94=
|
||||
@@ -164,8 +166,6 @@ github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
|
||||
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
||||
github.com/google/subcommands v1.2.0 h1:vWQspBTo2nEqTUFita5/KeEWlUL8kQObDFbub/EN9oE=
|
||||
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/wire v0.7.0 h1:JxUKI6+CVBgCO2WToKy/nQk0sS+amI9z9EjVmdaocj4=
|
||||
@@ -360,6 +360,8 @@ github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||
github.com/tiktoken-go/tokenizer v0.8.0 h1:drHWno2Zx3eAm/hk/LmvBKXPpSImB7BRyh/ru4+3Q7Y=
|
||||
github.com/tiktoken-go/tokenizer v0.8.0/go.mod h1:pTmPz4r14MV3JkUGAmAcdLdYhSxN68MCjrP+EoxBdx0=
|
||||
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
|
||||
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
|
||||
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
|
||||
@@ -415,20 +417,14 @@ go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
|
||||
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
|
||||
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
|
||||
golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI=
|
||||
golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8=
|
||||
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 h1:mgKeJMpvi0yx/sU5GsxQ7p6s2wtOnGAHZWCHUM4KGzY=
|
||||
golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546/go.mod h1:j/pmGrbnkbPtQfxEe5D0VQhZC6qKbfKifgD0oM7sR70=
|
||||
golang.org/x/image v0.39.0 h1:skVYidAEVKgn8lZ602XO75asgXBgLj9G/FE3RbuPFww=
|
||||
golang.org/x/image v0.39.0/go.mod h1:sIbmppfU+xFLPIG0FoVUTvyBMmgng1/XAMhQ2ft0hpA=
|
||||
golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI=
|
||||
golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY=
|
||||
golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM=
|
||||
golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU=
|
||||
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
|
||||
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
|
||||
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
|
||||
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
|
||||
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||
@@ -442,22 +438,14 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
|
||||
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
|
||||
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
|
||||
golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY=
|
||||
golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4=
|
||||
golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk=
|
||||
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
|
||||
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
|
||||
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
|
||||
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
|
||||
golang.org/x/time v0.12.0 h1:ScB/8o8olJvc+CQPWrK3fPZNfh7qgwCrY0zJmoEQLSE=
|
||||
golang.org/x/time v0.12.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s=
|
||||
golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0=
|
||||
golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c=
|
||||
golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
||||
@@ -29,7 +29,7 @@ const (
|
||||
|
||||
// DefaultCSPPolicy is the default Content-Security-Policy with nonce support
|
||||
// __CSP_NONCE__ will be replaced with actual nonce at request time by the SecurityHeaders middleware
|
||||
const DefaultCSPPolicy = "default-src 'self'; script-src 'self' __CSP_NONCE__ https://challenges.cloudflare.com https://static.cloudflareinsights.com https://*.stripe.com https://static.airwallex.com https://checkout.airwallex.com https://static-demo.airwallex.com https://checkout-demo.airwallex.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://static.airwallex.com https://checkout.airwallex.com https://static-demo.airwallex.com https://checkout-demo.airwallex.com; img-src 'self' data: https:; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self' https:; frame-src https://challenges.cloudflare.com https://*.stripe.com https://checkout.airwallex.com https://checkout-demo.airwallex.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'"
|
||||
const DefaultCSPPolicy = "default-src 'self'; script-src 'self' __CSP_NONCE__ https://challenges.cloudflare.com https://static.cloudflareinsights.com https://*.stripe.com https://static.airwallex.com https://checkout.airwallex.com https://static-demo.airwallex.com https://checkout-demo.airwallex.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://static.airwallex.com https://checkout.airwallex.com https://static-demo.airwallex.com https://checkout-demo.airwallex.com; img-src 'self' data: blob: https:; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self' https:; frame-src https://challenges.cloudflare.com https://*.stripe.com https://checkout.airwallex.com https://checkout-demo.airwallex.com; frame-ancestors 'none'; base-uri 'self'; form-action 'self'"
|
||||
|
||||
// UMQ(用户消息队列)模式常量
|
||||
const (
|
||||
@@ -93,6 +93,7 @@ type Config struct {
|
||||
Gemini GeminiConfig `mapstructure:"gemini"`
|
||||
Update UpdateConfig `mapstructure:"update"`
|
||||
Idempotency IdempotencyConfig `mapstructure:"idempotency"`
|
||||
BatchImage BatchImageConfig `mapstructure:"batch_image"`
|
||||
}
|
||||
|
||||
type LogConfig struct {
|
||||
@@ -175,6 +176,56 @@ type IdempotencyConfig struct {
|
||||
CleanupBatchSize int `mapstructure:"cleanup_batch_size"`
|
||||
}
|
||||
|
||||
type BatchImageConfig struct {
|
||||
Enabled bool `mapstructure:"enabled"`
|
||||
MaxItemsPerJobDefault int `mapstructure:"max_items_per_job_default"`
|
||||
MaxItemsPerJobTrial int `mapstructure:"max_items_per_job_trial"`
|
||||
MaxOutputImagesPerJob int `mapstructure:"max_output_images_per_job"`
|
||||
MaxOutputImagesPerItem int `mapstructure:"max_output_images_per_item"`
|
||||
MaxPromptCharsPerItem int `mapstructure:"max_prompt_chars_per_item"`
|
||||
MaxReferenceImagesPerJob int `mapstructure:"max_reference_images_per_job"`
|
||||
MaxReferenceInlineBytesPerJob int `mapstructure:"max_reference_inline_bytes_per_job"`
|
||||
DefaultResponseMimeType string `mapstructure:"default_response_mime_type"`
|
||||
DefaultImageSize string `mapstructure:"default_image_size"`
|
||||
MaxDownloadItemsZip int `mapstructure:"max_download_items_zip"`
|
||||
MaxDownloadBytesPerRequest int64 `mapstructure:"max_download_bytes_per_request"`
|
||||
MaxDownloadDurationSeconds int `mapstructure:"max_download_duration_seconds"`
|
||||
MaxDownloadConcurrencyPerUser int `mapstructure:"max_download_concurrency_per_user"`
|
||||
InputRetentionAfterTerminalHours int `mapstructure:"input_retention_after_terminal_hours"`
|
||||
OutputRetentionAfterTerminalHours int `mapstructure:"output_retention_after_terminal_hours"`
|
||||
OutputRetentionMaxDays int `mapstructure:"output_retention_max_days"`
|
||||
CleanupIntervalMinutes int `mapstructure:"cleanup_interval_minutes"`
|
||||
CleanupBatchSize int `mapstructure:"cleanup_batch_size"`
|
||||
QueueEnabled bool `mapstructure:"queue_enabled"`
|
||||
QueueReadyKey string `mapstructure:"queue_ready_key"`
|
||||
QueueDelayedKey string `mapstructure:"queue_delayed_key"`
|
||||
QueueActiveKey string `mapstructure:"queue_active_key"`
|
||||
InflightKeyPrefix string `mapstructure:"inflight_key_prefix"`
|
||||
LockKeyPrefix string `mapstructure:"lock_key_prefix"`
|
||||
IdempotencyKeyPrefix string `mapstructure:"idempotency_key_prefix"`
|
||||
InflightTTLSeconds int `mapstructure:"inflight_ttl_seconds"`
|
||||
JobLockTTLSeconds int `mapstructure:"job_lock_ttl_seconds"`
|
||||
DefaultRequeueDelaySeconds int `mapstructure:"default_requeue_delay_seconds"`
|
||||
ErrorRetryDelaySeconds int `mapstructure:"error_retry_delay_seconds"`
|
||||
LockConflictDelaySeconds int `mapstructure:"lock_conflict_delay_seconds"`
|
||||
StaleActiveAfterSeconds int `mapstructure:"stale_active_after_seconds"`
|
||||
DelayedMoverIntervalSeconds int `mapstructure:"delayed_mover_interval_seconds"`
|
||||
RecoveryIntervalSeconds int `mapstructure:"recovery_interval_seconds"`
|
||||
DelayedMoveLimit int `mapstructure:"delayed_move_limit"`
|
||||
RecoverLimit int `mapstructure:"recover_limit"`
|
||||
VertexEnabled bool `mapstructure:"vertex_enabled"`
|
||||
VertexProjectID string `mapstructure:"vertex_project_id"`
|
||||
VertexLocation string `mapstructure:"vertex_location"`
|
||||
// VertexManagedGCSBucket is a server-owned bucket for batch JSONL input/output.
|
||||
// Disable Cloud Storage soft delete on this bucket to avoid retaining deleted batch objects.
|
||||
VertexManagedGCSBucket string `mapstructure:"vertex_managed_gcs_bucket"`
|
||||
VertexManagedGCSPrefix string `mapstructure:"vertex_managed_gcs_prefix"`
|
||||
VertexInputRetentionHours int `mapstructure:"vertex_input_retention_hours"`
|
||||
VertexOutputRetentionHours int `mapstructure:"vertex_output_retention_hours"`
|
||||
VertexBatchPredictionBaseURL string `mapstructure:"vertex_batch_prediction_base_url"`
|
||||
VertexGCSBaseURL string `mapstructure:"vertex_gcs_base_url"`
|
||||
}
|
||||
|
||||
type LinuxDoConnectConfig struct {
|
||||
Enabled bool `mapstructure:"enabled"`
|
||||
ClientID string `mapstructure:"client_id"`
|
||||
@@ -550,6 +601,7 @@ type ServerConfig struct {
|
||||
Host string `mapstructure:"host"`
|
||||
Port int `mapstructure:"port"`
|
||||
Mode string `mapstructure:"mode"` // debug/release
|
||||
EnableServerTiming bool `mapstructure:"enable_server_timing"` // Admin UI Server-Timing response header
|
||||
FrontendURL string `mapstructure:"frontend_url"` // 前端基础 URL,用于生成邮件中的外部链接
|
||||
ReadHeaderTimeout int `mapstructure:"read_header_timeout"` // 读取请求头超时(秒)
|
||||
IdleTimeout int `mapstructure:"idle_timeout"` // 空闲连接超时(秒)
|
||||
@@ -721,6 +773,9 @@ type GatewayConfig struct {
|
||||
// OpenAIPassthroughAllowTimeoutHeaders: OpenAI 透传模式是否放行客户端超时头
|
||||
// 关闭(默认)可避免 x-stainless-timeout 等头导致上游提前断流。
|
||||
OpenAIPassthroughAllowTimeoutHeaders bool `mapstructure:"openai_passthrough_allow_timeout_headers"`
|
||||
// OpenAICompactModel: /responses/compact 上游使用的模型。
|
||||
// compact 端点支持模型滞后于普通 /responses 时,可用该配置降级规避上游错误。
|
||||
OpenAICompactModel string `mapstructure:"openai_compact_model"`
|
||||
// OpenAIWS: OpenAI Responses WebSocket 配置(默认开启,可按需回滚到 HTTP)
|
||||
OpenAIWS GatewayOpenAIWSConfig `mapstructure:"openai_ws"`
|
||||
// OpenAIScheduler: OpenAI 高级调度器粘性逃逸配置
|
||||
@@ -764,6 +819,8 @@ type GatewayConfig struct {
|
||||
ImageStreamDataIntervalTimeout int `mapstructure:"image_stream_data_interval_timeout"`
|
||||
// ImageStreamKeepaliveInterval: 图片流式 keepalive 间隔(秒),0表示禁用
|
||||
ImageStreamKeepaliveInterval int `mapstructure:"image_stream_keepalive_interval"`
|
||||
// ImageNonstreamKeepaliveInterval: 图片非流式 JSON keepalive 间隔(秒),0表示禁用
|
||||
ImageNonstreamKeepaliveInterval int `mapstructure:"image_nonstream_keepalive_interval"`
|
||||
// MaxLineSize: 上游 SSE 单行最大字节数(0使用默认值)
|
||||
MaxLineSize int `mapstructure:"max_line_size"`
|
||||
|
||||
@@ -867,8 +924,14 @@ func (c *UserMessageQueueConfig) GetEffectiveMode() string {
|
||||
type GatewayOpenAIWSConfig struct {
|
||||
// ModeRouterV2Enabled: 新版 WS mode 路由开关(默认 false;关闭时保持 legacy 行为)
|
||||
ModeRouterV2Enabled bool `mapstructure:"mode_router_v2_enabled"`
|
||||
// IngressModeDefault: ingress 默认模式(off/ctx_pool/passthrough)
|
||||
// IngressModeDefault: ingress 默认模式(off/ctx_pool/passthrough/http_bridge)
|
||||
IngressModeDefault string `mapstructure:"ingress_mode_default"`
|
||||
// IngressInterTurnIdleTimeoutSeconds bounds the time a client may remain idle
|
||||
// between completed ingress turns. Zero disables this protection.
|
||||
IngressInterTurnIdleTimeoutSeconds int `mapstructure:"ingress_inter_turn_idle_timeout_seconds"`
|
||||
// MaxIngressConnectionsPerAPIKey bounds live client WebSocket ingress sessions
|
||||
// per API key across all instances. Zero disables this protection.
|
||||
MaxIngressConnectionsPerAPIKey int `mapstructure:"max_ingress_connections_per_api_key"`
|
||||
// Enabled: 全局总开关(默认 true)
|
||||
Enabled bool `mapstructure:"enabled"`
|
||||
// OAuthEnabled: 是否允许 OpenAI OAuth 账号使用 WS
|
||||
@@ -964,6 +1027,11 @@ type GatewayOpenAIWSSchedulerScoreWeights struct {
|
||||
// Reset 倾向「会话窗口最早重置」的账号(use-it-or-lose-it)。
|
||||
// >0 时,剩余重置时间越短的账号得分越高,从而被优先用尽。默认 0(关闭,不改变原有行为)。
|
||||
Reset float64 `mapstructure:"reset"`
|
||||
// QuotaHeadroom 倾向 7d 剩余额度更健康的账号;默认 0(关闭,不改变原有行为)。
|
||||
QuotaHeadroom float64 `mapstructure:"quota_headroom"`
|
||||
// PreviousResponse/SessionSticky 仅在开启 OpenAI 高级调度的粘性加权时生效。
|
||||
PreviousResponse float64 `mapstructure:"previous_response"`
|
||||
SessionSticky float64 `mapstructure:"session_sticky"`
|
||||
}
|
||||
|
||||
// GatewayOpenAISchedulerConfig OpenAI 高级调度器配置。
|
||||
@@ -1394,6 +1462,9 @@ func load(allowMissingJWTSecret bool) (*Config, error) {
|
||||
// 环境变量支持
|
||||
viper.AutomaticEnv()
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||
if err := viper.BindEnv("server.enable_server_timing", "ENABLE_SERVER_TIMING"); err != nil {
|
||||
return nil, fmt.Errorf("bind ENABLE_SERVER_TIMING: %w", err)
|
||||
}
|
||||
|
||||
// 默认值
|
||||
setDefaults()
|
||||
@@ -1549,6 +1620,7 @@ func setDefaults() {
|
||||
viper.SetDefault("server.host", "0.0.0.0")
|
||||
viper.SetDefault("server.port", 8080)
|
||||
viper.SetDefault("server.mode", "release")
|
||||
viper.SetDefault("server.enable_server_timing", false)
|
||||
viper.SetDefault("server.frontend_url", "")
|
||||
viper.SetDefault("server.read_header_timeout", 30) // 30秒读取请求头
|
||||
viper.SetDefault("server.idle_timeout", 120) // 120秒空闲超时
|
||||
@@ -1724,6 +1796,53 @@ func setDefaults() {
|
||||
viper.SetDefault("redis.min_idle_conns", 128)
|
||||
viper.SetDefault("redis.enable_tls", false)
|
||||
|
||||
// Batch Image queue
|
||||
viper.SetDefault("batch_image.enabled", false)
|
||||
viper.SetDefault("batch_image.max_items_per_job_default", 200)
|
||||
viper.SetDefault("batch_image.max_items_per_job_trial", 50)
|
||||
viper.SetDefault("batch_image.max_output_images_per_job", 200)
|
||||
viper.SetDefault("batch_image.max_output_images_per_item", 4)
|
||||
viper.SetDefault("batch_image.max_prompt_chars_per_item", 8000)
|
||||
viper.SetDefault("batch_image.max_reference_images_per_job", 1000)
|
||||
viper.SetDefault("batch_image.max_reference_inline_bytes_per_job", 134217728)
|
||||
viper.SetDefault("batch_image.default_response_mime_type", "image/png")
|
||||
viper.SetDefault("batch_image.default_image_size", "1K")
|
||||
viper.SetDefault("batch_image.max_download_items_zip", 200)
|
||||
viper.SetDefault("batch_image.max_download_bytes_per_request", 536870912)
|
||||
viper.SetDefault("batch_image.max_download_duration_seconds", 600)
|
||||
viper.SetDefault("batch_image.max_download_concurrency_per_user", 1)
|
||||
viper.SetDefault("batch_image.input_retention_after_terminal_hours", 24)
|
||||
viper.SetDefault("batch_image.output_retention_after_terminal_hours", 72)
|
||||
viper.SetDefault("batch_image.output_retention_max_days", 7)
|
||||
viper.SetDefault("batch_image.cleanup_interval_minutes", 30)
|
||||
viper.SetDefault("batch_image.cleanup_batch_size", 100)
|
||||
viper.SetDefault("batch_image.queue_enabled", false)
|
||||
viper.SetDefault("batch_image.queue_ready_key", "batch_image:queue:ready")
|
||||
viper.SetDefault("batch_image.queue_delayed_key", "batch_image:queue:delayed")
|
||||
viper.SetDefault("batch_image.queue_active_key", "batch_image:queue:active")
|
||||
viper.SetDefault("batch_image.inflight_key_prefix", "batch_image:queue:inflight:")
|
||||
viper.SetDefault("batch_image.lock_key_prefix", "batch_image:queue:lock:")
|
||||
viper.SetDefault("batch_image.idempotency_key_prefix", "batch_image:queue:idem:")
|
||||
viper.SetDefault("batch_image.inflight_ttl_seconds", 604800)
|
||||
viper.SetDefault("batch_image.job_lock_ttl_seconds", 300)
|
||||
viper.SetDefault("batch_image.default_requeue_delay_seconds", 30)
|
||||
viper.SetDefault("batch_image.error_retry_delay_seconds", 60)
|
||||
viper.SetDefault("batch_image.lock_conflict_delay_seconds", 5)
|
||||
viper.SetDefault("batch_image.stale_active_after_seconds", 600)
|
||||
viper.SetDefault("batch_image.delayed_mover_interval_seconds", 5)
|
||||
viper.SetDefault("batch_image.recovery_interval_seconds", 300)
|
||||
viper.SetDefault("batch_image.delayed_move_limit", 100)
|
||||
viper.SetDefault("batch_image.recover_limit", 100)
|
||||
viper.SetDefault("batch_image.vertex_enabled", false)
|
||||
viper.SetDefault("batch_image.vertex_project_id", "")
|
||||
viper.SetDefault("batch_image.vertex_location", "global")
|
||||
viper.SetDefault("batch_image.vertex_managed_gcs_bucket", "")
|
||||
viper.SetDefault("batch_image.vertex_managed_gcs_prefix", "batch-image/{env}/{batch_id}")
|
||||
viper.SetDefault("batch_image.vertex_input_retention_hours", 24)
|
||||
viper.SetDefault("batch_image.vertex_output_retention_hours", 72)
|
||||
viper.SetDefault("batch_image.vertex_batch_prediction_base_url", "")
|
||||
viper.SetDefault("batch_image.vertex_gcs_base_url", "")
|
||||
|
||||
// Ops (vNext)
|
||||
viper.SetDefault("ops.enabled", true)
|
||||
viper.SetDefault("ops.use_preaggregated_tables", true)
|
||||
@@ -1834,10 +1953,13 @@ func setDefaults() {
|
||||
viper.SetDefault("gateway.force_codex_cli", false)
|
||||
viper.SetDefault("gateway.codex_image_generation_bridge_enabled", false)
|
||||
viper.SetDefault("gateway.openai_passthrough_allow_timeout_headers", false)
|
||||
viper.SetDefault("gateway.openai_compact_model", "gpt-5.4")
|
||||
// OpenAI Responses WebSocket(默认开启;可通过 force_http 紧急回滚)
|
||||
viper.SetDefault("gateway.openai_ws.enabled", true)
|
||||
viper.SetDefault("gateway.openai_ws.mode_router_v2_enabled", false)
|
||||
viper.SetDefault("gateway.openai_ws.ingress_mode_default", "ctx_pool")
|
||||
viper.SetDefault("gateway.openai_ws.ingress_inter_turn_idle_timeout_seconds", 300)
|
||||
viper.SetDefault("gateway.openai_ws.max_ingress_connections_per_api_key", 64)
|
||||
viper.SetDefault("gateway.openai_ws.oauth_enabled", true)
|
||||
viper.SetDefault("gateway.openai_ws.apikey_enabled", true)
|
||||
viper.SetDefault("gateway.openai_ws.force_http", false)
|
||||
@@ -1884,6 +2006,9 @@ func setDefaults() {
|
||||
viper.SetDefault("gateway.openai_ws.scheduler_score_weights.error_rate", 0.8)
|
||||
viper.SetDefault("gateway.openai_ws.scheduler_score_weights.ttft", 0.5)
|
||||
viper.SetDefault("gateway.openai_ws.scheduler_score_weights.reset", 0.0)
|
||||
viper.SetDefault("gateway.openai_ws.scheduler_score_weights.quota_headroom", 0.0)
|
||||
viper.SetDefault("gateway.openai_ws.scheduler_score_weights.previous_response", 5.0)
|
||||
viper.SetDefault("gateway.openai_ws.scheduler_score_weights.session_sticky", 3.0)
|
||||
// OpenAI HTTP upstream protocol strategy
|
||||
viper.SetDefault("gateway.openai_http2.enabled", true)
|
||||
viper.SetDefault("gateway.openai_http2.allow_proxy_fallback_to_http1", true)
|
||||
@@ -1914,6 +2039,7 @@ func setDefaults() {
|
||||
viper.SetDefault("gateway.stream_keepalive_interval", 10)
|
||||
viper.SetDefault("gateway.image_stream_data_interval_timeout", 900)
|
||||
viper.SetDefault("gateway.image_stream_keepalive_interval", 10)
|
||||
viper.SetDefault("gateway.image_nonstream_keepalive_interval", 0)
|
||||
viper.SetDefault("gateway.max_line_size", 500*1024*1024)
|
||||
viper.SetDefault("gateway.scheduling.sticky_session_max_waiting", 3)
|
||||
viper.SetDefault("gateway.scheduling.sticky_session_wait_timeout", 120*time.Second)
|
||||
@@ -1938,7 +2064,10 @@ func setDefaults() {
|
||||
viper.SetDefault("gateway.usage_record.worker_count", 128)
|
||||
viper.SetDefault("gateway.usage_record.queue_size", 16384)
|
||||
viper.SetDefault("gateway.usage_record.task_timeout_seconds", 5)
|
||||
viper.SetDefault("gateway.usage_record.overflow_policy", UsageRecordOverflowPolicySample)
|
||||
// 默认 sync:队列满时由提交方内联执行(提交点在响应写出之后,不阻塞客户端)。
|
||||
// sample/drop 会在溢出时静默丢弃计费任务,造成扣费与 usage_logs 对账缺口(issue #3656),
|
||||
// 仅供显式配置的运维场景使用。
|
||||
viper.SetDefault("gateway.usage_record.overflow_policy", UsageRecordOverflowPolicySync)
|
||||
viper.SetDefault("gateway.usage_record.overflow_sample_percent", 10)
|
||||
viper.SetDefault("gateway.usage_record.auto_scale_enabled", true)
|
||||
viper.SetDefault("gateway.usage_record.auto_scale_min_workers", 128)
|
||||
@@ -2318,6 +2447,61 @@ func (c *Config) Validate() error {
|
||||
if c.Redis.MinIdleConns > c.Redis.PoolSize {
|
||||
return fmt.Errorf("redis.min_idle_conns cannot exceed redis.pool_size")
|
||||
}
|
||||
if c.BatchImage.QueueEnabled {
|
||||
if strings.TrimSpace(c.BatchImage.QueueReadyKey) == "" {
|
||||
return fmt.Errorf("batch_image.queue_ready_key must not be empty")
|
||||
}
|
||||
if strings.TrimSpace(c.BatchImage.QueueDelayedKey) == "" {
|
||||
return fmt.Errorf("batch_image.queue_delayed_key must not be empty")
|
||||
}
|
||||
if strings.TrimSpace(c.BatchImage.QueueActiveKey) == "" {
|
||||
return fmt.Errorf("batch_image.queue_active_key must not be empty")
|
||||
}
|
||||
if strings.TrimSpace(c.BatchImage.InflightKeyPrefix) == "" {
|
||||
return fmt.Errorf("batch_image.inflight_key_prefix must not be empty")
|
||||
}
|
||||
if strings.TrimSpace(c.BatchImage.LockKeyPrefix) == "" {
|
||||
return fmt.Errorf("batch_image.lock_key_prefix must not be empty")
|
||||
}
|
||||
if c.BatchImage.InflightTTLSeconds <= 0 {
|
||||
return fmt.Errorf("batch_image.inflight_ttl_seconds must be positive")
|
||||
}
|
||||
if c.BatchImage.JobLockTTLSeconds <= 0 {
|
||||
return fmt.Errorf("batch_image.job_lock_ttl_seconds must be positive")
|
||||
}
|
||||
if c.BatchImage.StaleActiveAfterSeconds <= 0 {
|
||||
return fmt.Errorf("batch_image.stale_active_after_seconds must be positive")
|
||||
}
|
||||
if c.BatchImage.DelayedMoveLimit <= 0 {
|
||||
return fmt.Errorf("batch_image.delayed_move_limit must be positive")
|
||||
}
|
||||
if c.BatchImage.RecoverLimit <= 0 {
|
||||
return fmt.Errorf("batch_image.recover_limit must be positive")
|
||||
}
|
||||
}
|
||||
if c.BatchImage.VertexEnabled {
|
||||
if strings.TrimSpace(c.BatchImage.VertexManagedGCSBucket) == "" {
|
||||
return fmt.Errorf("batch_image.vertex_managed_gcs_bucket must not be empty when vertex is enabled")
|
||||
}
|
||||
if strings.Contains(c.BatchImage.VertexManagedGCSBucket, "://") {
|
||||
return fmt.Errorf("batch_image.vertex_managed_gcs_bucket must be a bucket name, not a URI")
|
||||
}
|
||||
if strings.TrimSpace(c.BatchImage.VertexLocation) == "" {
|
||||
return fmt.Errorf("batch_image.vertex_location must not be empty when vertex is enabled")
|
||||
}
|
||||
if strings.TrimSpace(c.BatchImage.VertexManagedGCSPrefix) == "" {
|
||||
return fmt.Errorf("batch_image.vertex_managed_gcs_prefix must not be empty when vertex is enabled")
|
||||
}
|
||||
if !strings.Contains(c.BatchImage.VertexManagedGCSPrefix, "{batch_id}") {
|
||||
return fmt.Errorf("batch_image.vertex_managed_gcs_prefix must contain {batch_id}")
|
||||
}
|
||||
if c.BatchImage.VertexInputRetentionHours <= 0 {
|
||||
return fmt.Errorf("batch_image.vertex_input_retention_hours must be positive")
|
||||
}
|
||||
if c.BatchImage.VertexOutputRetentionHours <= 0 {
|
||||
return fmt.Errorf("batch_image.vertex_output_retention_hours must be positive")
|
||||
}
|
||||
}
|
||||
if c.Dashboard.Enabled {
|
||||
if c.Dashboard.StatsFreshTTLSeconds <= 0 {
|
||||
return fmt.Errorf("dashboard_cache.stats_fresh_ttl_seconds must be positive")
|
||||
@@ -2542,6 +2726,13 @@ func (c *Config) Validate() error {
|
||||
(c.Gateway.ImageStreamKeepaliveInterval < 5 || c.Gateway.ImageStreamKeepaliveInterval > 60) {
|
||||
return fmt.Errorf("gateway.image_stream_keepalive_interval must be 0 or between 5-60 seconds")
|
||||
}
|
||||
if c.Gateway.ImageNonstreamKeepaliveInterval < 0 {
|
||||
return fmt.Errorf("gateway.image_nonstream_keepalive_interval must be non-negative")
|
||||
}
|
||||
if c.Gateway.ImageNonstreamKeepaliveInterval != 0 &&
|
||||
(c.Gateway.ImageNonstreamKeepaliveInterval < 5 || c.Gateway.ImageNonstreamKeepaliveInterval > 60) {
|
||||
return fmt.Errorf("gateway.image_nonstream_keepalive_interval must be 0 or between 5-60 seconds")
|
||||
}
|
||||
// 兼容旧键 sticky_previous_response_ttl_seconds
|
||||
if c.Gateway.OpenAIWS.StickyResponseIDTTLSeconds <= 0 && c.Gateway.OpenAIWS.StickyPreviousResponseTTLSeconds > 0 {
|
||||
c.Gateway.OpenAIWS.StickyResponseIDTTLSeconds = c.Gateway.OpenAIWS.StickyPreviousResponseTTLSeconds
|
||||
@@ -2549,6 +2740,12 @@ func (c *Config) Validate() error {
|
||||
if c.Gateway.OpenAIWS.MaxConnsPerAccount <= 0 {
|
||||
return fmt.Errorf("gateway.openai_ws.max_conns_per_account must be positive")
|
||||
}
|
||||
if c.Gateway.OpenAIWS.IngressInterTurnIdleTimeoutSeconds < 0 {
|
||||
return fmt.Errorf("gateway.openai_ws.ingress_inter_turn_idle_timeout_seconds must be non-negative")
|
||||
}
|
||||
if c.Gateway.OpenAIWS.MaxIngressConnectionsPerAPIKey < 0 {
|
||||
return fmt.Errorf("gateway.openai_ws.max_ingress_connections_per_api_key must be non-negative")
|
||||
}
|
||||
if c.Gateway.OpenAIWS.MinIdlePerAccount < 0 {
|
||||
return fmt.Errorf("gateway.openai_ws.min_idle_per_account must be non-negative")
|
||||
}
|
||||
@@ -2621,11 +2818,11 @@ func (c *Config) Validate() error {
|
||||
}
|
||||
if mode := strings.ToLower(strings.TrimSpace(c.Gateway.OpenAIWS.IngressModeDefault)); mode != "" {
|
||||
switch mode {
|
||||
case "off", "ctx_pool", "passthrough":
|
||||
case "off", "ctx_pool", "passthrough", "http_bridge":
|
||||
case "shared", "dedicated":
|
||||
slog.Warn("gateway.openai_ws.ingress_mode_default is deprecated, treating as ctx_pool; please update to off|ctx_pool|passthrough", "value", mode)
|
||||
slog.Warn("gateway.openai_ws.ingress_mode_default is deprecated, treating as ctx_pool; please update to off|ctx_pool|passthrough|http_bridge", "value", mode)
|
||||
default:
|
||||
return fmt.Errorf("gateway.openai_ws.ingress_mode_default must be one of off|ctx_pool|passthrough")
|
||||
return fmt.Errorf("gateway.openai_ws.ingress_mode_default must be one of off|ctx_pool|passthrough|http_bridge")
|
||||
}
|
||||
}
|
||||
if mode := strings.ToLower(strings.TrimSpace(c.Gateway.OpenAIWS.StoreDisabledConnMode)); mode != "" {
|
||||
@@ -2663,14 +2860,18 @@ func (c *Config) Validate() error {
|
||||
c.Gateway.OpenAIWS.SchedulerScoreWeights.Load < 0 ||
|
||||
c.Gateway.OpenAIWS.SchedulerScoreWeights.Queue < 0 ||
|
||||
c.Gateway.OpenAIWS.SchedulerScoreWeights.ErrorRate < 0 ||
|
||||
c.Gateway.OpenAIWS.SchedulerScoreWeights.TTFT < 0 {
|
||||
c.Gateway.OpenAIWS.SchedulerScoreWeights.TTFT < 0 ||
|
||||
c.Gateway.OpenAIWS.SchedulerScoreWeights.QuotaHeadroom < 0 ||
|
||||
c.Gateway.OpenAIWS.SchedulerScoreWeights.PreviousResponse < 0 ||
|
||||
c.Gateway.OpenAIWS.SchedulerScoreWeights.SessionSticky < 0 {
|
||||
return fmt.Errorf("gateway.openai_ws.scheduler_score_weights.* must be non-negative")
|
||||
}
|
||||
weightSum := c.Gateway.OpenAIWS.SchedulerScoreWeights.Priority +
|
||||
c.Gateway.OpenAIWS.SchedulerScoreWeights.Load +
|
||||
c.Gateway.OpenAIWS.SchedulerScoreWeights.Queue +
|
||||
c.Gateway.OpenAIWS.SchedulerScoreWeights.ErrorRate +
|
||||
c.Gateway.OpenAIWS.SchedulerScoreWeights.TTFT
|
||||
c.Gateway.OpenAIWS.SchedulerScoreWeights.TTFT +
|
||||
c.Gateway.OpenAIWS.SchedulerScoreWeights.QuotaHeadroom
|
||||
if weightSum <= 0 {
|
||||
return fmt.Errorf("gateway.openai_ws.scheduler_score_weights must not all be zero")
|
||||
}
|
||||
|
||||
@@ -17,6 +17,23 @@ func resetViperWithJWTSecret(t *testing.T) {
|
||||
t.Setenv("JWT_SECRET", strings.Repeat("x", 32))
|
||||
}
|
||||
|
||||
func TestLoadServerTimingConfig(t *testing.T) {
|
||||
t.Run("disabled by default", func(t *testing.T) {
|
||||
resetViperWithJWTSecret(t)
|
||||
cfg, err := Load()
|
||||
require.NoError(t, err)
|
||||
require.False(t, cfg.Server.EnableServerTiming)
|
||||
})
|
||||
|
||||
t.Run("enabled by exact environment variable", func(t *testing.T) {
|
||||
resetViperWithJWTSecret(t)
|
||||
t.Setenv("ENABLE_SERVER_TIMING", "true")
|
||||
cfg, err := Load()
|
||||
require.NoError(t, err)
|
||||
require.True(t, cfg.Server.EnableServerTiming)
|
||||
})
|
||||
}
|
||||
|
||||
func TestLoadForBootstrapAllowsMissingJWTSecret(t *testing.T) {
|
||||
viper.Reset()
|
||||
t.Setenv("JWT_SECRET", "")
|
||||
@@ -167,6 +184,9 @@ func TestLoadDefaultOpenAIWSConfig(t *testing.T) {
|
||||
if cfg.Gateway.OpenAIWS.PayloadLogSampleRate != 0.2 {
|
||||
t.Fatalf("Gateway.OpenAIWS.PayloadLogSampleRate = %v, want 0.2", cfg.Gateway.OpenAIWS.PayloadLogSampleRate)
|
||||
}
|
||||
if cfg.Gateway.OpenAIWS.SchedulerScoreWeights.QuotaHeadroom != 0 {
|
||||
t.Fatalf("Gateway.OpenAIWS.SchedulerScoreWeights.QuotaHeadroom = %v, want 0", cfg.Gateway.OpenAIWS.SchedulerScoreWeights.QuotaHeadroom)
|
||||
}
|
||||
if !cfg.Gateway.OpenAIWS.StoreDisabledForceNewConn {
|
||||
t.Fatalf("Gateway.OpenAIWS.StoreDisabledForceNewConn = false, want true")
|
||||
}
|
||||
@@ -179,6 +199,29 @@ func TestLoadDefaultOpenAIWSConfig(t *testing.T) {
|
||||
if cfg.Gateway.OpenAIWS.IngressModeDefault != "ctx_pool" {
|
||||
t.Fatalf("Gateway.OpenAIWS.IngressModeDefault = %q, want %q", cfg.Gateway.OpenAIWS.IngressModeDefault, "ctx_pool")
|
||||
}
|
||||
if cfg.Gateway.OpenAIWS.IngressInterTurnIdleTimeoutSeconds != 300 {
|
||||
t.Fatalf("Gateway.OpenAIWS.IngressInterTurnIdleTimeoutSeconds = %d, want 300", cfg.Gateway.OpenAIWS.IngressInterTurnIdleTimeoutSeconds)
|
||||
}
|
||||
if cfg.Gateway.OpenAIWS.MaxIngressConnectionsPerAPIKey != 64 {
|
||||
t.Fatalf("Gateway.OpenAIWS.MaxIngressConnectionsPerAPIKey = %d, want 64", cfg.Gateway.OpenAIWS.MaxIngressConnectionsPerAPIKey)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadDefaultOpenAICompactModel(t *testing.T) {
|
||||
resetViperWithJWTSecret(t)
|
||||
|
||||
cfg, err := Load()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "gpt-5.4", cfg.Gateway.OpenAICompactModel)
|
||||
}
|
||||
|
||||
func TestLoadOpenAICompactModelFromEnv(t *testing.T) {
|
||||
resetViperWithJWTSecret(t)
|
||||
t.Setenv("GATEWAY_OPENAI_COMPACT_MODEL", "gpt-5.3-codex")
|
||||
|
||||
cfg, err := Load()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "gpt-5.3-codex", cfg.Gateway.OpenAICompactModel)
|
||||
}
|
||||
|
||||
func TestLoadDefaultOpenAIHTTP2Enabled(t *testing.T) {
|
||||
@@ -216,6 +259,15 @@ func TestLoadOpenAIResponseHeaderTimeoutFromEnv(t *testing.T) {
|
||||
require.Equal(t, 1800, cfg.Gateway.OpenAIResponseHeaderTimeout)
|
||||
}
|
||||
|
||||
func TestLoadImageNonstreamKeepaliveFromEnv(t *testing.T) {
|
||||
resetViperWithJWTSecret(t)
|
||||
t.Setenv("GATEWAY_IMAGE_NONSTREAM_KEEPALIVE_INTERVAL", "15")
|
||||
|
||||
cfg, err := Load()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 15, cfg.Gateway.ImageNonstreamKeepaliveInterval)
|
||||
}
|
||||
|
||||
func TestLoadOpenAIWSStickyTTLCompatibility(t *testing.T) {
|
||||
resetViperWithJWTSecret(t)
|
||||
t.Setenv("GATEWAY_OPENAI_WS_STICKY_RESPONSE_ID_TTL_SECONDS", "0")
|
||||
@@ -250,6 +302,14 @@ func TestLoadDefaultIdempotencyConfig(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadDefaultBatchImageQueueDisabled(t *testing.T) {
|
||||
resetViperWithJWTSecret(t)
|
||||
|
||||
cfg, err := Load()
|
||||
require.NoError(t, err)
|
||||
require.False(t, cfg.BatchImage.QueueEnabled)
|
||||
}
|
||||
|
||||
func TestLoadIdempotencyConfigFromEnv(t *testing.T) {
|
||||
resetViperWithJWTSecret(t)
|
||||
t.Setenv("IDEMPOTENCY_OBSERVE_ONLY", "false")
|
||||
@@ -1378,6 +1438,16 @@ func TestValidateConfigErrors(t *testing.T) {
|
||||
mutate: func(c *Config) { c.Gateway.ImageStreamKeepaliveInterval = -1 },
|
||||
wantErr: "gateway.image_stream_keepalive_interval must be non-negative",
|
||||
},
|
||||
{
|
||||
name: "gateway image nonstream keepalive range",
|
||||
mutate: func(c *Config) { c.Gateway.ImageNonstreamKeepaliveInterval = 4 },
|
||||
wantErr: "gateway.image_nonstream_keepalive_interval",
|
||||
},
|
||||
{
|
||||
name: "gateway image nonstream keepalive negative",
|
||||
mutate: func(c *Config) { c.Gateway.ImageNonstreamKeepaliveInterval = -1 },
|
||||
wantErr: "gateway.image_nonstream_keepalive_interval must be non-negative",
|
||||
},
|
||||
{
|
||||
name: "gateway image stream data interval range",
|
||||
mutate: func(c *Config) { c.Gateway.ImageStreamDataIntervalTimeout = 30 },
|
||||
@@ -1612,6 +1682,16 @@ func TestValidateConfig_OpenAIWSRules(t *testing.T) {
|
||||
mutate: func(c *Config) { c.Gateway.OpenAIWS.MaxConnsPerAccount = 0 },
|
||||
wantErr: "gateway.openai_ws.max_conns_per_account",
|
||||
},
|
||||
{
|
||||
name: "ingress_inter_turn_idle_timeout_seconds 不能为负数",
|
||||
mutate: func(c *Config) { c.Gateway.OpenAIWS.IngressInterTurnIdleTimeoutSeconds = -1 },
|
||||
wantErr: "gateway.openai_ws.ingress_inter_turn_idle_timeout_seconds",
|
||||
},
|
||||
{
|
||||
name: "max_ingress_connections_per_api_key 不能为负数",
|
||||
mutate: func(c *Config) { c.Gateway.OpenAIWS.MaxIngressConnectionsPerAPIKey = -1 },
|
||||
wantErr: "gateway.openai_ws.max_ingress_connections_per_api_key",
|
||||
},
|
||||
{
|
||||
name: "min_idle_per_account 不能为负数",
|
||||
mutate: func(c *Config) { c.Gateway.OpenAIWS.MinIdlePerAccount = -1 },
|
||||
@@ -1675,7 +1755,7 @@ func TestValidateConfig_OpenAIWSRules(t *testing.T) {
|
||||
wantErr: "gateway.openai_ws.store_disabled_conn_mode",
|
||||
},
|
||||
{
|
||||
name: "ingress_mode_default 必须为 off|ctx_pool|passthrough",
|
||||
name: "ingress_mode_default 必须为 off|ctx_pool|passthrough|http_bridge",
|
||||
mutate: func(c *Config) { c.Gateway.OpenAIWS.IngressModeDefault = "invalid" },
|
||||
wantErr: "gateway.openai_ws.ingress_mode_default",
|
||||
},
|
||||
@@ -1717,6 +1797,11 @@ func TestValidateConfig_OpenAIWSRules(t *testing.T) {
|
||||
mutate: func(c *Config) { c.Gateway.OpenAIWS.SchedulerScoreWeights.Queue = -0.1 },
|
||||
wantErr: "gateway.openai_ws.scheduler_score_weights.* must be non-negative",
|
||||
},
|
||||
{
|
||||
name: "scheduler_score_weights quota_headroom 不能为负数",
|
||||
mutate: func(c *Config) { c.Gateway.OpenAIWS.SchedulerScoreWeights.QuotaHeadroom = -0.1 },
|
||||
wantErr: "gateway.openai_ws.scheduler_score_weights.* must be non-negative",
|
||||
},
|
||||
{
|
||||
name: "scheduler_score_weights 不能全为 0",
|
||||
mutate: func(c *Config) {
|
||||
@@ -1756,6 +1841,18 @@ func TestValidateConfig_OpenAIWSRules(t *testing.T) {
|
||||
require.Contains(t, err.Error(), tc.wantErr)
|
||||
})
|
||||
}
|
||||
|
||||
t.Run("quota_headroom 可作为唯一有效调度权重", func(t *testing.T) {
|
||||
cfg := buildValid(t)
|
||||
cfg.Gateway.OpenAIWS.SchedulerScoreWeights.Priority = 0
|
||||
cfg.Gateway.OpenAIWS.SchedulerScoreWeights.Load = 0
|
||||
cfg.Gateway.OpenAIWS.SchedulerScoreWeights.Queue = 0
|
||||
cfg.Gateway.OpenAIWS.SchedulerScoreWeights.ErrorRate = 0
|
||||
cfg.Gateway.OpenAIWS.SchedulerScoreWeights.TTFT = 0
|
||||
cfg.Gateway.OpenAIWS.SchedulerScoreWeights.QuotaHeadroom = 0.1
|
||||
|
||||
require.NoError(t, cfg.Validate())
|
||||
})
|
||||
}
|
||||
|
||||
func TestValidateConfig_AutoScaleDisabledIgnoreAutoScaleFields(t *testing.T) {
|
||||
@@ -1866,8 +1963,8 @@ func TestLoad_DefaultGatewayUsageRecordConfig(t *testing.T) {
|
||||
if cfg.Gateway.UsageRecord.TaskTimeoutSeconds != 5 {
|
||||
t.Fatalf("task_timeout_seconds = %d, want 5", cfg.Gateway.UsageRecord.TaskTimeoutSeconds)
|
||||
}
|
||||
if cfg.Gateway.UsageRecord.OverflowPolicy != UsageRecordOverflowPolicySample {
|
||||
t.Fatalf("overflow_policy = %s, want %s", cfg.Gateway.UsageRecord.OverflowPolicy, UsageRecordOverflowPolicySample)
|
||||
if cfg.Gateway.UsageRecord.OverflowPolicy != UsageRecordOverflowPolicySync {
|
||||
t.Fatalf("overflow_policy = %s, want %s", cfg.Gateway.UsageRecord.OverflowPolicy, UsageRecordOverflowPolicySync)
|
||||
}
|
||||
if cfg.Gateway.UsageRecord.OverflowSamplePercent != 10 {
|
||||
t.Fatalf("overflow_sample_percent = %d, want 10", cfg.Gateway.UsageRecord.OverflowSamplePercent)
|
||||
@@ -1919,6 +2016,9 @@ func TestLoad_DefaultGatewayImageStreamConfig(t *testing.T) {
|
||||
if cfg.Gateway.ImageStreamKeepaliveInterval != 10 {
|
||||
t.Fatalf("image_stream_keepalive_interval = %d, want 10", cfg.Gateway.ImageStreamKeepaliveInterval)
|
||||
}
|
||||
if cfg.Gateway.ImageNonstreamKeepaliveInterval != 0 {
|
||||
t.Fatalf("image_nonstream_keepalive_interval = %d, want 0", cfg.Gateway.ImageNonstreamKeepaliveInterval)
|
||||
}
|
||||
if cfg.Gateway.ImageConcurrency.Enabled {
|
||||
t.Fatalf("image_concurrency.enabled = true, want false")
|
||||
}
|
||||
|
||||
@@ -68,6 +68,9 @@ const (
|
||||
SubscriptionStatusSuspended = "suspended"
|
||||
)
|
||||
|
||||
// AntigravityGemini31ProAgentModel is the upstream route for Gemini 3.1 Pro High.
|
||||
const AntigravityGemini31ProAgentModel = "gemini-pro-agent"
|
||||
|
||||
// DefaultAntigravityModelMapping 是 Antigravity 平台的默认模型映射
|
||||
// 当账号未配置 model_mapping 时使用此默认值
|
||||
// 与前端 useModelWhitelist.ts 中的 antigravityDefaultMappings 保持一致
|
||||
@@ -103,10 +106,12 @@ var DefaultAntigravityModelMapping = map[string]string{
|
||||
"gemini-3-flash-preview": "gemini-3-flash",
|
||||
"gemini-3-pro-preview": "gemini-3-pro-high",
|
||||
// Gemini 3.1 白名单
|
||||
"gemini-3.1-pro-high": "gemini-3.1-pro-high",
|
||||
"gemini-3.1-pro-low": "gemini-3.1-pro-low",
|
||||
AntigravityGemini31ProAgentModel: AntigravityGemini31ProAgentModel,
|
||||
"gemini-3.1-pro": AntigravityGemini31ProAgentModel,
|
||||
"gemini-3.1-pro-high": AntigravityGemini31ProAgentModel,
|
||||
"gemini-3.1-pro-low": "gemini-3.1-pro-low",
|
||||
// Gemini 3.1 preview 映射
|
||||
"gemini-3.1-pro-preview": "gemini-3.1-pro-high",
|
||||
"gemini-3.1-pro-preview": AntigravityGemini31ProAgentModel,
|
||||
// Gemini 3.1 image 白名单
|
||||
"gemini-3.1-flash-image": "gemini-3.1-flash-image",
|
||||
// Gemini 3.1 image preview 映射
|
||||
@@ -136,6 +141,7 @@ var DefaultBedrockModelMapping = map[string]string{
|
||||
"claude-opus-4-1": "us.anthropic.claude-opus-4-1-20250805-v1:0",
|
||||
"claude-opus-4-20250514": "us.anthropic.claude-opus-4-20250514-v1:0",
|
||||
// Claude Sonnet
|
||||
"claude-sonnet-5": "us.anthropic.claude-sonnet-5-v1",
|
||||
"claude-sonnet-4-6-thinking": "us.anthropic.claude-sonnet-4-6",
|
||||
"claude-sonnet-4-6": "us.anthropic.claude-sonnet-4-6",
|
||||
"claude-sonnet-4-5": "us.anthropic.claude-sonnet-4-5-20250929-v1:0",
|
||||
|
||||
@@ -43,6 +43,28 @@ func TestDefaultAntigravityModelMapping_ContainsNewClaudeModels(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultAntigravityModelMapping_Gemini31ProAliases(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cases := map[string]string{
|
||||
AntigravityGemini31ProAgentModel: AntigravityGemini31ProAgentModel,
|
||||
"gemini-3.1-pro": AntigravityGemini31ProAgentModel,
|
||||
"gemini-3.1-pro-high": AntigravityGemini31ProAgentModel,
|
||||
"gemini-3.1-pro-preview": AntigravityGemini31ProAgentModel,
|
||||
"gemini-3.1-pro-low": "gemini-3.1-pro-low",
|
||||
}
|
||||
|
||||
for from, want := range cases {
|
||||
got, ok := DefaultAntigravityModelMapping[from]
|
||||
if !ok {
|
||||
t.Fatalf("expected mapping for %q to exist", from)
|
||||
}
|
||||
if got != want {
|
||||
t.Fatalf("unexpected mapping for %q: got %q want %q", from, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultBedrockModelMapping_ContainsNewClaudeModels(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ type codexJWTOpenAIClaims struct {
|
||||
}
|
||||
|
||||
type codexAccountIndex struct {
|
||||
accountsByKey map[string]service.Account
|
||||
accountsByKey map[string][]service.Account
|
||||
}
|
||||
|
||||
func (h *AccountHandler) ImportCodexSession(c *gin.Context) {
|
||||
@@ -115,6 +115,10 @@ func (h *AccountHandler) ImportCodexSession(c *gin.Context) {
|
||||
response.BadRequest(c, "Invalid request: "+err.Error())
|
||||
return
|
||||
}
|
||||
if err := service.ValidateOpenAILongContextBillingExtra(service.PlatformOpenAI, req.Extra); err != nil {
|
||||
response.ErrorFrom(c, err)
|
||||
return
|
||||
}
|
||||
if req.Concurrency != nil && *req.Concurrency < 0 {
|
||||
response.BadRequest(c, "concurrency must be >= 0")
|
||||
return
|
||||
@@ -178,7 +182,7 @@ func (h *AccountHandler) importCodexSessions(ctx context.Context, req CodexSessi
|
||||
}
|
||||
skipMixedChannelCheck := req.ConfirmMixedChannelRisk != nil && *req.ConfirmMixedChannelRisk
|
||||
|
||||
seenIdentity := map[string]int{}
|
||||
seenIdentity := map[string]codexSeenIdentity{}
|
||||
for _, entry := range entries {
|
||||
item, err := normalizeCodexImportEntry(entry)
|
||||
if err != nil {
|
||||
@@ -225,7 +229,7 @@ func (h *AccountHandler) importCodexSessions(ctx context.Context, req CodexSessi
|
||||
})
|
||||
}
|
||||
|
||||
if duplicateIndex, ok := firstSeenCodexIdentity(seenIdentity, item.IdentityKeys); ok {
|
||||
if duplicateIndex, ok := firstSeenCodexIdentity(seenIdentity, item.IdentityKeys, item.UserID); ok {
|
||||
message := fmt.Sprintf("与第 %d 条导入项重复,已跳过", duplicateIndex)
|
||||
result.Skipped++
|
||||
result.Items = append(result.Items, CodexSessionImportItem{
|
||||
@@ -241,9 +245,29 @@ func (h *AccountHandler) importCodexSessions(ctx context.Context, req CodexSessi
|
||||
})
|
||||
continue
|
||||
}
|
||||
markCodexIdentitySeen(seenIdentity, item.IdentityKeys, entry.Index)
|
||||
markCodexIdentitySeen(seenIdentity, item.IdentityKeys, entry.Index, item.UserID)
|
||||
|
||||
if existing := index.Find(item.IdentityKeys); existing != nil && updateExisting {
|
||||
existing, matchedKey := index.Find(item.IdentityKeys, item.UserID)
|
||||
if existing != nil && updateExisting {
|
||||
if strings.HasPrefix(matchedKey, "account:") && item.UserID != "" &&
|
||||
codexCredentialString(existing.Credentials, "chatgpt_user_id") == "" {
|
||||
result.Warnings = append(result.Warnings, CodexSessionImportMessage{
|
||||
Index: entry.Index,
|
||||
Name: accountName,
|
||||
Message: "已有账号未记录 chatgpt_user_id,已按共享的 chatgpt_account_id 匹配并回填,请确认两者属于同一用户",
|
||||
})
|
||||
}
|
||||
preserveExistingRefresh := item.RefreshToken == "" &&
|
||||
codexCredentialString(existing.Credentials, "refresh_token") != ""
|
||||
if preserveExistingRefresh {
|
||||
result.Warnings = append(result.Warnings, CodexSessionImportMessage{
|
||||
Index: entry.Index,
|
||||
Name: accountName,
|
||||
Message: "已有账号包含 refresh_token,本次 accessToken-only 导入已保留自动续期凭据",
|
||||
})
|
||||
effectiveExpiresAt = nil
|
||||
autoPauseOnExpired = nil
|
||||
}
|
||||
mergedCredentials := mergeCodexImportCredentials(existing.Credentials, credentials, item)
|
||||
mergedExtra := mergeCodexImportMap(existing.Extra, extra)
|
||||
updateInput := &service.UpdateAccountInput{
|
||||
@@ -583,7 +607,7 @@ func normalizeCodexImportEntry(entry codexImportEntry) (*codexImportAccount, err
|
||||
|
||||
fingerprint := codexTokenFingerprint(item.AccessToken)
|
||||
item.Extra["access_token_sha256"] = fingerprint
|
||||
item.IdentityKeys = buildCodexIdentityKeys(item.AccountID, item.UserID, item.Email, item.AccessToken)
|
||||
item.IdentityKeys = buildCodexImportIdentityKeys(item.AccountID, item.UserID, item.Email, item.AccessToken, item.RefreshToken)
|
||||
item.Name = buildCodexImportAccountName(item, entry.Index)
|
||||
|
||||
return item, nil
|
||||
@@ -806,13 +830,25 @@ func sanitizeCodexImportCredentialExtras(input map[string]any) map[string]any {
|
||||
return out
|
||||
}
|
||||
|
||||
func buildCodexIdentityKeys(accountID, userID, email, accessToken string) []string {
|
||||
keys := make([]string, 0, 4)
|
||||
// buildCodexImportIdentityKeys 生成导入条目的匹配键。refresh_token 缺失时
|
||||
// Codex session 只能作为 accessToken-only 凭据使用,此时以 access token
|
||||
// 指纹作为唯一稳定身份,避免同 workspace 下共享的 account/user 标识误合并。
|
||||
func buildCodexImportIdentityKeys(accountID, userID, email, accessToken, refreshToken string) []string {
|
||||
accessToken = strings.TrimSpace(accessToken)
|
||||
refreshToken = strings.TrimSpace(refreshToken)
|
||||
if refreshToken == "" && accessToken != "" {
|
||||
return []string{"access:" + codexTokenFingerprint(accessToken)}
|
||||
}
|
||||
return buildCodexStoredIdentityKeys(accountID, userID, email, accessToken)
|
||||
}
|
||||
|
||||
// buildCodexStoredIdentityKeys 生成存量账号索引键,保留 user/account 维度,
|
||||
// 让 accessToken-only 账号后续升级为完整 OAuth 时仍能命中并更新原账号。
|
||||
func buildCodexStoredIdentityKeys(accountID, userID, email, accessToken string) []string {
|
||||
keys := make([]string, 0, 3)
|
||||
accountID = strings.TrimSpace(accountID)
|
||||
userID = strings.TrimSpace(userID)
|
||||
if accountID != "" {
|
||||
keys = append(keys, "account:"+accountID)
|
||||
}
|
||||
accessToken = strings.TrimSpace(accessToken)
|
||||
if userID != "" {
|
||||
keys = append(keys, "user:"+userID)
|
||||
}
|
||||
@@ -821,14 +857,17 @@ func buildCodexIdentityKeys(accountID, userID, email, accessToken string) []stri
|
||||
keys = append(keys, "email:"+email)
|
||||
}
|
||||
}
|
||||
if accessToken = strings.TrimSpace(accessToken); accessToken != "" {
|
||||
if accessToken != "" {
|
||||
keys = append(keys, "access:"+codexTokenFingerprint(accessToken))
|
||||
}
|
||||
if accountID != "" {
|
||||
keys = append(keys, "account:"+accountID)
|
||||
}
|
||||
return keys
|
||||
}
|
||||
|
||||
func buildCodexAccountIndex(accounts []service.Account) *codexAccountIndex {
|
||||
index := &codexAccountIndex{accountsByKey: map[string]service.Account{}}
|
||||
index := &codexAccountIndex{accountsByKey: map[string][]service.Account{}}
|
||||
for _, account := range accounts {
|
||||
index.Add(account)
|
||||
}
|
||||
@@ -840,43 +879,99 @@ func (i *codexAccountIndex) Add(account service.Account) {
|
||||
return
|
||||
}
|
||||
if i.accountsByKey == nil {
|
||||
i.accountsByKey = map[string]service.Account{}
|
||||
i.accountsByKey = map[string][]service.Account{}
|
||||
}
|
||||
keys := buildCodexIdentityKeys(
|
||||
i.remove(account.ID)
|
||||
keys := buildCodexStoredIdentityKeys(
|
||||
codexCredentialString(account.Credentials, "chatgpt_account_id"),
|
||||
codexCredentialString(account.Credentials, "chatgpt_user_id"),
|
||||
codexCredentialString(account.Credentials, "email"),
|
||||
codexCredentialString(account.Credentials, "access_token"),
|
||||
)
|
||||
for _, key := range keys {
|
||||
i.accountsByKey[key] = account
|
||||
i.accountsByKey[key] = upsertCodexAccount(i.accountsByKey[key], account)
|
||||
}
|
||||
}
|
||||
|
||||
func (i *codexAccountIndex) Find(keys []string) *service.Account {
|
||||
func (i *codexAccountIndex) remove(accountID int64) {
|
||||
for key, accounts := range i.accountsByKey {
|
||||
kept := accounts[:0]
|
||||
for _, account := range accounts {
|
||||
if account.ID != accountID {
|
||||
kept = append(kept, account)
|
||||
}
|
||||
}
|
||||
if len(kept) == 0 {
|
||||
delete(i.accountsByKey, key)
|
||||
continue
|
||||
}
|
||||
i.accountsByKey[key] = kept
|
||||
}
|
||||
}
|
||||
|
||||
// upsertCodexAccount 保留同一键下的全部候选账号(共享的 account: 键可对应
|
||||
// 团队内多个账号),同一账号重复 Add 时原位替换为最新状态。
|
||||
func upsertCodexAccount(accounts []service.Account, account service.Account) []service.Account {
|
||||
for idx := range accounts {
|
||||
if accounts[idx].ID == account.ID {
|
||||
accounts[idx] = account
|
||||
return accounts
|
||||
}
|
||||
}
|
||||
return append(accounts, account)
|
||||
}
|
||||
|
||||
// Find 返回第一个通过跨用户校验的候选账号及其命中的匹配键。
|
||||
func (i *codexAccountIndex) Find(keys []string, userID string) (*service.Account, string) {
|
||||
if i == nil {
|
||||
return nil
|
||||
return nil, ""
|
||||
}
|
||||
for _, key := range keys {
|
||||
if account, ok := i.accountsByKey[key]; ok {
|
||||
return &account
|
||||
for _, account := range i.accountsByKey[key] {
|
||||
if codexIdentityConflicts(key, userID, codexCredentialString(account.Credentials, "chatgpt_user_id")) {
|
||||
continue
|
||||
}
|
||||
return &account, key
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return nil, ""
|
||||
}
|
||||
|
||||
func firstSeenCodexIdentity(seen map[string]int, keys []string) (int, bool) {
|
||||
// codexIdentityConflicts 判断 account: 键的命中是否把同一 ChatGPT 团队的两个
|
||||
// 不同成员误连到一起:双方都携带 user id 且不相等时视为冲突。存量索引侧
|
||||
// 仍保留 account 键,任一侧缺少 user id 时允许匹配,使含 refresh_token
|
||||
// 的常规导入和 accessToken-only 账号升级为完整 OAuth 时仍能更新原账号。
|
||||
func codexIdentityConflicts(key, userID, storedUserID string) bool {
|
||||
if !strings.HasPrefix(key, "account:") {
|
||||
return false
|
||||
}
|
||||
userID = strings.TrimSpace(userID)
|
||||
storedUserID = strings.TrimSpace(storedUserID)
|
||||
return userID != "" && storedUserID != "" && userID != storedUserID
|
||||
}
|
||||
|
||||
type codexSeenIdentity struct {
|
||||
index int
|
||||
userID string
|
||||
}
|
||||
|
||||
func firstSeenCodexIdentity(seen map[string]codexSeenIdentity, keys []string, userID string) (int, bool) {
|
||||
for _, key := range keys {
|
||||
if index, ok := seen[key]; ok {
|
||||
return index, true
|
||||
entry, ok := seen[key]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if codexIdentityConflicts(key, userID, entry.userID) {
|
||||
continue
|
||||
}
|
||||
return entry.index, true
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func markCodexIdentitySeen(seen map[string]int, keys []string, index int) {
|
||||
func markCodexIdentitySeen(seen map[string]codexSeenIdentity, keys []string, index int, userID string) {
|
||||
for _, key := range keys {
|
||||
seen[key] = index
|
||||
seen[key] = codexSeenIdentity{index: index, userID: userID}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -897,8 +992,15 @@ func mergeCodexImportCredentials(existing, incoming map[string]any, item *codexI
|
||||
return out
|
||||
}
|
||||
if strings.TrimSpace(item.RefreshToken) == "" {
|
||||
delete(out, "refresh_token")
|
||||
delete(out, "client_id")
|
||||
if codexCredentialString(existing, "refresh_token") == "" {
|
||||
delete(out, "refresh_token")
|
||||
delete(out, "client_id")
|
||||
} else {
|
||||
out["refresh_token"] = existing["refresh_token"]
|
||||
if clientID, ok := existing["client_id"]; ok {
|
||||
out["client_id"] = clientID
|
||||
}
|
||||
}
|
||||
}
|
||||
if strings.TrimSpace(item.IDToken) == "" {
|
||||
delete(out, "id_token")
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/Wei-Shaw/sub2api/internal/service"
|
||||
)
|
||||
|
||||
func TestParseCodexSessionImportEntriesSupportsRawTokenJSONAndArray(t *testing.T) {
|
||||
@@ -142,7 +145,7 @@ func TestNormalizeCodexSessionJSONExtractsCredentialsAndIgnoresSessionToken(t *t
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergeCodexImportCredentialsClearsStaleRefreshFieldsWhenIncomingHasNoRefreshToken(t *testing.T) {
|
||||
func TestMergeCodexImportCredentialsPreservesExistingRefreshFieldsWhenIncomingHasNoRefreshToken(t *testing.T) {
|
||||
existing := map[string]any{
|
||||
"access_token": "old-access-token",
|
||||
"refresh_token": "old-refresh-token",
|
||||
@@ -169,11 +172,11 @@ func TestMergeCodexImportCredentialsClearsStaleRefreshFieldsWhenIncomingHasNoRef
|
||||
if merged["chatgpt_account_id"] != "acct-new" {
|
||||
t.Fatalf("chatgpt_account_id = %v, want acct-new", merged["chatgpt_account_id"])
|
||||
}
|
||||
if _, ok := merged["refresh_token"]; ok {
|
||||
t.Fatalf("refresh_token should be cleared")
|
||||
if merged["refresh_token"] != "old-refresh-token" {
|
||||
t.Fatalf("refresh_token = %v, want old-refresh-token", merged["refresh_token"])
|
||||
}
|
||||
if _, ok := merged["client_id"]; ok {
|
||||
t.Fatalf("client_id should be cleared")
|
||||
if merged["client_id"] != "old-client-id" {
|
||||
t.Fatalf("client_id = %v, want old-client-id", merged["client_id"])
|
||||
}
|
||||
if _, ok := merged["id_token"]; ok {
|
||||
t.Fatalf("id_token should be cleared")
|
||||
@@ -299,14 +302,20 @@ func TestResolveCodexImportExpiryForNoRefreshTokenUsesEarlierRequestExpiry(t *te
|
||||
}
|
||||
|
||||
func TestCodexIdentityKeysPreferStrongIdentifiers(t *testing.T) {
|
||||
keys := buildCodexIdentityKeys("acct-1", "user-1", "same@example.com", "token")
|
||||
keys := buildCodexImportIdentityKeys("acct-1", "user-1", "same@example.com", "token", "refresh")
|
||||
if len(keys) == 0 || keys[0] != "user:user-1" {
|
||||
t.Fatalf("user key should have highest priority when refresh token exists: %v", keys)
|
||||
}
|
||||
if keys[len(keys)-1] != "account:acct-1" {
|
||||
t.Fatalf("shared account key should be the last fallback: %v", keys)
|
||||
}
|
||||
for _, key := range keys {
|
||||
if strings.HasPrefix(key, "email:") {
|
||||
t.Fatalf("strong identity should not include email fallback: %v", keys)
|
||||
}
|
||||
}
|
||||
|
||||
keys = buildCodexIdentityKeys("", "", "same@example.com", "token")
|
||||
keys = buildCodexImportIdentityKeys("", "", "same@example.com", "token", "refresh")
|
||||
hasEmail := false
|
||||
for _, key := range keys {
|
||||
if key == "email:same@example.com" {
|
||||
@@ -316,6 +325,609 @@ func TestCodexIdentityKeysPreferStrongIdentifiers(t *testing.T) {
|
||||
if !hasEmail {
|
||||
t.Fatalf("weak identity should include email fallback: %v", keys)
|
||||
}
|
||||
|
||||
keys = buildCodexImportIdentityKeys("acct-1", "user-1", "same@example.com", "token", "")
|
||||
if len(keys) != 1 || !strings.HasPrefix(keys[0], "access:") {
|
||||
t.Fatalf("accessToken-only identity should use only access fingerprint: %v", keys)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCodexAccountIndexDoesNotMatchDifferentUsersInSameChatGPTAccount(t *testing.T) {
|
||||
existing := service.Account{
|
||||
ID: 10,
|
||||
Credentials: map[string]any{
|
||||
"chatgpt_account_id": "team-1",
|
||||
"chatgpt_user_id": "user-1",
|
||||
"access_token": "token-1",
|
||||
"refresh_token": "refresh-1",
|
||||
},
|
||||
}
|
||||
index := buildCodexAccountIndex([]service.Account{existing})
|
||||
|
||||
keys := buildCodexImportIdentityKeys("team-1", "user-2", "", "token-2", "refresh-2")
|
||||
if got, _ := index.Find(keys, "user-2"); got != nil {
|
||||
t.Fatalf("Find matched account ID %d for a different chatgpt_user_id in the same team", got.ID)
|
||||
}
|
||||
|
||||
keys = buildCodexImportIdentityKeys("team-1", "user-1", "", "token-2", "refresh-2")
|
||||
got, _ := index.Find(keys, "user-1")
|
||||
if got == nil || got.ID != existing.ID {
|
||||
t.Fatalf("Find by same chatgpt_user_id = %v, want account ID %d", got, existing.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCodexAccountIndexFallsBackToAccountKeyWhenRefreshTokenExistsAndUserIDMissing(t *testing.T) {
|
||||
// 含 refresh_token 的常规导入沿用 a5638a4e 的兼容逻辑:存量账号缺少
|
||||
// chatgpt_user_id 时,携带 user id 的重新导入仍可命中并回填。
|
||||
legacy := service.Account{
|
||||
ID: 20,
|
||||
Credentials: map[string]any{
|
||||
"chatgpt_account_id": "team-1",
|
||||
"access_token": "token-old",
|
||||
"refresh_token": "refresh-old",
|
||||
},
|
||||
}
|
||||
index := buildCodexAccountIndex([]service.Account{legacy})
|
||||
|
||||
keys := buildCodexImportIdentityKeys("team-1", "user-1", "", "token-new", "refresh-new")
|
||||
got, matchedKey := index.Find(keys, "user-1")
|
||||
if got == nil || got.ID != legacy.ID {
|
||||
t.Fatalf("Find legacy account without stored user id = %v, want account ID %d", got, legacy.ID)
|
||||
}
|
||||
if matchedKey != "account:team-1" {
|
||||
t.Fatalf("matched key = %q, want account:team-1", matchedKey)
|
||||
}
|
||||
|
||||
// 反向:含 refresh_token 的导入条目无法解析出 user id 时,仍应通过
|
||||
// account 键命中已有账号,保持常规导入去重行为。
|
||||
full := service.Account{
|
||||
ID: 21,
|
||||
Credentials: map[string]any{
|
||||
"chatgpt_account_id": "team-2",
|
||||
"chatgpt_user_id": "user-9",
|
||||
"access_token": "token-old",
|
||||
"refresh_token": "refresh-old",
|
||||
},
|
||||
}
|
||||
index = buildCodexAccountIndex([]service.Account{full})
|
||||
|
||||
keys = buildCodexImportIdentityKeys("team-2", "", "", "token-opaque", "refresh-new")
|
||||
got, _ = index.Find(keys, "")
|
||||
if got == nil || got.ID != full.ID {
|
||||
t.Fatalf("Find by account key without entry user id = %v, want account ID %d", got, full.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCodexAccountIndexAccessTokenOnlyUsesTokenFingerprint(t *testing.T) {
|
||||
existing := service.Account{
|
||||
ID: 22,
|
||||
Credentials: map[string]any{
|
||||
"chatgpt_account_id": "team-1",
|
||||
"chatgpt_user_id": "user-1",
|
||||
"access_token": "token-old",
|
||||
},
|
||||
}
|
||||
index := buildCodexAccountIndex([]service.Account{existing})
|
||||
|
||||
keys := buildCodexImportIdentityKeys("team-1", "user-1", "", "token-new", "")
|
||||
if got, matchedKey := index.Find(keys, "user-1"); got != nil {
|
||||
t.Fatalf("accessToken-only import matched by %q despite different token: account ID %d", matchedKey, got.ID)
|
||||
}
|
||||
|
||||
keys = buildCodexImportIdentityKeys("team-1", "user-1", "", "token-old", "")
|
||||
got, matchedKey := index.Find(keys, "user-1")
|
||||
if got == nil || got.ID != existing.ID {
|
||||
t.Fatalf("Find accessToken-only duplicate by fingerprint = %v, want account ID %d", got, existing.ID)
|
||||
}
|
||||
if !strings.HasPrefix(matchedKey, "access:") {
|
||||
t.Fatalf("matched key = %q, want access fingerprint", matchedKey)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCodexAccountIndexKeepsAllCandidatesForSharedAccountKey(t *testing.T) {
|
||||
legacy := service.Account{
|
||||
ID: 30,
|
||||
Credentials: map[string]any{
|
||||
"chatgpt_account_id": "team-1",
|
||||
"access_token": "token-legacy",
|
||||
"refresh_token": "refresh-legacy",
|
||||
},
|
||||
}
|
||||
member := service.Account{
|
||||
ID: 31,
|
||||
Credentials: map[string]any{
|
||||
"chatgpt_account_id": "team-1",
|
||||
"chatgpt_user_id": "user-2",
|
||||
"access_token": "token-member",
|
||||
"refresh_token": "refresh-member",
|
||||
},
|
||||
}
|
||||
|
||||
// 无论索引构建顺序如何,携带新 user id 的条目都应跳过 user-2 的账号,
|
||||
// 命中缺少 user id 的存量账号,而不是因单一候选被遮蔽而落空。
|
||||
for _, accounts := range [][]service.Account{
|
||||
{member, legacy},
|
||||
{legacy, member},
|
||||
} {
|
||||
index := buildCodexAccountIndex(accounts)
|
||||
|
||||
keys := buildCodexImportIdentityKeys("team-1", "user-1", "", "token-new", "refresh-new")
|
||||
got, matchedKey := index.Find(keys, "user-1")
|
||||
if got == nil || got.ID != legacy.ID {
|
||||
t.Fatalf("Find with shared account key = %v, want legacy account ID %d", got, legacy.ID)
|
||||
}
|
||||
if matchedKey != "account:team-1" {
|
||||
t.Fatalf("matched key = %q, want account:team-1", matchedKey)
|
||||
}
|
||||
|
||||
keys = buildCodexImportIdentityKeys("team-1", "user-2", "", "token-new", "refresh-new")
|
||||
got, matchedKey = index.Find(keys, "user-2")
|
||||
if got == nil || got.ID != member.ID {
|
||||
t.Fatalf("Find by user key = %v, want member account ID %d", got, member.ID)
|
||||
}
|
||||
if matchedKey != "user:user-2" {
|
||||
t.Fatalf("matched key = %q, want user:user-2", matchedKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCodexAccountIndexUpsertReplacesSameAccount(t *testing.T) {
|
||||
legacy := service.Account{
|
||||
ID: 40,
|
||||
Credentials: map[string]any{
|
||||
"chatgpt_account_id": "team-1",
|
||||
"access_token": "token-old",
|
||||
},
|
||||
}
|
||||
index := buildCodexAccountIndex([]service.Account{legacy})
|
||||
|
||||
backfilled := service.Account{
|
||||
ID: 40,
|
||||
Credentials: map[string]any{
|
||||
"chatgpt_account_id": "team-1",
|
||||
"chatgpt_user_id": "user-1",
|
||||
"access_token": "token-new",
|
||||
"refresh_token": "refresh-new",
|
||||
},
|
||||
}
|
||||
index.Add(backfilled)
|
||||
|
||||
// 回填后同一账号在 account 键下应被原位替换而非残留旧副本:
|
||||
// 其他成员的条目不应再通过旧副本(无 user id)命中该账号。
|
||||
keys := buildCodexImportIdentityKeys("team-1", "user-2", "", "token-other", "refresh-other")
|
||||
if got, matchedKey := index.Find(keys, "user-2"); got != nil {
|
||||
t.Fatalf("stale candidate matched after upsert by %q: account ID %d", matchedKey, got.ID)
|
||||
}
|
||||
|
||||
keys = buildCodexImportIdentityKeys("team-1", "user-1", "", "token-other", "refresh-other")
|
||||
got, _ := index.Find(keys, "user-1")
|
||||
if got == nil || got.ID != backfilled.ID {
|
||||
t.Fatalf("Find after upsert = %v, want account ID %d", got, backfilled.ID)
|
||||
}
|
||||
if uid := codexCredentialString(got.Credentials, "chatgpt_user_id"); uid != "user-1" {
|
||||
t.Fatalf("upsert did not replace credentials, chatgpt_user_id = %q", uid)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCodexIdentitySeenDistinguishesTeamMembers(t *testing.T) {
|
||||
seen := map[string]codexSeenIdentity{}
|
||||
member1 := buildCodexImportIdentityKeys("team-1", "user-1", "", "token-1", "refresh-1")
|
||||
markCodexIdentitySeen(seen, member1, 1, "user-1")
|
||||
|
||||
member2 := buildCodexImportIdentityKeys("team-1", "user-2", "", "token-2", "refresh-2")
|
||||
if index, ok := firstSeenCodexIdentity(seen, member2, "user-2"); ok {
|
||||
t.Fatalf("different team member treated as duplicate of entry %d", index)
|
||||
}
|
||||
|
||||
again := buildCodexImportIdentityKeys("team-1", "user-1", "", "token-3", "refresh-3")
|
||||
index, ok := firstSeenCodexIdentity(seen, again, "user-1")
|
||||
if !ok || index != 1 {
|
||||
t.Fatalf("same user re-entry dedup = (%d, %v), want (1, true)", index, ok)
|
||||
}
|
||||
|
||||
// 无 user id 的条目不应因共享 account id 与已见团队成员互相去重;
|
||||
// 只有相同 access token 指纹才视为重复。
|
||||
opaque := buildCodexImportIdentityKeys("team-1", "", "", "token-4", "")
|
||||
index, ok = firstSeenCodexIdentity(seen, opaque, "")
|
||||
if ok {
|
||||
t.Fatalf("entry without user id dedup = (%d, %v), want no match", index, ok)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNormalizeCodexImportUsesJWTSubForAccessTokenOnlyIdentity(t *testing.T) {
|
||||
accessToken := buildCodexImportTestJWT(t, time.Now().Add(time.Hour), map[string]any{
|
||||
"sub": "user-from-access-token",
|
||||
"https://api.openai.com/auth": map[string]any{
|
||||
"chatgpt_account_id": "workspace-1",
|
||||
},
|
||||
})
|
||||
|
||||
item, err := normalizeCodexImportEntry(codexImportEntry{Index: 1, Value: accessToken})
|
||||
if err != nil {
|
||||
t.Fatalf("normalizeCodexImportEntry error = %v", err)
|
||||
}
|
||||
if item.UserID != "user-from-access-token" {
|
||||
t.Fatalf("UserID = %q, want JWT sub", item.UserID)
|
||||
}
|
||||
if len(item.IdentityKeys) != 1 || !strings.HasPrefix(item.IdentityKeys[0], "access:") {
|
||||
t.Fatalf("IdentityKeys = %v, want access fingerprint only for accessToken-only import", item.IdentityKeys)
|
||||
}
|
||||
if got := item.Credentials["chatgpt_user_id"]; got != "user-from-access-token" {
|
||||
t.Fatalf("credential chatgpt_user_id = %v, want JWT sub", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestImportCodexSessionsAccessTokenOnlySameWorkspaceDifferentUsersCreatesTwoAccounts(t *testing.T) {
|
||||
svc := newCodexImportMemoryAdminService(nil)
|
||||
handler := NewAccountHandler(svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
|
||||
req := CodexSessionImportRequest{SkipDefaultGroupBind: boolPtr(true)}
|
||||
entries := []codexImportEntry{
|
||||
{Index: 1, Value: buildCodexAccessOnlyImportValue(t, "workspace-1", "user-1")},
|
||||
{Index: 2, Value: buildCodexAccessOnlyImportValue(t, "workspace-1", "user-2")},
|
||||
}
|
||||
|
||||
result, err := handler.importCodexSessions(context.Background(), req, entries)
|
||||
if err != nil {
|
||||
t.Fatalf("importCodexSessions error = %v", err)
|
||||
}
|
||||
if result.Created != 2 || result.Updated != 0 || result.Skipped != 0 || result.Failed != 0 {
|
||||
t.Fatalf("result = %+v, want two created accounts", result)
|
||||
}
|
||||
if len(svc.createdAccounts) != 2 {
|
||||
t.Fatalf("created accounts = %d, want 2", len(svc.createdAccounts))
|
||||
}
|
||||
if svc.createdAccounts[0].Credentials["chatgpt_user_id"] == svc.createdAccounts[1].Credentials["chatgpt_user_id"] {
|
||||
t.Fatalf("created accounts share user id: %v", svc.createdAccounts)
|
||||
}
|
||||
}
|
||||
|
||||
func TestImportCodexSessionsAccessTokenOnlySameWorkspaceAndUserDifferentTokensCreatesTwoAccounts(t *testing.T) {
|
||||
svc := newCodexImportMemoryAdminService(nil)
|
||||
handler := NewAccountHandler(svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
|
||||
req := CodexSessionImportRequest{SkipDefaultGroupBind: boolPtr(true)}
|
||||
entries := []codexImportEntry{
|
||||
{Index: 1, Value: map[string]any{
|
||||
"access_token": buildCodexImportTestJWT(t, time.Now().Add(time.Hour), map[string]any{
|
||||
"sub": "shared-user",
|
||||
"jti": "token-1",
|
||||
"https://api.openai.com/auth": map[string]any{
|
||||
"chatgpt_account_id": "workspace-1",
|
||||
},
|
||||
}),
|
||||
}},
|
||||
{Index: 2, Value: map[string]any{
|
||||
"access_token": buildCodexImportTestJWT(t, time.Now().Add(time.Hour), map[string]any{
|
||||
"sub": "shared-user",
|
||||
"jti": "token-2",
|
||||
"https://api.openai.com/auth": map[string]any{
|
||||
"chatgpt_account_id": "workspace-1",
|
||||
},
|
||||
}),
|
||||
}},
|
||||
}
|
||||
|
||||
result, err := handler.importCodexSessions(context.Background(), req, entries)
|
||||
if err != nil {
|
||||
t.Fatalf("importCodexSessions error = %v", err)
|
||||
}
|
||||
if result.Created != 2 || result.Updated != 0 || result.Skipped != 0 || result.Failed != 0 {
|
||||
t.Fatalf("result = %+v, want two created accounts", result)
|
||||
}
|
||||
if len(svc.createdAccounts) != 2 {
|
||||
t.Fatalf("created accounts = %d, want 2", len(svc.createdAccounts))
|
||||
}
|
||||
}
|
||||
|
||||
func TestImportCodexSessionsAccessTokenOnlySameUserUpdatesExisting(t *testing.T) {
|
||||
existingToken := buildCodexAccessToken(t, "workspace-1", "user-1", time.Now().Add(time.Hour))
|
||||
svc := newCodexImportMemoryAdminService([]service.Account{{
|
||||
ID: 10,
|
||||
Name: "existing",
|
||||
Platform: service.PlatformOpenAI,
|
||||
Type: service.AccountTypeOAuth,
|
||||
Credentials: map[string]any{
|
||||
"chatgpt_account_id": "workspace-1",
|
||||
"chatgpt_user_id": "user-1",
|
||||
"access_token": existingToken,
|
||||
},
|
||||
Extra: map[string]any{"openai_long_context_billing_enabled": false},
|
||||
}})
|
||||
handler := NewAccountHandler(svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
|
||||
req := CodexSessionImportRequest{SkipDefaultGroupBind: boolPtr(true)}
|
||||
entries := []codexImportEntry{
|
||||
{Index: 1, Value: map[string]any{"access_token": existingToken}},
|
||||
}
|
||||
|
||||
result, err := handler.importCodexSessions(context.Background(), req, entries)
|
||||
if err != nil {
|
||||
t.Fatalf("importCodexSessions error = %v", err)
|
||||
}
|
||||
if result.Created != 0 || result.Updated != 1 || result.Failed != 0 {
|
||||
t.Fatalf("result = %+v, want one updated account", result)
|
||||
}
|
||||
if len(svc.createdAccounts) != 0 {
|
||||
t.Fatalf("created accounts = %d, want 0", len(svc.createdAccounts))
|
||||
}
|
||||
if len(svc.updatedAccounts) != 1 || svc.updatedAccounts[0].id != 10 {
|
||||
t.Fatalf("updated accounts = %+v, want account 10", svc.updatedAccounts)
|
||||
}
|
||||
if got := svc.updatedAccounts[0].input.Extra["openai_long_context_billing_enabled"]; got != false {
|
||||
t.Fatalf("openai_long_context_billing_enabled = %v, want false", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestImportCodexSessionsUpgradesAccessTokenOnlyAccountWithRefreshToken(t *testing.T) {
|
||||
oldToken := buildCodexAccessTokenWithJTI(t, "workspace-1", "user-1", "old-token", time.Now().Add(time.Hour))
|
||||
newToken := buildCodexAccessTokenWithJTI(t, "workspace-1", "user-1", "new-token", time.Now().Add(time.Hour))
|
||||
svc := newCodexImportMemoryAdminService([]service.Account{{
|
||||
ID: 12,
|
||||
Name: "existing",
|
||||
Platform: service.PlatformOpenAI,
|
||||
Type: service.AccountTypeOAuth,
|
||||
Credentials: map[string]any{
|
||||
"chatgpt_account_id": "workspace-1",
|
||||
"chatgpt_user_id": "user-1",
|
||||
"access_token": oldToken,
|
||||
},
|
||||
}})
|
||||
handler := NewAccountHandler(svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
|
||||
req := CodexSessionImportRequest{SkipDefaultGroupBind: boolPtr(true)}
|
||||
entries := []codexImportEntry{
|
||||
{Index: 1, Value: map[string]any{
|
||||
"access_token": newToken,
|
||||
"refresh_token": "refresh-new",
|
||||
}},
|
||||
}
|
||||
|
||||
result, err := handler.importCodexSessions(context.Background(), req, entries)
|
||||
if err != nil {
|
||||
t.Fatalf("importCodexSessions error = %v", err)
|
||||
}
|
||||
if result.Created != 0 || result.Updated != 1 || result.Failed != 0 {
|
||||
t.Fatalf("result = %+v, want one updated account", result)
|
||||
}
|
||||
if len(svc.updatedAccounts) != 1 || svc.updatedAccounts[0].id != 12 {
|
||||
t.Fatalf("updated accounts = %+v, want account 12", svc.updatedAccounts)
|
||||
}
|
||||
if got := svc.updatedAccounts[0].input.Credentials["refresh_token"]; got != "refresh-new" {
|
||||
t.Fatalf("updated refresh_token = %v, want refresh-new", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestImportCodexSessionsAccessTokenOnlyPreservesExistingRefreshToken(t *testing.T) {
|
||||
existingToken := buildCodexAccessToken(t, "workspace-1", "user-1", time.Now().Add(time.Hour))
|
||||
svc := newCodexImportMemoryAdminService([]service.Account{{
|
||||
ID: 13,
|
||||
Name: "existing",
|
||||
Platform: service.PlatformOpenAI,
|
||||
Type: service.AccountTypeOAuth,
|
||||
Credentials: map[string]any{
|
||||
"chatgpt_account_id": "workspace-1",
|
||||
"chatgpt_user_id": "user-1",
|
||||
"access_token": existingToken,
|
||||
"refresh_token": "refresh-old",
|
||||
"client_id": "client-old",
|
||||
},
|
||||
}})
|
||||
handler := NewAccountHandler(svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
|
||||
req := CodexSessionImportRequest{SkipDefaultGroupBind: boolPtr(true)}
|
||||
entries := []codexImportEntry{
|
||||
{Index: 1, Value: map[string]any{"access_token": existingToken}},
|
||||
}
|
||||
|
||||
result, err := handler.importCodexSessions(context.Background(), req, entries)
|
||||
if err != nil {
|
||||
t.Fatalf("importCodexSessions error = %v", err)
|
||||
}
|
||||
if result.Created != 0 || result.Updated != 1 || result.Failed != 0 {
|
||||
t.Fatalf("result = %+v, want one updated account", result)
|
||||
}
|
||||
update := svc.updatedAccounts[0].input
|
||||
if got := update.Credentials["refresh_token"]; got != "refresh-old" {
|
||||
t.Fatalf("refresh_token = %v, want refresh-old", got)
|
||||
}
|
||||
if got := update.Credentials["client_id"]; got != "client-old" {
|
||||
t.Fatalf("client_id = %v, want client-old", got)
|
||||
}
|
||||
if update.ExpiresAt != nil {
|
||||
t.Fatalf("ExpiresAt = %v, want nil to preserve OAuth account expiry", *update.ExpiresAt)
|
||||
}
|
||||
if update.AutoPauseOnExpired != nil {
|
||||
t.Fatalf("AutoPauseOnExpired = %v, want nil to preserve OAuth account scheduling", *update.AutoPauseOnExpired)
|
||||
}
|
||||
}
|
||||
|
||||
func TestImportCodexSessionsBatchOldAccessTokenDoesNotRollbackRefreshToken(t *testing.T) {
|
||||
oldToken := buildCodexAccessTokenWithJTI(t, "workspace-1", "user-1", "old-token", time.Now().Add(time.Hour))
|
||||
newToken := buildCodexAccessTokenWithJTI(t, "workspace-1", "user-1", "new-token", time.Now().Add(time.Hour))
|
||||
svc := newCodexImportMemoryAdminService([]service.Account{{
|
||||
ID: 14,
|
||||
Name: "existing",
|
||||
Platform: service.PlatformOpenAI,
|
||||
Type: service.AccountTypeOAuth,
|
||||
Credentials: map[string]any{
|
||||
"chatgpt_account_id": "workspace-1",
|
||||
"chatgpt_user_id": "user-1",
|
||||
"access_token": oldToken,
|
||||
"refresh_token": "refresh-old",
|
||||
},
|
||||
}})
|
||||
handler := NewAccountHandler(svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
|
||||
req := CodexSessionImportRequest{SkipDefaultGroupBind: boolPtr(true)}
|
||||
entries := []codexImportEntry{
|
||||
{Index: 1, Value: map[string]any{
|
||||
"access_token": newToken,
|
||||
"refresh_token": "refresh-new",
|
||||
}},
|
||||
{Index: 2, Value: map[string]any{"access_token": oldToken}},
|
||||
}
|
||||
|
||||
result, err := handler.importCodexSessions(context.Background(), req, entries)
|
||||
if err != nil {
|
||||
t.Fatalf("importCodexSessions error = %v", err)
|
||||
}
|
||||
if result.Updated != 1 || result.Created != 1 || result.Failed != 0 {
|
||||
t.Fatalf("result = %+v, want first item updated and stale access token created separately", result)
|
||||
}
|
||||
if len(svc.updatedAccounts) != 1 || svc.updatedAccounts[0].id != 14 {
|
||||
t.Fatalf("updated accounts = %+v, want account 14 updated once", svc.updatedAccounts)
|
||||
}
|
||||
stored, err := svc.GetAccount(context.Background(), 14)
|
||||
if err != nil {
|
||||
t.Fatalf("GetAccount error = %v", err)
|
||||
}
|
||||
if got := stored.Credentials["access_token"]; got != newToken {
|
||||
t.Fatalf("stored access_token rolled back = %v, want new token", got)
|
||||
}
|
||||
if got := stored.Credentials["refresh_token"]; got != "refresh-new" {
|
||||
t.Fatalf("stored refresh_token = %v, want refresh-new", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestImportCodexSessionsWithRefreshTokenKeepsExistingDedup(t *testing.T) {
|
||||
existingToken := buildCodexAccessToken(t, "workspace-1", "user-1", time.Now().Add(time.Hour))
|
||||
svc := newCodexImportMemoryAdminService([]service.Account{{
|
||||
ID: 11,
|
||||
Name: "existing",
|
||||
Platform: service.PlatformOpenAI,
|
||||
Type: service.AccountTypeOAuth,
|
||||
Credentials: map[string]any{
|
||||
"chatgpt_account_id": "workspace-1",
|
||||
"chatgpt_user_id": "user-1",
|
||||
"access_token": existingToken,
|
||||
"refresh_token": "refresh-old",
|
||||
},
|
||||
}})
|
||||
handler := NewAccountHandler(svc, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
|
||||
req := CodexSessionImportRequest{SkipDefaultGroupBind: boolPtr(true)}
|
||||
entries := []codexImportEntry{
|
||||
{Index: 1, Value: buildCodexRefreshImportValue(t, "workspace-1", "user-1", "refresh-new")},
|
||||
}
|
||||
|
||||
result, err := handler.importCodexSessions(context.Background(), req, entries)
|
||||
if err != nil {
|
||||
t.Fatalf("importCodexSessions error = %v", err)
|
||||
}
|
||||
if result.Created != 0 || result.Updated != 1 || result.Failed != 0 {
|
||||
t.Fatalf("result = %+v, want one updated account", result)
|
||||
}
|
||||
if got := svc.updatedAccounts[0].input.Credentials["refresh_token"]; got != "refresh-new" {
|
||||
t.Fatalf("updated refresh_token = %v, want refresh-new", got)
|
||||
}
|
||||
}
|
||||
|
||||
type codexImportMemoryAdminService struct {
|
||||
*stubAdminService
|
||||
nextID int64
|
||||
updatedAccounts []struct {
|
||||
id int64
|
||||
input *service.UpdateAccountInput
|
||||
}
|
||||
}
|
||||
|
||||
func newCodexImportMemoryAdminService(accounts []service.Account) *codexImportMemoryAdminService {
|
||||
stub := newStubAdminService()
|
||||
stub.accounts = append([]service.Account(nil), accounts...)
|
||||
return &codexImportMemoryAdminService{
|
||||
stubAdminService: stub,
|
||||
nextID: 100,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *codexImportMemoryAdminService) CreateAccount(ctx context.Context, input *service.CreateAccountInput) (*service.Account, error) {
|
||||
s.createdAccounts = append(s.createdAccounts, input)
|
||||
if s.createAccountErr != nil {
|
||||
return nil, s.createAccountErr
|
||||
}
|
||||
account := service.Account{
|
||||
ID: s.nextID,
|
||||
Name: input.Name,
|
||||
Platform: input.Platform,
|
||||
Type: input.Type,
|
||||
Status: service.StatusActive,
|
||||
Credentials: cloneCodexImportTestMap(input.Credentials),
|
||||
Extra: cloneCodexImportTestMap(input.Extra),
|
||||
}
|
||||
s.nextID++
|
||||
s.accounts = append(s.accounts, account)
|
||||
return &account, nil
|
||||
}
|
||||
|
||||
func (s *codexImportMemoryAdminService) UpdateAccount(ctx context.Context, id int64, input *service.UpdateAccountInput) (*service.Account, error) {
|
||||
s.updatedAccounts = append(s.updatedAccounts, struct {
|
||||
id int64
|
||||
input *service.UpdateAccountInput
|
||||
}{id: id, input: input})
|
||||
if s.updateAccountErr != nil {
|
||||
return nil, s.updateAccountErr
|
||||
}
|
||||
for idx := range s.accounts {
|
||||
if s.accounts[idx].ID == id {
|
||||
s.accounts[idx].Credentials = cloneCodexImportTestMap(input.Credentials)
|
||||
s.accounts[idx].Extra = cloneCodexImportTestMap(input.Extra)
|
||||
return &s.accounts[idx], nil
|
||||
}
|
||||
}
|
||||
account := service.Account{ID: id, Status: service.StatusActive, Credentials: cloneCodexImportTestMap(input.Credentials)}
|
||||
return &account, nil
|
||||
}
|
||||
|
||||
func (s *codexImportMemoryAdminService) GetAccount(ctx context.Context, id int64) (*service.Account, error) {
|
||||
for idx := range s.accounts {
|
||||
if s.accounts[idx].ID == id {
|
||||
return &s.accounts[idx], nil
|
||||
}
|
||||
}
|
||||
return s.stubAdminService.GetAccount(ctx, id)
|
||||
}
|
||||
|
||||
func buildCodexAccessOnlyImportValue(t *testing.T, accountID, userID string) map[string]any {
|
||||
t.Helper()
|
||||
return map[string]any{
|
||||
"access_token": buildCodexAccessToken(t, accountID, userID, time.Now().Add(time.Hour)),
|
||||
}
|
||||
}
|
||||
|
||||
func buildCodexRefreshImportValue(t *testing.T, accountID, userID, refreshToken string) map[string]any {
|
||||
t.Helper()
|
||||
return map[string]any{
|
||||
"access_token": buildCodexAccessToken(t, accountID, userID, time.Now().Add(time.Hour)),
|
||||
"refresh_token": refreshToken,
|
||||
}
|
||||
}
|
||||
|
||||
func buildCodexAccessToken(t *testing.T, accountID, userID string, exp time.Time) string {
|
||||
t.Helper()
|
||||
return buildCodexAccessTokenWithJTI(t, accountID, userID, "", exp)
|
||||
}
|
||||
|
||||
func buildCodexAccessTokenWithJTI(t *testing.T, accountID, userID, jti string, exp time.Time) string {
|
||||
t.Helper()
|
||||
claims := map[string]any{
|
||||
"sub": userID,
|
||||
"https://api.openai.com/auth": map[string]any{
|
||||
"chatgpt_account_id": accountID,
|
||||
},
|
||||
}
|
||||
if jti != "" {
|
||||
claims["jti"] = jti
|
||||
}
|
||||
return buildCodexImportTestJWT(t, exp, claims)
|
||||
}
|
||||
|
||||
func cloneCodexImportTestMap(input map[string]any) map[string]any {
|
||||
if input == nil {
|
||||
return nil
|
||||
}
|
||||
out := make(map[string]any, len(input))
|
||||
for key, value := range input {
|
||||
out[key] = value
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func boolPtr(v bool) *bool {
|
||||
return &v
|
||||
}
|
||||
|
||||
func buildCodexImportTestJWT(t *testing.T, exp time.Time, extraClaims map[string]any) string {
|
||||
|
||||
@@ -30,6 +30,9 @@ type DataPayload struct {
|
||||
ExportedAt string `json:"exported_at"`
|
||||
Proxies []DataProxy `json:"proxies"`
|
||||
Accounts []DataAccount `json:"accounts"`
|
||||
// SkippedShadows 记录导出时被排除的 spark 影子账号数量(见 ExportData)。仅作可见性提示,
|
||||
// 导入侧忽略该字段;omitempty 保持向后兼容。
|
||||
SkippedShadows int `json:"skipped_shadows,omitempty"`
|
||||
}
|
||||
|
||||
type DataProxy struct {
|
||||
@@ -50,6 +53,10 @@ type DataProxy struct {
|
||||
// DataAccount 是管理员显式备份导出使用的账号结构,故意不走 dto.Account 的脱敏路径,
|
||||
// Credentials 原文返回。这是"管理员备份"这一显式行为的一部分;如未来需要导出脱敏版本,
|
||||
// 应新增独立结构而非修改这里。
|
||||
// 注意:本结构不含 parent_account_id/quota_dimension——spark 影子账号在 ExportData 处被显式
|
||||
// 排除(影子不持凭据、通用凭据型导入强制 credentials 非空无法重建父子链接),不在此表达。
|
||||
// 影子的独立调度配置(priority/并发/分组/status 管理员可单独调)亦不在本备份范围,属已知局限
|
||||
// (外审第6轮裁决:保持排除 + 前端警告,而非升级格式做完整往返)。
|
||||
type DataAccount struct {
|
||||
Name string `json:"name"`
|
||||
Notes *string `json:"notes,omitempty"`
|
||||
@@ -105,6 +112,24 @@ func (h *AccountHandler) ExportData(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 排除 spark 影子账号:影子不持凭据,通用凭据型导出无法表达父子链接、导入侧又强制 credentials
|
||||
// 非空——若混入会产出无法还原的坏备份(导入即失败)。影子的独立调度配置(priority/并发/分组/
|
||||
// status,管理员可单独调)随之不进备份,还原后需在重建的影子上重新调优;前端按 skipped_shadows
|
||||
// 提示用户(外审第5轮发现、第6轮裁决:保持排除 + 警告,不做完整往返)。
|
||||
skippedShadows := 0
|
||||
exportable := make([]service.Account, 0, len(accounts))
|
||||
for i := range accounts {
|
||||
if accounts[i].IsCredentialShadow() {
|
||||
skippedShadows++
|
||||
continue
|
||||
}
|
||||
exportable = append(exportable, accounts[i])
|
||||
}
|
||||
accounts = exportable
|
||||
if skippedShadows > 0 {
|
||||
slog.Info("export_skipped_spark_shadows", "count", skippedShadows)
|
||||
}
|
||||
|
||||
includeProxies, err := parseIncludeProxies(c)
|
||||
if err != nil {
|
||||
response.BadRequest(c, err.Error())
|
||||
@@ -191,9 +216,10 @@ func (h *AccountHandler) ExportData(c *gin.Context) {
|
||||
}
|
||||
|
||||
payload := DataPayload{
|
||||
ExportedAt: time.Now().UTC().Format(time.RFC3339),
|
||||
Proxies: dataProxies,
|
||||
Accounts: dataAccounts,
|
||||
ExportedAt: time.Now().UTC().Format(time.RFC3339),
|
||||
Proxies: dataProxies,
|
||||
Accounts: dataAccounts,
|
||||
SkippedShadows: skippedShadows,
|
||||
}
|
||||
|
||||
response.Success(c, payload)
|
||||
@@ -434,6 +460,7 @@ func (h *AccountHandler) importData(ctx context.Context, req DataImportRequest)
|
||||
if created.Platform == service.PlatformAntigravity && created.Type == service.AccountTypeOAuth {
|
||||
privacyAccounts = append(privacyAccounts, created)
|
||||
}
|
||||
h.scheduleGrokImportProbe(created)
|
||||
result.AccountCreated++
|
||||
}
|
||||
|
||||
|
||||
@@ -18,10 +18,11 @@ type dataResponse struct {
|
||||
}
|
||||
|
||||
type dataPayload struct {
|
||||
Type string `json:"type"`
|
||||
Version int `json:"version"`
|
||||
Proxies []dataProxy `json:"proxies"`
|
||||
Accounts []dataAccount `json:"accounts"`
|
||||
Type string `json:"type"`
|
||||
Version int `json:"version"`
|
||||
Proxies []dataProxy `json:"proxies"`
|
||||
Accounts []dataAccount `json:"accounts"`
|
||||
SkippedShadows int `json:"skipped_shadows"`
|
||||
}
|
||||
|
||||
type dataProxy struct {
|
||||
@@ -172,6 +173,46 @@ func TestExportDataWithoutProxies(t *testing.T) {
|
||||
require.Nil(t, resp.Data.Accounts[0].ProxyKey)
|
||||
}
|
||||
|
||||
// TestExportDataExcludesSparkShadow 验证外审第5轮 P1/P2:导出时排除 spark 影子账号
|
||||
// (影子无凭据、导入侧强制 credentials 非空,混入会产出无法还原的坏备份),并透出跳过计数。
|
||||
func TestExportDataExcludesSparkShadow(t *testing.T) {
|
||||
router, adminSvc := setupAccountDataRouter()
|
||||
|
||||
parentID := int64(21)
|
||||
adminSvc.accounts = []service.Account{
|
||||
{
|
||||
ID: parentID,
|
||||
Name: "mother",
|
||||
Platform: service.PlatformOpenAI,
|
||||
Type: service.AccountTypeOAuth,
|
||||
Credentials: map[string]any{"token": "secret"},
|
||||
Status: service.StatusActive,
|
||||
},
|
||||
{
|
||||
ID: 22,
|
||||
Name: "mother (Spark)",
|
||||
Platform: service.PlatformOpenAI,
|
||||
Type: service.AccountTypeOAuth,
|
||||
Credentials: map[string]any{}, // 影子恒空凭据
|
||||
ParentAccountID: &parentID, // 影子标记
|
||||
QuotaDimension: service.QuotaDimensionSpark,
|
||||
Status: service.StatusActive,
|
||||
},
|
||||
}
|
||||
|
||||
rec := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/v1/admin/accounts/data?include_proxies=false", nil)
|
||||
router.ServeHTTP(rec, req)
|
||||
require.Equal(t, http.StatusOK, rec.Code)
|
||||
|
||||
var resp dataResponse
|
||||
require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &resp))
|
||||
require.Equal(t, 0, resp.Code)
|
||||
require.Len(t, resp.Data.Accounts, 1, "影子应被排除,仅导出母账号")
|
||||
require.Equal(t, "mother", resp.Data.Accounts[0].Name)
|
||||
require.Equal(t, 1, resp.Data.SkippedShadows, "跳过的影子数量应透出")
|
||||
}
|
||||
|
||||
func TestExportDataPassesAccountFiltersAndSort(t *testing.T) {
|
||||
router, adminSvc := setupAccountDataRouter()
|
||||
adminSvc.accounts = []service.Account{
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"log"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -25,6 +26,7 @@ import (
|
||||
"github.com/Wei-Shaw/sub2api/internal/pkg/openai"
|
||||
"github.com/Wei-Shaw/sub2api/internal/pkg/response"
|
||||
"github.com/Wei-Shaw/sub2api/internal/pkg/timezone"
|
||||
"github.com/Wei-Shaw/sub2api/internal/pkg/xai"
|
||||
"github.com/Wei-Shaw/sub2api/internal/service"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -58,6 +60,7 @@ type AccountHandler struct {
|
||||
sessionLimitCache service.SessionLimitCache
|
||||
rpmCache service.RPMCache
|
||||
tokenCacheInvalidator service.TokenCacheInvalidator
|
||||
grokImportProber grokUsageProber
|
||||
}
|
||||
|
||||
// NewAccountHandler creates a new admin account handler
|
||||
@@ -169,13 +172,29 @@ type CheckMixedChannelRequest struct {
|
||||
// AccountWithConcurrency extends Account with real-time concurrency info
|
||||
type AccountWithConcurrency struct {
|
||||
*dto.Account
|
||||
CurrentConcurrency int `json:"current_concurrency"`
|
||||
CurrentConcurrency int `json:"current_concurrency"`
|
||||
SchedulerScore *AccountSchedulerScore `json:"scheduler_score,omitempty"`
|
||||
SchedulerScores []AccountSchedulerGroupScore `json:"scheduler_scores,omitempty"`
|
||||
// 以下字段仅对 Anthropic OAuth/SetupToken 账号有效,且仅在启用相应功能时返回
|
||||
CurrentWindowCost *float64 `json:"current_window_cost,omitempty"` // 当前窗口费用
|
||||
ActiveSessions *int `json:"active_sessions,omitempty"` // 当前活跃会话数
|
||||
CurrentRPM *int `json:"current_rpm,omitempty"` // 当前分钟 RPM 计数
|
||||
}
|
||||
|
||||
type AccountSchedulerScore struct {
|
||||
BaseScore float64 `json:"base_score"`
|
||||
StickyScore float64 `json:"sticky_score"`
|
||||
StickyScoreInfinity bool `json:"sticky_score_infinity"`
|
||||
StickyWeightedEnabled bool `json:"sticky_weighted_enabled"`
|
||||
}
|
||||
|
||||
type AccountSchedulerGroupScore struct {
|
||||
GroupID *int64 `json:"group_id"`
|
||||
GroupName string `json:"group_name,omitempty"`
|
||||
GroupPriority *int `json:"group_priority,omitempty"`
|
||||
AccountSchedulerScore
|
||||
}
|
||||
|
||||
const accountListGroupUngroupedQueryValue = "ungrouped"
|
||||
|
||||
func (h *AccountHandler) buildAccountResponseWithRuntime(ctx context.Context, account *service.Account) AccountWithConcurrency {
|
||||
@@ -219,9 +238,237 @@ func (h *AccountHandler) buildAccountResponseWithRuntime(ctx context.Context, ac
|
||||
}
|
||||
}
|
||||
|
||||
h.enrichShadowParents(ctx, []AccountWithConcurrency{item})
|
||||
|
||||
return item
|
||||
}
|
||||
|
||||
// scoreOpenAIAccountSchedulerPool 对池内 OpenAI 账号计算调度分数快照。
|
||||
// loadMap 为共享的账号负载数据(含池内全部账号即可,多余条目无害);传 nil 时自行批查。
|
||||
func (h *AccountHandler) scoreOpenAIAccountSchedulerPool(ctx context.Context, accounts []service.Account, loadMap map[int64]*service.AccountLoadInfo) map[int64]AccountSchedulerScore {
|
||||
if len(accounts) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
openAIAccounts := make([]*service.Account, 0, len(accounts))
|
||||
for i := range accounts {
|
||||
account := &accounts[i]
|
||||
if account.Platform != service.PlatformOpenAI {
|
||||
continue
|
||||
}
|
||||
openAIAccounts = append(openAIAccounts, account)
|
||||
}
|
||||
if len(openAIAccounts) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if loadMap == nil {
|
||||
loadMap = h.fetchOpenAIAccountLoadMap(ctx, openAIAccounts)
|
||||
}
|
||||
|
||||
var scores map[int64]service.OpenAIAccountSchedulerScoreSnapshot
|
||||
if h.rateLimitService != nil {
|
||||
scores = h.rateLimitService.BuildOpenAIAccountSchedulerScoreSnapshot(ctx, openAIAccounts, loadMap)
|
||||
} else {
|
||||
scores = service.BuildOpenAIAccountSchedulerScoreSnapshot(openAIAccounts, loadMap)
|
||||
}
|
||||
result := make(map[int64]AccountSchedulerScore, len(scores))
|
||||
for accountID, score := range scores {
|
||||
result[accountID] = AccountSchedulerScore{
|
||||
BaseScore: score.BaseScore,
|
||||
StickyScore: score.StickyScore,
|
||||
StickyScoreInfinity: score.StickyScoreInfinity,
|
||||
StickyWeightedEnabled: score.StickyWeightedEnabled,
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// fetchOpenAIAccountLoadMap 一次性批查给定 OpenAI 账号的负载数据;
|
||||
// 失败时记录日志并返回空表(分数按零负载计算,属可接受降级)。
|
||||
func (h *AccountHandler) fetchOpenAIAccountLoadMap(ctx context.Context, openAIAccounts []*service.Account) map[int64]*service.AccountLoadInfo {
|
||||
loadMap := map[int64]*service.AccountLoadInfo{}
|
||||
if h.concurrencyService == nil || len(openAIAccounts) == 0 {
|
||||
return loadMap
|
||||
}
|
||||
seen := make(map[int64]struct{}, len(openAIAccounts))
|
||||
loadReq := make([]service.AccountWithConcurrency, 0, len(openAIAccounts))
|
||||
for _, account := range openAIAccounts {
|
||||
if account == nil {
|
||||
continue
|
||||
}
|
||||
if _, ok := seen[account.ID]; ok {
|
||||
continue
|
||||
}
|
||||
seen[account.ID] = struct{}{}
|
||||
loadReq = append(loadReq, service.AccountWithConcurrency{
|
||||
ID: account.ID,
|
||||
MaxConcurrency: account.EffectiveLoadFactor(),
|
||||
})
|
||||
}
|
||||
if batchLoad, err := h.concurrencyService.GetAccountsLoadBatch(ctx, loadReq); err != nil {
|
||||
slog.Warn("openai_scheduler_score_load_batch_failed", "error", err)
|
||||
} else if batchLoad != nil {
|
||||
loadMap = batchLoad
|
||||
}
|
||||
return loadMap
|
||||
}
|
||||
|
||||
func (h *AccountHandler) buildOpenAIAccountSchedulerScores(
|
||||
ctx context.Context,
|
||||
accounts []service.Account,
|
||||
filterPool []service.Account,
|
||||
) (map[int64]*AccountSchedulerScore, map[int64][]AccountSchedulerGroupScore) {
|
||||
if len(accounts) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
if len(filterPool) == 0 {
|
||||
filterPool = accounts
|
||||
}
|
||||
|
||||
pageOpenAIAccountIDs := make(map[int64]struct{})
|
||||
groupIDs := make(map[int64]struct{})
|
||||
for i := range accounts {
|
||||
account := &accounts[i]
|
||||
if account.Platform != service.PlatformOpenAI {
|
||||
continue
|
||||
}
|
||||
pageOpenAIAccountIDs[account.ID] = struct{}{}
|
||||
if len(account.AccountGroups) == 0 && len(account.GroupIDs) == 0 {
|
||||
continue
|
||||
}
|
||||
for _, accountGroup := range account.AccountGroups {
|
||||
if accountGroup.GroupID > 0 {
|
||||
groupIDs[accountGroup.GroupID] = struct{}{}
|
||||
}
|
||||
}
|
||||
for _, groupID := range account.GroupIDs {
|
||||
if groupID > 0 {
|
||||
groupIDs[groupID] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(pageOpenAIAccountIDs) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// 先取各分组池,再对"过滤池 ∪ 分组池"的账号并集做一次负载批查,
|
||||
// 避免每个池各查一次 Redis 的 N+1。
|
||||
groupIDList := make([]int64, 0, len(groupIDs))
|
||||
for groupID := range groupIDs {
|
||||
groupIDList = append(groupIDList, groupID)
|
||||
}
|
||||
sort.Slice(groupIDList, func(i, j int) bool { return groupIDList[i] < groupIDList[j] })
|
||||
|
||||
groupPools := make(map[int64][]service.Account, len(groupIDList))
|
||||
if h.adminService != nil {
|
||||
for _, groupID := range groupIDList {
|
||||
gid := groupID
|
||||
pool, err := h.adminService.ListOpenAISchedulableAccountsForSchedulerScore(ctx, &gid)
|
||||
if err != nil {
|
||||
slog.Warn("openai_scheduler_group_score_pool_failed", "group_id", gid, "error", err)
|
||||
continue
|
||||
}
|
||||
groupPools[gid] = pool
|
||||
}
|
||||
}
|
||||
|
||||
loadUnion := make([]*service.Account, 0, len(filterPool))
|
||||
collectOpenAIAccounts := func(pool []service.Account) {
|
||||
for i := range pool {
|
||||
if pool[i].Platform == service.PlatformOpenAI {
|
||||
loadUnion = append(loadUnion, &pool[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
collectOpenAIAccounts(filterPool)
|
||||
for _, pool := range groupPools {
|
||||
collectOpenAIAccounts(pool)
|
||||
}
|
||||
loadMap := h.fetchOpenAIAccountLoadMap(ctx, loadUnion)
|
||||
|
||||
baseScores := make(map[int64]*AccountSchedulerScore)
|
||||
for accountID, score := range h.scoreOpenAIAccountSchedulerPool(ctx, filterPool, loadMap) {
|
||||
copiedScore := score
|
||||
baseScores[accountID] = &copiedScore
|
||||
}
|
||||
|
||||
groupScoresByAccount := make(map[int64][]AccountSchedulerGroupScore)
|
||||
scoreGroupPool := func(groupID *int64, groupNameByID map[int64]string, groupPriorityByAccount map[int64]int, pool []service.Account) {
|
||||
if len(pool) == 0 {
|
||||
return
|
||||
}
|
||||
scores := h.scoreOpenAIAccountSchedulerPool(ctx, pool, loadMap)
|
||||
for accountID, schedulerScore := range scores {
|
||||
if _, ok := pageOpenAIAccountIDs[accountID]; !ok {
|
||||
continue
|
||||
}
|
||||
groupScore := AccountSchedulerGroupScore{
|
||||
GroupID: groupID,
|
||||
AccountSchedulerScore: schedulerScore,
|
||||
}
|
||||
if groupID != nil {
|
||||
groupScore.GroupName = groupNameByID[*groupID]
|
||||
if priority, ok := groupPriorityByAccount[accountID]; ok {
|
||||
groupScore.GroupPriority = &priority
|
||||
}
|
||||
}
|
||||
groupScoresByAccount[accountID] = append(groupScoresByAccount[accountID], groupScore)
|
||||
}
|
||||
}
|
||||
|
||||
for _, groupID := range groupIDList {
|
||||
gid := groupID
|
||||
pool, ok := groupPools[gid]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
groupNameByID := make(map[int64]string)
|
||||
groupPriorityByAccount := make(map[int64]int)
|
||||
for i := range pool {
|
||||
account := &pool[i]
|
||||
for _, accountGroup := range account.AccountGroups {
|
||||
if accountGroup.GroupID != gid {
|
||||
continue
|
||||
}
|
||||
groupPriorityByAccount[account.ID] = accountGroup.Priority
|
||||
if accountGroup.Group != nil {
|
||||
groupNameByID[gid] = accountGroup.Group.Name
|
||||
}
|
||||
}
|
||||
}
|
||||
scoreGroupPool(&gid, groupNameByID, groupPriorityByAccount, pool)
|
||||
}
|
||||
|
||||
for accountID := range groupScoresByAccount {
|
||||
sort.SliceStable(groupScoresByAccount[accountID], func(i, j int) bool {
|
||||
left := groupScoresByAccount[accountID][i]
|
||||
right := groupScoresByAccount[accountID][j]
|
||||
return *left.GroupID < *right.GroupID
|
||||
})
|
||||
}
|
||||
return baseScores, groupScoresByAccount
|
||||
}
|
||||
|
||||
func (h *AccountHandler) listAccountSchedulerScoreFilterPool(
|
||||
ctx context.Context,
|
||||
platform, accountType, status, search string,
|
||||
groupID int64,
|
||||
privacyMode string,
|
||||
) []service.Account {
|
||||
if h.adminService == nil || (platform != "" && platform != service.PlatformOpenAI) {
|
||||
return nil
|
||||
}
|
||||
// 池只用于 OpenAI 分数计算(非 OpenAI 账号会在打分时被丢弃),
|
||||
// 无论列表页平台过滤为何,查询一律限定 openai,避免无过滤时全表扫描。
|
||||
accounts, err := h.adminService.ListAccountsForSchedulerScoreFilter(ctx, service.PlatformOpenAI, accountType, status, search, groupID, privacyMode)
|
||||
if err != nil {
|
||||
slog.Warn("openai_scheduler_filter_score_pool_failed", "error", err)
|
||||
return nil
|
||||
}
|
||||
return accounts
|
||||
}
|
||||
|
||||
// List handles listing all accounts with pagination
|
||||
// GET /api/v1/admin/accounts
|
||||
func (h *AccountHandler) List(c *gin.Context) {
|
||||
@@ -239,6 +486,8 @@ func (h *AccountHandler) List(c *gin.Context) {
|
||||
search = search[:100]
|
||||
}
|
||||
lite := parseBoolQueryWithDefault(c.Query("lite"), false)
|
||||
// 调度分需要跨候选池批量打分并读取负载,默认列表不计算;只有前端列可见时才显式开启。
|
||||
includeSchedulerScore := parseBoolQueryWithDefault(c.Query("include_scheduler_score"), false)
|
||||
|
||||
var groupID int64
|
||||
if groupIDStr := c.Query("group"); groupIDStr != "" {
|
||||
@@ -274,6 +523,20 @@ func (h *AccountHandler) List(c *gin.Context) {
|
||||
var windowCosts map[int64]float64
|
||||
var activeSessions map[int64]int
|
||||
var rpmCounts map[int64]int
|
||||
// 双重门控:用户要看该列,且当前页确实有 OpenAI 账号,才进入昂贵的候选池打分路径。
|
||||
var schedulerScores map[int64]*AccountSchedulerScore
|
||||
var schedulerGroupScores map[int64][]AccountSchedulerGroupScore
|
||||
pageHasOpenAIAccounts := false
|
||||
for i := range accounts {
|
||||
if accounts[i].Platform == service.PlatformOpenAI {
|
||||
pageHasOpenAIAccounts = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if includeSchedulerScore && pageHasOpenAIAccounts {
|
||||
schedulerFilterPool := h.listAccountSchedulerScoreFilterPool(c.Request.Context(), platform, accountType, status, search, groupID, privacyMode)
|
||||
schedulerScores, schedulerGroupScores = h.buildOpenAIAccountSchedulerScores(c.Request.Context(), accounts, schedulerFilterPool)
|
||||
}
|
||||
|
||||
// 始终获取并发数(Redis ZCARD,极低开销)
|
||||
if h.concurrencyService != nil {
|
||||
@@ -354,6 +617,8 @@ func (h *AccountHandler) List(c *gin.Context) {
|
||||
item := AccountWithConcurrency{
|
||||
Account: dto.AccountFromService(acc),
|
||||
CurrentConcurrency: concurrencyCounts[acc.ID],
|
||||
SchedulerScore: schedulerScores[acc.ID],
|
||||
SchedulerScores: schedulerGroupScores[acc.ID],
|
||||
}
|
||||
|
||||
// 添加窗口费用(仅当启用时)
|
||||
@@ -380,6 +645,8 @@ func (h *AccountHandler) List(c *gin.Context) {
|
||||
result[i] = item
|
||||
}
|
||||
|
||||
h.enrichShadowParents(c.Request.Context(), result)
|
||||
|
||||
etag := buildAccountsListETag(result, total, page, pageSize, platform, accountType, status, search, lite)
|
||||
if etag != "" {
|
||||
c.Header("ETag", etag)
|
||||
@@ -518,6 +785,10 @@ func (h *AccountHandler) Create(c *gin.Context) {
|
||||
response.BadRequest(c, "Invalid request: "+err.Error())
|
||||
return
|
||||
}
|
||||
if err := service.ValidateOpenAILongContextBillingExtra(req.Platform, req.Extra); err != nil {
|
||||
response.ErrorFrom(c, err)
|
||||
return
|
||||
}
|
||||
if req.RateMultiplier != nil && *req.RateMultiplier < 0 {
|
||||
response.BadRequest(c, "rate_multiplier must be >= 0")
|
||||
return
|
||||
@@ -585,6 +856,7 @@ func (h *AccountHandler) Create(c *gin.Context) {
|
||||
// OpenAI APIKey 账号创建后异步探测上游 /v1/responses 能力。
|
||||
// 探测失败不影响账号创建响应。
|
||||
h.scheduleOpenAIResponsesProbe(createdAccount)
|
||||
h.scheduleGrokImportProbe(createdAccount)
|
||||
response.Success(c, result.Data)
|
||||
}
|
||||
|
||||
@@ -832,6 +1104,12 @@ func (h *AccountHandler) refreshSingleAccount(ctx context.Context, account *serv
|
||||
if !account.IsOAuth() {
|
||||
return nil, "", infraerrors.BadRequest("NOT_OAUTH", "cannot refresh non-OAuth account")
|
||||
}
|
||||
// spark 影子凭据由母账号管理、自身恒空,刷新无意义且会先打上游;在调用上游前早拒
|
||||
// (覆盖单账号与批量两入口;批量侧将其计为 failed 并附说明)(外审第6轮)。
|
||||
if account.IsCredentialShadow() {
|
||||
return nil, "", infraerrors.BadRequest("SPARK_SHADOW_NO_REFRESH",
|
||||
"cannot refresh spark shadow account; its credentials are managed by the parent account")
|
||||
}
|
||||
|
||||
var newCredentials map[string]any
|
||||
|
||||
@@ -1027,6 +1305,10 @@ func (h *AccountHandler) ApplyOAuthCredentials(c *gin.Context) {
|
||||
response.ErrorFrom(c, infraerrors.BadRequest("NOT_OAUTH", "cannot apply oauth credentials to non-OAuth account"))
|
||||
return
|
||||
}
|
||||
if err := service.ValidateOpenAILongContextBillingExtra(existing.Platform, req.Extra); err != nil {
|
||||
response.ErrorFrom(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
updatedAccount, err := h.adminService.UpdateAccount(ctx, accountID, &service.UpdateAccountInput{
|
||||
Type: req.Type,
|
||||
@@ -1320,6 +1602,12 @@ func (h *AccountHandler) BatchCreate(c *gin.Context) {
|
||||
response.BadRequest(c, "Invalid request: "+err.Error())
|
||||
return
|
||||
}
|
||||
for _, item := range req.Accounts {
|
||||
if err := service.ValidateOpenAILongContextBillingExtra(item.Platform, item.Extra); err != nil {
|
||||
response.ErrorFrom(c, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
executeAdminIdempotentJSON(c, "admin.accounts.batch_create", req, service.DefaultWriteIdempotencyTTL(), func(ctx context.Context) (any, error) {
|
||||
success := 0
|
||||
@@ -1381,6 +1669,7 @@ func (h *AccountHandler) BatchCreate(c *gin.Context) {
|
||||
}
|
||||
// OpenAI APIKey 账号异步探测 /v1/responses 能力。
|
||||
h.scheduleOpenAIResponsesProbe(account)
|
||||
h.scheduleGrokImportProbe(account)
|
||||
success++
|
||||
results = append(results, gin.H{
|
||||
"name": item.Name,
|
||||
@@ -1812,7 +2101,7 @@ func (h *AccountHandler) ResetQuota(c *gin.Context) {
|
||||
}
|
||||
|
||||
if err := h.adminService.ResetAccountQuota(c.Request.Context(), accountID); err != nil {
|
||||
response.InternalError(c, "Failed to reset account quota: "+err.Error())
|
||||
response.ErrorFrom(c, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2064,6 +2353,56 @@ func (h *AccountHandler) GetAvailableModels(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// Handle Grok accounts
|
||||
if account.Platform == service.PlatformGrok {
|
||||
defaultModels := xai.DefaultModels()
|
||||
|
||||
hasExplicitMapping := false
|
||||
switch rawMapping := account.Credentials["model_mapping"].(type) {
|
||||
case map[string]any:
|
||||
hasExplicitMapping = len(rawMapping) > 0
|
||||
case map[string]string:
|
||||
hasExplicitMapping = len(rawMapping) > 0
|
||||
}
|
||||
if !hasExplicitMapping {
|
||||
response.Success(c, defaultModels)
|
||||
return
|
||||
}
|
||||
|
||||
mapping := account.GetModelMapping()
|
||||
if len(mapping) == 0 {
|
||||
response.Success(c, defaultModels)
|
||||
return
|
||||
}
|
||||
|
||||
defaultByID := make(map[string]xai.Model, len(defaultModels))
|
||||
for _, model := range defaultModels {
|
||||
defaultByID[model.ID] = model
|
||||
}
|
||||
|
||||
requestedModels := make([]string, 0, len(mapping))
|
||||
for requestedModel := range mapping {
|
||||
requestedModels = append(requestedModels, requestedModel)
|
||||
}
|
||||
sort.Strings(requestedModels)
|
||||
|
||||
var models []xai.Model
|
||||
for _, requestedModel := range requestedModels {
|
||||
if defaultModel, found := defaultByID[requestedModel]; found {
|
||||
models = append(models, defaultModel)
|
||||
continue
|
||||
}
|
||||
models = append(models, xai.Model{
|
||||
ID: requestedModel,
|
||||
Object: "model",
|
||||
OwnedBy: "xai",
|
||||
DisplayName: requestedModel,
|
||||
})
|
||||
}
|
||||
response.Success(c, models)
|
||||
return
|
||||
}
|
||||
|
||||
// Handle Claude/Anthropic accounts
|
||||
// For OAuth and Setup-Token accounts: return default models
|
||||
if account.IsOAuth() {
|
||||
|
||||
@@ -61,6 +61,7 @@ func setupSyncUpstreamModelsRouter(adminSvc service.AdminService, upstream servi
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
upstream,
|
||||
&config.Config{Security: config.SecurityConfig{URLAllowlist: config.URLAllowlistConfig{Enabled: false}}},
|
||||
nil,
|
||||
@@ -70,6 +71,77 @@ func setupSyncUpstreamModelsRouter(adminSvc service.AdminService, upstream servi
|
||||
return router
|
||||
}
|
||||
|
||||
func TestAccountHandlerGetAvailableModels_GrokUsesXAIModels(t *testing.T) {
|
||||
svc := &availableModelsAdminService{
|
||||
stubAdminService: newStubAdminService(),
|
||||
account: service.Account{
|
||||
ID: 44,
|
||||
Name: "grok-oauth",
|
||||
Platform: service.PlatformGrok,
|
||||
Type: service.AccountTypeOAuth,
|
||||
Status: service.StatusActive,
|
||||
Credentials: map[string]any{
|
||||
"model_mapping": map[string]any{
|
||||
"grok-4.3": "grok-4.3",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
router := setupAvailableModelsRouter(svc)
|
||||
|
||||
rec := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/v1/admin/accounts/44/models", nil)
|
||||
router.ServeHTTP(rec, req)
|
||||
|
||||
require.Equal(t, http.StatusOK, rec.Code)
|
||||
|
||||
var resp struct {
|
||||
Data []struct {
|
||||
ID string `json:"id"`
|
||||
} `json:"data"`
|
||||
}
|
||||
require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &resp))
|
||||
require.Len(t, resp.Data, 1)
|
||||
require.Equal(t, "grok-4.3", resp.Data[0].ID)
|
||||
}
|
||||
|
||||
func TestAccountHandlerGetAvailableModels_GrokDefaultsToXAIModelsWithoutMapping(t *testing.T) {
|
||||
svc := &availableModelsAdminService{
|
||||
stubAdminService: newStubAdminService(),
|
||||
account: service.Account{
|
||||
ID: 45,
|
||||
Name: "grok-oauth-defaults",
|
||||
Platform: service.PlatformGrok,
|
||||
Type: service.AccountTypeOAuth,
|
||||
Status: service.StatusActive,
|
||||
},
|
||||
}
|
||||
router := setupAvailableModelsRouter(svc)
|
||||
|
||||
rec := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/v1/admin/accounts/45/models", nil)
|
||||
router.ServeHTTP(rec, req)
|
||||
|
||||
require.Equal(t, http.StatusOK, rec.Code)
|
||||
|
||||
var resp struct {
|
||||
Data []struct {
|
||||
ID string `json:"id"`
|
||||
} `json:"data"`
|
||||
}
|
||||
require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &resp))
|
||||
require.NotEmpty(t, resp.Data)
|
||||
|
||||
var ids []string
|
||||
for _, model := range resp.Data {
|
||||
id := model.ID
|
||||
ids = append(ids, id)
|
||||
require.NotContains(t, strings.ToLower(id), "claude")
|
||||
}
|
||||
require.Contains(t, ids, "grok-4.3")
|
||||
require.Contains(t, ids, "grok-build-0.1")
|
||||
}
|
||||
|
||||
func TestAccountHandlerGetAvailableModels_OpenAIOAuthUsesExplicitModelMapping(t *testing.T) {
|
||||
svc := &availableModelsAdminService{
|
||||
stubAdminService: newStubAdminService(),
|
||||
@@ -141,6 +213,48 @@ func TestAccountHandlerGetAvailableModels_OpenAIOAuthPassthroughFallsBackToDefau
|
||||
require.NotEqual(t, "gpt-5", resp.Data[0].ID)
|
||||
}
|
||||
|
||||
func TestAccountHandlerGetAvailableModels_OpenAISparkShadowReturnsMappingModels(t *testing.T) {
|
||||
parentID := int64(100)
|
||||
svc := &availableModelsAdminService{
|
||||
stubAdminService: newStubAdminService(),
|
||||
account: service.Account{
|
||||
ID: 44,
|
||||
Name: "openai-spark-shadow",
|
||||
Platform: service.PlatformOpenAI,
|
||||
Type: service.AccountTypeOAuth,
|
||||
Status: service.StatusActive,
|
||||
ParentAccountID: &parentID,
|
||||
QuotaDimension: service.QuotaDimensionSpark,
|
||||
Credentials: map[string]any{
|
||||
"model_mapping": map[string]any{
|
||||
"gpt-5.3-codex-spark": "gpt-5.3-codex-spark",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
router := setupAvailableModelsRouter(svc)
|
||||
|
||||
rec := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/v1/admin/accounts/44/models", nil)
|
||||
router.ServeHTTP(rec, req)
|
||||
|
||||
require.Equal(t, http.StatusOK, rec.Code)
|
||||
|
||||
var resp struct {
|
||||
Data []struct {
|
||||
ID string `json:"id"`
|
||||
} `json:"data"`
|
||||
}
|
||||
require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &resp))
|
||||
ids := make([]string, 0, len(resp.Data))
|
||||
for _, m := range resp.Data {
|
||||
ids = append(ids, m.ID)
|
||||
}
|
||||
require.ElementsMatch(t, []string{
|
||||
"gpt-5.3-codex-spark",
|
||||
}, ids, "影子可用模型由 model_mapping 派生(非写死)")
|
||||
}
|
||||
|
||||
func TestAccountHandlerSyncUpstreamModels_ConfigErrorReturnsBadRequest(t *testing.T) {
|
||||
svc := &availableModelsAdminService{
|
||||
stubAdminService: newStubAdminService(),
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/Wei-Shaw/sub2api/internal/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
@@ -50,3 +51,259 @@ func TestAccountHandlerListIncludesCreatedAt(t *testing.T) {
|
||||
_, offset := parsed.Zone()
|
||||
require.Equal(t, 0, offset)
|
||||
}
|
||||
|
||||
func TestAccountHandlerListReturnsSchedulerScoresPerGroup(t *testing.T) {
|
||||
router, adminSvc := setupAccountListRouter()
|
||||
now := time.Now().UTC()
|
||||
groupID := int64(41)
|
||||
adminSvc.accounts = []service.Account{
|
||||
{
|
||||
ID: 101,
|
||||
Name: "account-high-priority",
|
||||
Platform: service.PlatformOpenAI,
|
||||
Type: service.AccountTypeAPIKey,
|
||||
Status: service.StatusActive,
|
||||
Schedulable: true,
|
||||
Concurrency: 10,
|
||||
Priority: 1,
|
||||
AccountGroups: []service.AccountGroup{
|
||||
{AccountID: 101, GroupID: groupID, Priority: 100, Group: &service.Group{ID: groupID, Name: "openai"}},
|
||||
},
|
||||
GroupIDs: []int64{groupID},
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
},
|
||||
{
|
||||
ID: 102,
|
||||
Name: "account-low-priority",
|
||||
Platform: service.PlatformOpenAI,
|
||||
Type: service.AccountTypeAPIKey,
|
||||
Status: service.StatusActive,
|
||||
Schedulable: true,
|
||||
Concurrency: 10,
|
||||
Priority: 100000,
|
||||
AccountGroups: []service.AccountGroup{
|
||||
{AccountID: 102, GroupID: groupID, Priority: 1, Group: &service.Group{ID: groupID, Name: "openai"}},
|
||||
},
|
||||
GroupIDs: []int64{groupID},
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
},
|
||||
}
|
||||
|
||||
rec := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/v1/admin/accounts?page=1&page_size=20&platform=openai&include_scheduler_score=1", nil)
|
||||
router.ServeHTTP(rec, req)
|
||||
|
||||
require.Equal(t, http.StatusOK, rec.Code)
|
||||
var payload struct {
|
||||
Data struct {
|
||||
Items []struct {
|
||||
ID int64 `json:"id"`
|
||||
SchedulerScore struct {
|
||||
BaseScore float64 `json:"base_score"`
|
||||
} `json:"scheduler_score"`
|
||||
SchedulerScores []struct {
|
||||
GroupID *int64 `json:"group_id"`
|
||||
GroupName string `json:"group_name"`
|
||||
GroupPriority *int `json:"group_priority"`
|
||||
BaseScore float64 `json:"base_score"`
|
||||
} `json:"scheduler_scores"`
|
||||
} `json:"items"`
|
||||
} `json:"data"`
|
||||
}
|
||||
require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &payload))
|
||||
require.Len(t, payload.Data.Items, 2)
|
||||
|
||||
var high, low *struct {
|
||||
ID int64 `json:"id"`
|
||||
SchedulerScore struct {
|
||||
BaseScore float64 `json:"base_score"`
|
||||
} `json:"scheduler_score"`
|
||||
SchedulerScores []struct {
|
||||
GroupID *int64 `json:"group_id"`
|
||||
GroupName string `json:"group_name"`
|
||||
GroupPriority *int `json:"group_priority"`
|
||||
BaseScore float64 `json:"base_score"`
|
||||
} `json:"scheduler_scores"`
|
||||
}
|
||||
for i := range payload.Data.Items {
|
||||
item := &payload.Data.Items[i]
|
||||
switch item.ID {
|
||||
case 101:
|
||||
high = item
|
||||
case 102:
|
||||
low = item
|
||||
}
|
||||
}
|
||||
require.NotNil(t, high)
|
||||
require.NotNil(t, low)
|
||||
require.Len(t, high.SchedulerScores, 1)
|
||||
require.Len(t, low.SchedulerScores, 1)
|
||||
require.Equal(t, groupID, *high.SchedulerScores[0].GroupID)
|
||||
require.Equal(t, "openai", high.SchedulerScores[0].GroupName)
|
||||
require.Equal(t, 100, *high.SchedulerScores[0].GroupPriority)
|
||||
require.Equal(t, 1, *low.SchedulerScores[0].GroupPriority)
|
||||
require.Greater(t, high.SchedulerScores[0].BaseScore, low.SchedulerScores[0].BaseScore)
|
||||
}
|
||||
|
||||
func TestAccountHandlerListSkipsSchedulerScoresByDefault(t *testing.T) {
|
||||
router, adminSvc := setupAccountListRouter()
|
||||
now := time.Now().UTC()
|
||||
adminSvc.accounts = []service.Account{
|
||||
{
|
||||
ID: 110,
|
||||
Name: "openai-account",
|
||||
Platform: service.PlatformOpenAI,
|
||||
Type: service.AccountTypeAPIKey,
|
||||
Status: service.StatusActive,
|
||||
Schedulable: true,
|
||||
Concurrency: 10,
|
||||
Priority: 1,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
},
|
||||
}
|
||||
|
||||
rec := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/v1/admin/accounts?page=1&page_size=20&platform=openai", nil)
|
||||
router.ServeHTTP(rec, req)
|
||||
|
||||
require.Equal(t, http.StatusOK, rec.Code)
|
||||
require.Zero(t, adminSvc.schedulerScoreFilterCalls)
|
||||
require.Zero(t, adminSvc.openAISchedulerScorePoolCalls)
|
||||
|
||||
var payload struct {
|
||||
Data struct {
|
||||
Items []map[string]any `json:"items"`
|
||||
} `json:"data"`
|
||||
}
|
||||
require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &payload))
|
||||
require.Len(t, payload.Data.Items, 1)
|
||||
require.NotContains(t, payload.Data.Items[0], "scheduler_score")
|
||||
require.NotContains(t, payload.Data.Items[0], "scheduler_scores")
|
||||
}
|
||||
|
||||
func TestAccountHandlerListKeepsSchedulerScoreScopedToFilter(t *testing.T) {
|
||||
router, adminSvc := setupAccountListRouter()
|
||||
now := time.Now().UTC()
|
||||
groupID := int64(42)
|
||||
visibleAccount := service.Account{
|
||||
ID: 201,
|
||||
Name: "visible-low-priority",
|
||||
Platform: service.PlatformOpenAI,
|
||||
Type: service.AccountTypeAPIKey,
|
||||
Status: service.StatusActive,
|
||||
Schedulable: true,
|
||||
Concurrency: 10,
|
||||
Priority: 100000,
|
||||
AccountGroups: []service.AccountGroup{
|
||||
{AccountID: 201, GroupID: groupID, Priority: 1, Group: &service.Group{ID: groupID, Name: "openai"}},
|
||||
},
|
||||
GroupIDs: []int64{groupID},
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
hiddenGroupPeer := service.Account{
|
||||
ID: 202,
|
||||
Name: "hidden-high-priority",
|
||||
Platform: service.PlatformOpenAI,
|
||||
Type: service.AccountTypeAPIKey,
|
||||
Status: service.StatusActive,
|
||||
Schedulable: true,
|
||||
Concurrency: 10,
|
||||
Priority: 1,
|
||||
AccountGroups: []service.AccountGroup{
|
||||
{AccountID: 202, GroupID: groupID, Priority: 2, Group: &service.Group{ID: groupID, Name: "openai"}},
|
||||
},
|
||||
GroupIDs: []int64{groupID},
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
adminSvc.accounts = []service.Account{visibleAccount}
|
||||
adminSvc.accountSchedulerScoreFilterAccounts = []service.Account{visibleAccount, hiddenGroupPeer}
|
||||
adminSvc.openAISchedulerScorePoolAccounts = []service.Account{visibleAccount, hiddenGroupPeer}
|
||||
|
||||
rec := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/v1/admin/accounts?page=1&page_size=1&platform=openai&include_scheduler_score=1", nil)
|
||||
router.ServeHTTP(rec, req)
|
||||
|
||||
require.Equal(t, http.StatusOK, rec.Code)
|
||||
var payload struct {
|
||||
Data struct {
|
||||
Items []struct {
|
||||
ID int64 `json:"id"`
|
||||
SchedulerScore struct {
|
||||
BaseScore float64 `json:"base_score"`
|
||||
} `json:"scheduler_score"`
|
||||
SchedulerScores []struct {
|
||||
GroupID *int64 `json:"group_id"`
|
||||
BaseScore float64 `json:"base_score"`
|
||||
} `json:"scheduler_scores"`
|
||||
} `json:"items"`
|
||||
} `json:"data"`
|
||||
}
|
||||
require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &payload))
|
||||
require.Len(t, payload.Data.Items, 1)
|
||||
item := payload.Data.Items[0]
|
||||
require.Equal(t, int64(201), item.ID)
|
||||
require.Len(t, item.SchedulerScores, 1)
|
||||
require.Equal(t, groupID, *item.SchedulerScores[0].GroupID)
|
||||
require.Equal(t, item.SchedulerScores[0].BaseScore, item.SchedulerScore.BaseScore)
|
||||
}
|
||||
|
||||
func TestAccountHandlerListSchedulerScoreIgnoresPagination(t *testing.T) {
|
||||
router, adminSvc := setupAccountListRouter()
|
||||
now := time.Now().UTC()
|
||||
visibleAccount := service.Account{
|
||||
ID: 301,
|
||||
Name: "visible-low-priority",
|
||||
Platform: service.PlatformOpenAI,
|
||||
Type: service.AccountTypeAPIKey,
|
||||
Status: service.StatusActive,
|
||||
Schedulable: true,
|
||||
Concurrency: 10,
|
||||
Priority: 100000,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
hiddenFilterPeer := service.Account{
|
||||
ID: 302,
|
||||
Name: "hidden-high-priority",
|
||||
Platform: service.PlatformOpenAI,
|
||||
Type: service.AccountTypeAPIKey,
|
||||
Status: service.StatusActive,
|
||||
Schedulable: true,
|
||||
Concurrency: 10,
|
||||
Priority: 1,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
}
|
||||
adminSvc.accounts = []service.Account{visibleAccount}
|
||||
adminSvc.accountSchedulerScoreFilterAccounts = []service.Account{visibleAccount, hiddenFilterPeer}
|
||||
|
||||
rec := httptest.NewRecorder()
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/v1/admin/accounts?page=1&page_size=1&platform=openai&include_scheduler_score=1", nil)
|
||||
router.ServeHTTP(rec, req)
|
||||
|
||||
require.Equal(t, http.StatusOK, rec.Code)
|
||||
var payload struct {
|
||||
Data struct {
|
||||
Items []struct {
|
||||
ID int64 `json:"id"`
|
||||
SchedulerScore struct {
|
||||
BaseScore float64 `json:"base_score"`
|
||||
} `json:"scheduler_score"`
|
||||
SchedulerScores []struct {
|
||||
GroupID *int64 `json:"group_id"`
|
||||
BaseScore float64 `json:"base_score"`
|
||||
} `json:"scheduler_scores"`
|
||||
} `json:"items"`
|
||||
} `json:"data"`
|
||||
}
|
||||
require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &payload))
|
||||
require.Len(t, payload.Data.Items, 1)
|
||||
require.Equal(t, int64(301), payload.Data.Items[0].ID)
|
||||
require.Less(t, payload.Data.Items[0].SchedulerScore.BaseScore, 3.75)
|
||||
require.Empty(t, payload.Data.Items[0].SchedulerScores)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors"
|
||||
"github.com/Wei-Shaw/sub2api/internal/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAccountAdminBoundariesRejectMalformedOpenAILongContextBillingValue(t *testing.T) {
|
||||
const malformedExtra = `"extra":{"openai_long_context_billing_enabled":"true"}`
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
method string
|
||||
path string
|
||||
body string
|
||||
mount func(*gin.Engine, *AccountHandler)
|
||||
setup func(*stubAdminService)
|
||||
}{
|
||||
{
|
||||
name: "create",
|
||||
method: http.MethodPost,
|
||||
path: "/accounts",
|
||||
body: `{"name":"account","platform":"openai","type":"apikey","credentials":{"api_key":"test"},` + malformedExtra + `}`,
|
||||
mount: func(router *gin.Engine, handler *AccountHandler) { router.POST("/accounts", handler.Create) },
|
||||
},
|
||||
{
|
||||
name: "update",
|
||||
method: http.MethodPut,
|
||||
path: "/accounts/1",
|
||||
body: `{` + malformedExtra + `}`,
|
||||
mount: func(router *gin.Engine, handler *AccountHandler) { router.PUT("/accounts/:id", handler.Update) },
|
||||
setup: func(stub *stubAdminService) {
|
||||
stub.updateAccountErr = infraerrors.BadRequest("OPENAI_LONG_CONTEXT_BILLING_INVALID", "invalid")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "bulk update",
|
||||
method: http.MethodPost,
|
||||
path: "/accounts/bulk-update",
|
||||
body: `{"account_ids":[1],` + malformedExtra + `}`,
|
||||
mount: func(router *gin.Engine, handler *AccountHandler) {
|
||||
router.POST("/accounts/bulk-update", handler.BulkUpdate)
|
||||
},
|
||||
setup: func(stub *stubAdminService) {
|
||||
stub.bulkUpdateAccountErr = infraerrors.BadRequest("OPENAI_LONG_CONTEXT_BILLING_INVALID", "invalid")
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "batch create",
|
||||
method: http.MethodPost,
|
||||
path: "/accounts/batch",
|
||||
body: `{"accounts":[{"name":"account","platform":"openai","type":"apikey","credentials":{"api_key":"test"},` + malformedExtra + `}]}`,
|
||||
mount: func(router *gin.Engine, handler *AccountHandler) { router.POST("/accounts/batch", handler.BatchCreate) },
|
||||
},
|
||||
{
|
||||
name: "Codex session import",
|
||||
method: http.MethodPost,
|
||||
path: "/accounts/import-codex-session",
|
||||
body: `{"content":"token",` + malformedExtra + `}`,
|
||||
mount: func(router *gin.Engine, handler *AccountHandler) {
|
||||
router.POST("/accounts/import-codex-session", handler.ImportCodexSession)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
stub := newStubAdminService()
|
||||
if tt.setup != nil {
|
||||
tt.setup(stub)
|
||||
}
|
||||
handler := NewAccountHandler(stub, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
|
||||
router := gin.New()
|
||||
tt.mount(router, handler)
|
||||
recorder := httptest.NewRecorder()
|
||||
request := httptest.NewRequest(tt.method, tt.path, bytes.NewBufferString(tt.body))
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
router.ServeHTTP(recorder, request)
|
||||
|
||||
require.Equal(t, http.StatusBadRequest, recorder.Code)
|
||||
var responseBody struct {
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
require.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &responseBody))
|
||||
require.Equal(t, "OPENAI_LONG_CONTEXT_BILLING_INVALID", responseBody.Reason)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestAccountCreateBoundaryDoesNotApplyOpenAIValidationToOtherPlatforms(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
handler := NewAccountHandler(newStubAdminService(), nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
|
||||
router := gin.New()
|
||||
router.POST("/accounts", handler.Create)
|
||||
recorder := httptest.NewRecorder()
|
||||
request := httptest.NewRequest(http.MethodPost, "/accounts", bytes.NewBufferString(
|
||||
`{"name":"account","platform":"anthropic","type":"apikey","credentials":{"api_key":"test"},"extra":{"openai_long_context_billing_enabled":"provider-owned"}}`,
|
||||
))
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
router.ServeHTTP(recorder, request)
|
||||
|
||||
require.Equal(t, http.StatusOK, recorder.Code)
|
||||
}
|
||||
|
||||
func TestApplyOAuthCredentialsRejectsMalformedOpenAILongContextBillingBeforeMutation(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
stub := newStubAdminService()
|
||||
stub.getAccountResult = &service.Account{
|
||||
ID: 1,
|
||||
Platform: service.PlatformOpenAI,
|
||||
Type: service.AccountTypeOAuth,
|
||||
}
|
||||
handler := NewAccountHandler(stub, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil)
|
||||
router := gin.New()
|
||||
router.POST("/accounts/:id/apply-oauth-credentials", handler.ApplyOAuthCredentials)
|
||||
recorder := httptest.NewRecorder()
|
||||
request := httptest.NewRequest(http.MethodPost, "/accounts/1/apply-oauth-credentials", bytes.NewBufferString(
|
||||
`{"type":"oauth","credentials":{"access_token":"new-token"},"extra":{"openai_long_context_billing_enabled":"true"}}`,
|
||||
))
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
router.ServeHTTP(recorder, request)
|
||||
|
||||
require.Equal(t, http.StatusBadRequest, recorder.Code)
|
||||
var responseBody struct {
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
require.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &responseBody))
|
||||
require.Equal(t, "OPENAI_LONG_CONTEXT_BILLING_INVALID", responseBody.Reason)
|
||||
require.Zero(t, stub.updateAccountCalls)
|
||||
require.Zero(t, stub.updateAccountExtraCalls)
|
||||
}
|
||||
|
||||
func TestOpenAIOAuthCodexPATBoundaryRejectsMalformedOpenAILongContextBillingValueBeforeTokenValidation(t *testing.T) {
|
||||
gin.SetMode(gin.TestMode)
|
||||
handler := NewOpenAIOAuthHandler(nil, newStubAdminService(), nil)
|
||||
router := gin.New()
|
||||
router.Use(gin.Recovery())
|
||||
router.POST("/openai/create-from-codex-pat", handler.CreateAccountFromCodexPAT)
|
||||
recorder := httptest.NewRecorder()
|
||||
request := httptest.NewRequest(http.MethodPost, "/openai/create-from-codex-pat", bytes.NewBufferString(
|
||||
`{"access_token":"token","extra":{"openai_long_context_billing_enabled":1}}`,
|
||||
))
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
|
||||
router.ServeHTTP(recorder, request)
|
||||
|
||||
require.Equal(t, http.StatusBadRequest, recorder.Code)
|
||||
var responseBody struct {
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
require.NoError(t, json.Unmarshal(recorder.Body.Bytes(), &responseBody))
|
||||
require.Equal(t, "OPENAI_LONG_CONTEXT_BILLING_INVALID", responseBody.Reason)
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors"
|
||||
"github.com/Wei-Shaw/sub2api/internal/service"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestRefreshSingleAccount_RejectsShadow 验证外审第6轮:手动刷新对 spark 影子在调用上游前早拒
|
||||
// (影子凭据由母账号管理、自身恒空,刷新无意义)。该守卫同时覆盖单账号与批量刷新两入口。
|
||||
func TestRefreshSingleAccount_RejectsShadow(t *testing.T) {
|
||||
h := &AccountHandler{} // 影子在使用任何依赖前即返回,无需注入
|
||||
parentID := int64(5)
|
||||
shadow := &service.Account{
|
||||
ID: 9,
|
||||
Platform: service.PlatformOpenAI,
|
||||
Type: service.AccountTypeOAuth, // IsOAuth()=true,确保不是先撞 NOT_OAUTH
|
||||
ParentAccountID: &parentID,
|
||||
QuotaDimension: service.QuotaDimensionSpark,
|
||||
}
|
||||
|
||||
_, _, err := h.refreshSingleAccount(context.Background(), shadow)
|
||||
require.Error(t, err, "影子刷新应被早拒")
|
||||
require.Equal(t, http.StatusBadRequest, infraerrors.Code(err))
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Wei-Shaw/sub2api/internal/service"
|
||||
)
|
||||
|
||||
// enrichShadowParentInfo 把母账号的展示信息回填到影子行的 parent_* 字段。
|
||||
// 纯函数:仅依赖传入的母账号 map,便于单测;非影子或母账号缺失时优雅留空。
|
||||
func enrichShadowParentInfo(items []AccountWithConcurrency, parents map[int64]*service.Account) {
|
||||
for i := range items {
|
||||
a := items[i].Account
|
||||
if a == nil || a.ParentAccountID == nil {
|
||||
continue
|
||||
}
|
||||
p := parents[*a.ParentAccountID]
|
||||
if p == nil {
|
||||
continue
|
||||
}
|
||||
a.ParentEmail = p.GetCredential("email")
|
||||
a.ParentPlanType = p.GetCredential("plan_type")
|
||||
a.ParentSubscriptionExpiresAt = p.GetCredential("subscription_expires_at")
|
||||
a.ParentChatGPTAccountID = p.GetCredential("chatgpt_account_id")
|
||||
a.ParentPrivacyMode = p.GetExtraString("privacy_mode")
|
||||
}
|
||||
}
|
||||
|
||||
// enrichShadowParents 收集本批影子行的母账号 ID、一次批量解析(避免 N+1),再回填。
|
||||
// 解析失败时不报错(parent_* 留空,降级)。
|
||||
func (h *AccountHandler) enrichShadowParents(ctx context.Context, items []AccountWithConcurrency) {
|
||||
seen := make(map[int64]struct{})
|
||||
for i := range items {
|
||||
a := items[i].Account
|
||||
if a == nil || a.ParentAccountID == nil {
|
||||
continue
|
||||
}
|
||||
seen[*a.ParentAccountID] = struct{}{}
|
||||
}
|
||||
if len(seen) == 0 {
|
||||
return
|
||||
}
|
||||
parentIDs := make([]int64, 0, len(seen))
|
||||
for pid := range seen {
|
||||
parentIDs = append(parentIDs, pid)
|
||||
}
|
||||
parents, err := h.adminService.GetAccountsByIDs(ctx, parentIDs)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
pmap := make(map[int64]*service.Account, len(parents))
|
||||
for _, p := range parents {
|
||||
pmap[p.ID] = p
|
||||
}
|
||||
enrichShadowParentInfo(items, pmap)
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user