mirror of
https://github.com/astaxie/beego.git
synced 2025-07-11 14:21:00 +00:00
Compare commits
1078 Commits
v1.8.3
...
v2.0.0-bet
Author | SHA1 | Date | |
---|---|---|---|
fb12e1f743 | |||
8c0fc30094 | |||
20a0de6bd0 | |||
b4396c97bb | |||
cbbb6bfb08 | |||
b2a96234ab | |||
471ebba64d | |||
d07a1eaa8e | |||
9524036aab | |||
45260e4119 | |||
02234dc503 | |||
05f4e0c146 | |||
ae108ec826 | |||
7c61eb058f | |||
03ba495b7f | |||
d26683799a | |||
f9075e8274 | |||
022ad862ac | |||
93bdf97068 | |||
3c48719999 | |||
cbb3de741d | |||
c510926cb8 | |||
140a4b90a3 | |||
c07acaebbc | |||
105b874477 | |||
3fc21ae6ec | |||
ccf873fa8b | |||
2572094a8d | |||
568626cd57 | |||
34d6a733e9 | |||
db3defa76a | |||
1dffa20435 | |||
e44f16c672 | |||
d41abdb5e4 | |||
f1358cf78d | |||
14c1b76569 | |||
8e37fe3b78 | |||
2708916f96 | |||
91e18996bd | |||
034cb3222e | |||
66804324f2 | |||
dc65055cf6 | |||
b8c1e133bf | |||
8cc74652a2 | |||
d66321fe4e | |||
6aa6c55f07 | |||
ff762b561c | |||
d8e8f41230 | |||
9e6b8fcf34 | |||
48e98482f7 | |||
ff7a8b966b | |||
f9bef68aa9 | |||
484beb8bad | |||
43560dede4 | |||
c435d231ab | |||
b838683731 | |||
70cca5e298 | |||
f1cca45d8d | |||
4dc694411f | |||
3364c609de | |||
c5d43e87fe | |||
b89d9511ab | |||
0b7ece44cf | |||
6ffbc0a2b8 | |||
325a0821c1 | |||
dd3f1ce9be | |||
463e96447a | |||
03498529b9 | |||
9a7c43c404 | |||
44127edefc | |||
089006525e | |||
2846043f2a | |||
e6a257f987 | |||
2473e69417 | |||
d455805a0a | |||
bd1cfefec7 | |||
7effdb0e7d | |||
b027968c0b | |||
961f300c14 | |||
7570abd310 | |||
7c8136710c | |||
a3ece98cec | |||
a31dce6216 | |||
a1782cc22d | |||
67f64afa85 | |||
2539fe3831 | |||
05c125ec2d | |||
6e638ef6c8 | |||
df043f22fc | |||
fbaf3380c6 | |||
b7bc57c4d1 | |||
26208a53e6 | |||
32cdda96bd | |||
5995b00fa2 | |||
5618df8c76 | |||
c6c9ad46f9 | |||
5973ef107c | |||
b575fa1ebe | |||
6bbca96c6c | |||
63cd8e4e15 | |||
93736a8e66 | |||
654d87b210 | |||
0048b7d158 | |||
00e44952ff | |||
8982f5d702 | |||
6612bc4c2a | |||
f580a714d5 | |||
9ccd58bfff | |||
0f50b07a20 | |||
b86cf22fc4 | |||
6bf01eaeca | |||
8e015deee5 | |||
3acda41bc7 | |||
5b3dd7e50f | |||
f4a43814be | |||
35f1bd2119 | |||
f6c95ad534 | |||
f1950482c2 | |||
1dae2c9eb3 | |||
8ef9965eef | |||
3530457ff9 | |||
cbd51616f1 | |||
bdd8df6751 | |||
8fc4f8847c | |||
3bf5cde38c | |||
7a53baaf9b | |||
7574b91760 | |||
78d91062c9 | |||
23792401b5 | |||
e54dbabf0b | |||
cdc8110ea4 | |||
f6519b29a8 | |||
185d55eb46 | |||
91410be722 | |||
ff53e12191 | |||
8e879726fe | |||
33b052bc7a | |||
087399c44a | |||
f4f200cf04 | |||
0a58428220 | |||
60bb057783 | |||
c0462f75bf | |||
5cf33f2655 | |||
670064686e | |||
8736ffaf6f | |||
0019e0fc1b | |||
03bec05714 | |||
e831b97eb8 | |||
81b9a1382a | |||
0189e6329a | |||
6684924e99 | |||
e0a934af1d | |||
8178f035a0 | |||
2b39ff7837 | |||
c2361170b3 | |||
5b35bf6065 | |||
14c911e9d7 | |||
9472cba6c9 | |||
b83094ac1e | |||
f946a35acd | |||
9bd3a27e80 | |||
1cb0ff560d | |||
cceecad8c2 | |||
d24f861629 | |||
c2471b22ad | |||
c5970766a3 | |||
48a98ec1a5 | |||
ed1d2c7f6e | |||
7a94996e22 | |||
597c55d547 | |||
026e8bc55a | |||
581e48679e | |||
09afe0ae8e | |||
08e49ca323 | |||
e1da804b2b | |||
705e091593 | |||
6bdedff457 | |||
f3be6dd2e9 | |||
9fe353dd0b | |||
9003ca3eef | |||
ff5ac3adf4 | |||
ca4a217783 | |||
e6ea307549 | |||
2c16c7b917 | |||
77ddc3338f | |||
ac3a549187 | |||
fe56de06b5 | |||
6c002a3124 | |||
cead72c6df | |||
7fe4eaef50 | |||
63599c0032 | |||
4db256c9fb | |||
c548764c8e | |||
b4a85c8f13 | |||
94f476fa39 | |||
8574e30b3a | |||
7442919f5a | |||
f6ec4efc70 | |||
7b899aa9af | |||
f73eee75ff | |||
739b8bab0c | |||
139c393f08 | |||
bdec93986b | |||
7ce0fde171 | |||
d6a2621b3c | |||
813a4df3c5 | |||
7267f5e573 | |||
5bc8d90d7f | |||
2d1c02e1c1 | |||
9ca9535c48 | |||
d1d9df74c7 | |||
d326d74c34 | |||
82178a487b | |||
a1b7fd3c93 | |||
0813471202 | |||
ce698aacf6 | |||
c22af4c611 | |||
f8c0e6fec5 | |||
882f1273c8 | |||
5a1fa4e1ec | |||
d05460237c | |||
75107f735e | |||
2e891152dd | |||
dec98f004c | |||
26b016a3a4 | |||
19aae0b7e1 | |||
2e192e1ed0 | |||
f9a3eae9d5 | |||
7fc1e4de96 | |||
993ccac2bd | |||
2fd65a469c | |||
a2fa073072 | |||
08cec9178f | |||
63b3fc4a99 | |||
1b4bb43df0 | |||
ec55edfbc4 | |||
2fce8f9d1b | |||
15489fa76a | |||
e7d8bab5d9 | |||
2f5683610f | |||
5c8c088684 | |||
009074725e | |||
ce50ca22d7 | |||
3052c64b6c | |||
5f2f6e4f86 | |||
3382a5baa1 | |||
882aa9b967 | |||
02972d8702 | |||
261b704d8b | |||
6c6cf91741 | |||
ae8461f95d | |||
aa3987f816 | |||
3dc5ec1060 | |||
1961c1e441 | |||
787bb60b42 | |||
12b984861d | |||
79ffef90e3 | |||
310161f9d4 | |||
a0d1c42dac | |||
6f5c5bd3a6 | |||
28e6b3b924 | |||
9e1346ef4d | |||
9f295067b7 | |||
71776e4bef | |||
87b40ee9e7 | |||
7831638f37 | |||
5203804165 | |||
d4074b5004 | |||
0815e77f9a | |||
c46ba86215 | |||
9d23e5a3fb | |||
513a4afff1 | |||
15e11931fc | |||
7d561607d8 | |||
22b8cae73b | |||
aa06a10493 | |||
9b58c2836c | |||
15f04b8da4 | |||
7312197732 | |||
e87de70c6d | |||
4304b40a82 | |||
e8facd28f5 | |||
54ef476600 | |||
756df9385f | |||
21f281655d | |||
2e7fb81348 | |||
ebc0207909 | |||
2386c9c80d | |||
b9f9fcca5f | |||
16d71893cd | |||
cfff0f3b46 | |||
93eb7c6b83 | |||
79c2157ad4 | |||
30eb889a91 | |||
9c51952db4 | |||
16b66509f6 | |||
d5695060c5 | |||
af2143f8fb | |||
a66b9950e7 | |||
44460bc457 | |||
41feb3a711 | |||
b6f7d30f9f | |||
4aad313de7 | |||
aefe21b63a | |||
32da446eb1 | |||
d9c016ed98 | |||
7258ef113a | |||
d6779c4a90 | |||
192a278a2a | |||
7a48fbb698 | |||
3e2c795410 | |||
55e6298f29 | |||
b50fb44950 | |||
9d936c58bf | |||
ffe1d52120 | |||
1c0714405a | |||
678b90385b | |||
5940ae33c2 | |||
3db31385cf | |||
2b9aaa5b0d | |||
dced745d55 | |||
25ba78ea72 | |||
863b5bd0f4 | |||
ba3153621a | |||
40cdc877b6 | |||
76debb1899 | |||
35dcc3df7c | |||
c3f14a0ad6 | |||
8ee167bc7b | |||
2eccb23461 | |||
28d3f624a3 | |||
926b80d1d8 | |||
c08b27111c | |||
03f78b2e4a | |||
946a42c021 | |||
d7b0d55357 | |||
728bf34006 | |||
e0f8c6832d | |||
469dc7bea9 | |||
ca0c64b69e | |||
5a4a082af0 | |||
9dc660c1da | |||
d8724cb122 | |||
fc56c562db | |||
8d1a9bc92e | |||
db547a7c84 | |||
7c575585e9 | |||
289f86247e | |||
ca9b21bb30 | |||
d6ef33feee | |||
2f5ed5b433 | |||
9c18dbe7dc | |||
01219944a4 | |||
4fac6ceb3f | |||
1c4085e7ea | |||
2117562113 | |||
1f9da8d75b | |||
9dea9f9ae7 | |||
0f6735e20d | |||
ad68e8d866 | |||
26beef756f | |||
5c9cc805a1 | |||
de51bd28d7 | |||
6b6a0e8a56 | |||
8039cc8e59 | |||
b88b7d2899 | |||
e725192072 | |||
469f2c226d | |||
828b20163d | |||
9c5eab4834 | |||
1813d414ae | |||
6052524a28 | |||
3ce68d6a30 | |||
89420eacd0 | |||
6d9862b924 | |||
96658121dc | |||
43a3623f51 | |||
089dfbdbee | |||
526a5463d6 | |||
a28d294a83 | |||
f70fd5babf | |||
a764e17fbf | |||
f5c580a403 | |||
7210dc24b6 | |||
1060dc7df8 | |||
3ab1e48217 | |||
a5e8344a0a | |||
e1386c448c | |||
6e4d0917b2 | |||
9b43a90138 | |||
b7833fb297 | |||
16b81d09a7 | |||
0056b92d0b | |||
decc75e025 | |||
f2bae3e367 | |||
6eeea141d8 | |||
6c0db4db3d | |||
b9fbcbd906 | |||
40181c1042 | |||
3879fd9c34 | |||
af238ee047 | |||
86935ada01 | |||
8160059182 | |||
dc70e9fc47 | |||
bac2b31afe | |||
a134cb8d17 | |||
4ad699b7b8 | |||
14fc935cb6 | |||
d9f262e277 | |||
131748bb3d | |||
2c3c66ccea | |||
71cb1379b4 | |||
b351f02525 | |||
8e29300f85 | |||
5f31bf45d4 | |||
3e30f37172 | |||
ce4ce74c8d | |||
ce0e7525ad | |||
d0b7244d57 | |||
5100a8c396 | |||
b8efb3ef45 | |||
ae15b54f83 | |||
0dab959c95 | |||
ee615dd08f | |||
b879a07b3a | |||
c265f6e49c | |||
690e91e1b6 | |||
50f71a8a21 | |||
677d010d86 | |||
db2a1134ce | |||
c2771397be | |||
70733d9810 | |||
11740cede6 | |||
4ffe26a1d2 | |||
075db4773b | |||
2fd9dfca7b | |||
eea20f6ceb | |||
8055357576 | |||
9fda81b7f3 | |||
4b12e053b7 | |||
0307c8b110 | |||
867f83de34 | |||
af19822293 | |||
2449aad105 | |||
d31975a752 | |||
b28d5e2716 | |||
ab33d683ea | |||
f99cbe0fa4 | |||
0aa82d875a | |||
8f3d1c5f42 | |||
2410b364af | |||
713503e43d | |||
cfdd1cd5be | |||
de5650b723 | |||
e5e4a3bea7 | |||
90d0b43f34 | |||
1b7f5ba2c4 | |||
96f01079cb | |||
9d4b5b313f | |||
b882009979 | |||
a768bf8f00 | |||
034599ca1d | |||
5a02c556b2 | |||
dc5c42e981 | |||
92a4119258 | |||
aa90c67a75 | |||
38a144c68f | |||
793047097c | |||
1923b8c767 | |||
fb640f0075 | |||
241f10b429 | |||
b8d626bbea | |||
2a6ceca861 | |||
10236b9f2d | |||
b3ae5d4ac6 | |||
77fc8e4e38 | |||
5a5482c77f | |||
11774c87a5 | |||
6d47b4a2e0 | |||
8395a26061 | |||
4348356d0a | |||
b551949a2b | |||
32cd76396d | |||
5620608418 | |||
32ee728078 | |||
de7ce2f9b0 | |||
d6c2a9fd4b | |||
582a4fa34b | |||
99647986de | |||
5bcde306ea | |||
2909ff3366 | |||
40078cba2c | |||
5d0c0a03d7 | |||
8cfd7f5c19 | |||
62d96c2e93 | |||
e844058aed | |||
1eab6bb32a | |||
c265d32c36 | |||
06692c3e27 | |||
394a73c75f | |||
cbcde8bd1f | |||
b17e49e6aa | |||
873f62edff | |||
cc0eacbe02 | |||
649c5c861d | |||
206a7ed1fc | |||
3c046a4dbf | |||
f2be6af2ca | |||
804b9769e0 | |||
585df01899 | |||
1a529c061c | |||
fcacfc08e3 | |||
a0ca3d61d6 | |||
39bd40e512 | |||
8748de95c7 | |||
0939e8e493 | |||
6a33feee46 | |||
58b2ac702c | |||
175714f69a | |||
d5b70118a3 | |||
a9629f707e | |||
6123c72752 | |||
56afa5c2bf | |||
0c576dac82 | |||
8462372c03 | |||
20ff97d53d | |||
8ce5b6cc52 | |||
afb787d49d | |||
0b165b78a1 | |||
fa97488bdc | |||
3086081ec0 | |||
dfab44c24a | |||
1900246054 | |||
e980f92c63 | |||
ce3800e3ef | |||
e3d668f450 | |||
75b4bc5896 | |||
c0ecf32d17 | |||
3155f07ccd | |||
02bead5097 | |||
e8b29c9fd1 | |||
610f27d684 | |||
59466f6678 | |||
3ddd8f860e | |||
8535ec0819 | |||
f294121ab7 | |||
0b8ebaf387 | |||
3b00cfccec | |||
005391be81 | |||
bc8fffe347 | |||
914bbfd710 | |||
be31bd2bbd | |||
95ff817019 | |||
ea91e7638c | |||
4564e9810c | |||
44a1a8f6be | |||
9cecb22170 | |||
7693502aaa | |||
c0fae547e9 | |||
0ba77a0d87 | |||
661dcbb6ca | |||
578440a18d | |||
93485df3d2 | |||
121fab61f1 | |||
915eec7943 | |||
8432a1c758 | |||
4a5e108527 | |||
6dd5171fdf | |||
c2b6cb5c3a | |||
1f93040af6 | |||
52f8ccd06c | |||
3b86feab8a | |||
aba51d99a1 | |||
8454e8417e | |||
422e8285b5 | |||
bb6ca6b100 | |||
1483c1f545 | |||
3d6a68de77 | |||
387d387080 | |||
94ed35e781 | |||
8995b291a9 | |||
1942438b22 | |||
40d653e659 | |||
ddcd28e67f | |||
65f587d5e9 | |||
2fefd8cbbf | |||
ba17bdd366 | |||
c998e52cc0 | |||
3224369ac9 | |||
67666dbe0f | |||
d7430eb921 | |||
26a6b426f1 | |||
6f35ce67f7 | |||
3406d58797 | |||
7925458fc0 | |||
b6854aaf9f | |||
656f595226 | |||
280aaf9d3b | |||
7abdb05f91 | |||
af4464ce58 | |||
6ca0978777 | |||
8506194d2c | |||
3bd7614ade | |||
bd1b421491 | |||
920207f72c | |||
12fdc04f1b | |||
d0c744ae6a | |||
dc07fa7085 | |||
1c893996c0 | |||
a9ffc2a078 | |||
712bbfe575 | |||
0145fe3486 | |||
2a579eb27c | |||
5b42afa324 | |||
97713849a1 | |||
abc9c38224 | |||
f237ff049a | |||
00264650b5 | |||
2956d33bab | |||
c3eca637fb | |||
0d54bbff02 | |||
e65a9cbc00 | |||
3ed82c0882 | |||
475feb7e24 | |||
30b80cba92 | |||
fe519bd2a0 | |||
f508f8d959 | |||
e295c3c7c3 | |||
313be996cd | |||
2ae480556d | |||
7173fd7490 | |||
d792536c23 | |||
80aabdd372 | |||
6892369cc6 | |||
5b80a56c36 | |||
bf15535a5b | |||
edb1c52dee | |||
6e16b8cdcf | |||
24215fb3eb | |||
d02699a189 | |||
2034d1b101 | |||
5fe19d639f | |||
1dea80d4ea | |||
28f0008075 | |||
ffe1b00baf | |||
d2c289193a | |||
f867583256 | |||
98dfb92e17 | |||
c8f22be675 | |||
f03a7d1128 | |||
6da4a66c20 | |||
5e4241fc87 | |||
bf468c8d0c | |||
0d77a3f8d2 | |||
1b6edafc96 | |||
8152ade1b6 | |||
6350f8b904 | |||
0c5398a19c | |||
4b656268d3 | |||
10729a1fc5 | |||
cdb3ef808f | |||
a5a2471f2c | |||
6282747f6d | |||
d5fd5cad38 | |||
fab7c6b6d0 | |||
42ade6aa49 | |||
55d9b69cd9 | |||
2a8d6f943f | |||
6b0155c4fb | |||
e22a5143bc | |||
a17eb54515 | |||
d5cf1050db | |||
b021686521 | |||
b0e2bbce2a | |||
7a50ea7e36 | |||
3070cfc60b | |||
e56d1b718f | |||
c4c3067a31 | |||
81346fe641 | |||
1a66ad56c6 | |||
31f2adb79d | |||
f514ae309b | |||
277d3d98e3 | |||
2c46877b36 | |||
cfe54a02c5 | |||
55f390d08a | |||
cf31222643 | |||
9e036bcab5 | |||
d02170e3cb | |||
2d6f1af1a5 | |||
430457609f | |||
0333e26b3e | |||
d0d28566b9 | |||
872b787e6c | |||
01a99edf80 | |||
6050d37d2a | |||
876dce8e54 | |||
24885c28f2 | |||
5ea04bdfd3 | |||
9fdc1eaf3a | |||
6b5a70d246 | |||
8391d26220 | |||
f193e313a3 | |||
9ac4928113 | |||
9865779f14 | |||
aa6d0f9f0b | |||
68b0bd98fd | |||
3447798494 | |||
ca1b96f986 | |||
771fe35431 | |||
2f00ad1602 | |||
f740b71ded | |||
7aae58a543 | |||
c8da875f83 | |||
501d8a97f6 | |||
736e66fcda | |||
d3ad810f16 | |||
abc8b78065 | |||
f64e6b72e9 | |||
4e83b4400a | |||
f6f61513a1 | |||
8217817a0b | |||
833f54d818 | |||
706c086bc5 | |||
187add9b84 | |||
5b8e468a13 | |||
dff9c8f5fa | |||
21a8623002 | |||
ea9c5822e6 | |||
ad0d166d46 | |||
2c2ace9a60 | |||
8134a89e81 | |||
e342a0099f | |||
c4ed5030da | |||
7b9c24567d | |||
6906c5ce30 | |||
e4605f232b | |||
6092e737a1 | |||
0e4d954fa7 | |||
1cbba4d56f | |||
cf5d1f3f3c | |||
1097ac3682 | |||
755cc98ef7 | |||
5c407ff2e3 | |||
8f455ef199 | |||
7e0649d661 | |||
1a3dcb4f84 | |||
b606f1f73f | |||
8241f219fd | |||
dea45a3d6c | |||
34a812d45f | |||
842336834f | |||
58fe012446 | |||
bf0d40bca6 | |||
48e6658eca | |||
1bd3fb7a33 | |||
d86410a631 | |||
6b62502b99 | |||
053a075344 | |||
9dd7d19ce7 | |||
efe0f67388 | |||
de66d2bdfd | |||
0e4fe4d177 | |||
6d84db1e93 | |||
2486f3826a | |||
d7b8aa8b52 | |||
c7c0b01ec5 | |||
6d69047fff | |||
787ab12605 | |||
f4112accef | |||
42c394e28b | |||
5051d902fb | |||
48acfa08be | |||
39fc30b8b2 | |||
046cb248e0 | |||
31c746d9d7 | |||
38a2f32252 | |||
d55f54a8ab | |||
feb0e67fd7 | |||
a09bafbf2a | |||
03de7456ca | |||
78f2fd8d14 | |||
a048ed51a7 | |||
164a9231e8 | |||
aaa7e33778 | |||
f7008e2877 | |||
cf6e825547 | |||
38f9a3c49e | |||
f18283a517 | |||
61aec396e0 | |||
5ba9e63086 | |||
5acc56648d | |||
bc773039ca | |||
868fc2a29f | |||
81f69f12ab | |||
0711c3289f | |||
b8868d6d2d | |||
30bbc81a2e | |||
1a3f1d66c1 | |||
6bdd152d91 | |||
443c77b303 | |||
0dff771707 | |||
c9b6e4f825 | |||
abd02c7de4 | |||
eb4e0e4030 | |||
96dffcd27f | |||
0d0d87f600 | |||
2c779a4287 | |||
f25893832f | |||
af73a2d515 | |||
67a6b8723c | |||
fdccd85330 | |||
ca394fc8ab | |||
9c9ba0129f | |||
b61c91d93d | |||
f15732798f | |||
efbe655d6a | |||
27ced1d9c3 | |||
8f6bce3b87 | |||
be75f93d43 | |||
541fb181fe | |||
293b54192f | |||
0e0718d110 | |||
6fec0a7831 | |||
654ebebe3c | |||
08c3ca642e | |||
b3c46a87ac | |||
464d080518 | |||
227c04c9e6 | |||
e5d68aceed | |||
67d9241abc | |||
110dbcb31f | |||
740bf72f0c | |||
6b3b8607a0 | |||
b21c59ee70 | |||
fc2c96a177 | |||
87ba3f3cd3 | |||
b80b7b06fc | |||
ad6c97ec1b | |||
d3d97de312 | |||
bf915c3280 | |||
19c5cd130d | |||
1df2662924 | |||
f979050a45 | |||
45b68d444d | |||
732f79e758 | |||
4e954e32b8 | |||
92e81ccf50 | |||
91f2005067 | |||
7c80bf6f9d | |||
cc2c98c112 | |||
c3c0adbf55 | |||
04c305f273 | |||
8c8cf46b55 | |||
e96ae0c24a | |||
98a3cda260 | |||
1fd7fa5df7 | |||
3d3f2ed4c5 | |||
0f73050567 | |||
a40899e6be | |||
a9a15e2c54 | |||
896c258e44 | |||
6df42d63e2 | |||
33bf80b052 | |||
d5c1c0e9a4 | |||
8e61a6a6de | |||
ccaa2dd9e0 | |||
507ea757d7 | |||
9d526dfd50 | |||
ba89253e4a | |||
0d6f190e72 | |||
91b9a65db0 | |||
e96a5fb3ca | |||
f5f70f386d | |||
242efcf7fa | |||
51cc6fc257 | |||
5fb29cb772 | |||
2da894d4a7 | |||
2623b15ce0 | |||
6db9ad7002 | |||
889408136b | |||
886fefe738 | |||
768406f134 | |||
075e63b2bd | |||
0057c08a90 | |||
09b073356d | |||
3c9ed48630 | |||
65d8b4f544 | |||
6d18d4dcdd | |||
21fe2d519e | |||
9a7554fa01 | |||
37d1c13603 | |||
5ed112e946 | |||
453f112094 | |||
faa3341603 | |||
ee9cf05796 | |||
6de538b136 | |||
47c1072b78 | |||
e81f1e53bf | |||
cf92d2c6ef | |||
0507076c3f | |||
59fd3952b7 | |||
7fd80e6aa1 | |||
24fa6189b5 | |||
0bde9cbd91 | |||
122414d789 | |||
aac69674ad | |||
1a42154c64 | |||
e81cca304b | |||
07aa97aa9a | |||
94fba0b2aa | |||
80aa47f605 | |||
f16688817a | |||
2670a86005 | |||
0e369e6df8 | |||
84443b9c05 | |||
33be6803a3 | |||
aef2f1c66e | |||
619cd2d908 | |||
4613acd88e | |||
bf5c5626ab | |||
0fbbc67c3d | |||
3e1916ec3c | |||
b068a676dd | |||
ed73bdcfab | |||
ae94b705ea | |||
08fb921053 | |||
e67e57f8fb | |||
b30969704a | |||
646acc423e | |||
c3a81a23f9 | |||
103dd22151 | |||
ec6cb43711 | |||
84cb9a5986 | |||
9b8bc2aef7 | |||
9710d9e961 | |||
58bb49a78c | |||
df37739c7d | |||
a5dd5d161d | |||
6827107177 | |||
a30a89e57e | |||
d352e4abcb | |||
a948d4c1e1 | |||
b7eb3963f5 | |||
f7afb3cb75 | |||
348bf51a42 | |||
dfea2cc5f3 | |||
532eab8e1d | |||
3872382a4b | |||
4018693fbd | |||
3b829504f6 | |||
80fa51468c | |||
3504d2a4da | |||
229d8b9530 | |||
9536d460d0 | |||
e211e4839c | |||
3332dbe595 | |||
b9c8c08c03 | |||
663f22d849 | |||
fbaa4d1233 | |||
7dc8991140 | |||
0ce70b8c99 | |||
b169ea4b63 | |||
72ec4df679 | |||
b91263a254 | |||
e91afb1938 | |||
74eb613919 | |||
32d4310861 | |||
c56704f3fd | |||
c5118e9535 | |||
9b57566963 | |||
8d59e7afd1 | |||
fd733f76f0 | |||
37d4bb3df5 | |||
5697c6d7cc | |||
51a6162363 | |||
5a12b3d020 | |||
bebd2c469d | |||
d15e66a4ff | |||
c04d43695c | |||
d813334a24 | |||
9fef2f2eb4 | |||
0c746f4547 | |||
f5c8b1c6ac | |||
4921014c64 | |||
520753415f | |||
3162da131d | |||
a7354d2d08 | |||
07a9a2d0f3 | |||
c8c25549e7 | |||
6641a436a2 | |||
1dd50fb65f | |||
4bc4f77c29 | |||
ef36ecd376 | |||
c6cef853c7 | |||
33ad8d5db4 | |||
33e6d57754 | |||
afa57ca1f2 | |||
510dd02a06 | |||
166e88c103 | |||
51b6adeb24 | |||
51c19c374a | |||
b23452dc3f | |||
f61038e6bd | |||
b9117e2ff1 | |||
5a7a3da909 | |||
3f4502990a | |||
e14113aa0e | |||
d96289a81b | |||
4fc95b0d69 | |||
aa3d6c5363 | |||
5ac0cb929c | |||
b27ab53017 | |||
1aba294405 | |||
657e55ed59 | |||
621c25396e | |||
715ba918f0 | |||
8bb0a70847 | |||
94e79eddcf | |||
749a4028b4 | |||
fc55c2b57c | |||
d58ad2ee36 | |||
cb38ab4f85 | |||
fc86f6422d | |||
d453242e48 | |||
7c2ec075a4 | |||
c903de41e4 | |||
e8c8366308 | |||
4901567bba | |||
29bcd31b27 | |||
83a563c0ab | |||
e888fee4e0 | |||
c1ba11f531 | |||
ed558a0e70 | |||
6b9c3f4824 | |||
7ec819deed | |||
4cfb3678f8 | |||
3c17e2a7e6 | |||
e72b02b7cc | |||
82586c70e9 | |||
cb86bcc9e8 | |||
234708062a | |||
6e34f43721 | |||
3249ec8ebf | |||
31b2b21dbc | |||
d0c1936922 | |||
338a23a12b | |||
932def1ed2 | |||
16b5a11484 | |||
547fbce86c | |||
5a2eea07cb | |||
2231841d74 | |||
805a674825 | |||
f2925978f1 | |||
fe3a224a23 | |||
2754edc849 | |||
79f60274a0 | |||
a87c1c5e8e | |||
2b00b7d66d | |||
3d9286f089 | |||
55e6c15073 | |||
8b504e7d51 | |||
47ef2b343e | |||
80dcdb8645 | |||
d1c3bd8416 | |||
0240e182c6 | |||
7f2e3feb3c | |||
d15dd2795c | |||
0ea34fff27 | |||
4e8f212069 | |||
eb71d0ea7f | |||
b24ddb953c | |||
12f8fbe37f | |||
5e8312bc23 | |||
88d07058a5 | |||
b9e3cbbf44 | |||
3c0c87f473 | |||
7886e69236 |
19
.github/workflows/stale.yml
vendored
Normal file
19
.github/workflows/stale.yml
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
name: Mark stale issues and pull requests
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "30 1 * * *"
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
stale-issue-message: 'This issue is inactive for a long time.'
|
||||
stale-pr-message: 'This PR is inactive for a long time'
|
||||
stale-issue-label: 'inactive-issue'
|
||||
stale-pr-label: 'inactive-pr'
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -4,3 +4,9 @@
|
||||
*.swp
|
||||
*.swo
|
||||
beego.iml
|
||||
|
||||
_beeTmp/
|
||||
_beeTmp2/
|
||||
pkg/_beeTmp/
|
||||
pkg/_beeTmp2/
|
||||
test/tmp/
|
||||
|
@ -1,4 +0,0 @@
|
||||
github.com/astaxie/beego/*/*:S1012
|
||||
github.com/astaxie/beego/*:S1012
|
||||
github.com/astaxie/beego/*/*:S1007
|
||||
github.com/astaxie/beego/*:S1007
|
87
.travis.yml
87
.travis.yml
@ -1,62 +1,105 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.6.4
|
||||
- 1.7.5
|
||||
- 1.8.1
|
||||
- "1.14.x"
|
||||
services:
|
||||
- redis-server
|
||||
- mysql
|
||||
- postgresql
|
||||
- memcached
|
||||
- docker
|
||||
env:
|
||||
- ORM_DRIVER=sqlite3 ORM_SOURCE=$TRAVIS_BUILD_DIR/orm_test.db
|
||||
- ORM_DRIVER=mysql ORM_SOURCE="root:@/orm_test?charset=utf8"
|
||||
- ORM_DRIVER=postgres ORM_SOURCE="user=postgres dbname=orm_test sslmode=disable"
|
||||
global:
|
||||
- GO_REPO_FULLNAME="github.com/astaxie/beego"
|
||||
matrix:
|
||||
- ORM_DRIVER=sqlite3 ORM_SOURCE=$TRAVIS_BUILD_DIR/orm_test.db
|
||||
- ORM_DRIVER=postgres ORM_SOURCE="user=postgres dbname=orm_test sslmode=disable"
|
||||
- ORM_DRIVER=mysql export ORM_SOURCE="root:@/orm_test?charset=utf8"
|
||||
before_install:
|
||||
- git clone git://github.com/ideawu/ssdb.git
|
||||
- cd ssdb
|
||||
- make
|
||||
- cd ..
|
||||
# link the local repo with ${GOPATH}/src/<namespace>/<repo>
|
||||
- GO_REPO_NAMESPACE=${GO_REPO_FULLNAME%/*}
|
||||
# relies on GOPATH to contain only one directory...
|
||||
- mkdir -p ${GOPATH}/src/${GO_REPO_NAMESPACE}
|
||||
- ln -sv ${TRAVIS_BUILD_DIR} ${GOPATH}/src/${GO_REPO_FULLNAME}
|
||||
- cd ${GOPATH}/src/${GO_REPO_FULLNAME}
|
||||
# get and build ssdb
|
||||
- git clone git://github.com/ideawu/ssdb.git
|
||||
- cd ssdb
|
||||
- make
|
||||
- cd ..
|
||||
# - prepare etcd
|
||||
# - prepare for etcd unit tests
|
||||
- rm -rf /tmp/etcd-data.tmp
|
||||
- mkdir -p /tmp/etcd-data.tmp
|
||||
- docker rmi gcr.io/etcd-development/etcd:v3.3.25 || true &&
|
||||
docker run -d
|
||||
-p 2379:2379
|
||||
-p 2380:2380
|
||||
--mount type=bind,source=/tmp/etcd-data.tmp,destination=/etcd-data
|
||||
--name etcd-gcr-v3.3.25
|
||||
gcr.io/etcd-development/etcd:v3.3.25
|
||||
/usr/local/bin/etcd
|
||||
--name s1
|
||||
--data-dir /etcd-data
|
||||
--listen-client-urls http://0.0.0.0:2379
|
||||
--advertise-client-urls http://0.0.0.0:2379
|
||||
--listen-peer-urls http://0.0.0.0:2380
|
||||
--initial-advertise-peer-urls http://0.0.0.0:2380
|
||||
--initial-cluster s1=http://0.0.0.0:2380
|
||||
--initial-cluster-token tkn
|
||||
--initial-cluster-state new
|
||||
- docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.float 1.23"
|
||||
- docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.bool true"
|
||||
- docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.int 11"
|
||||
- docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.string hello"
|
||||
- docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.serialize.name test"
|
||||
- docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put sub.sub.key1 sub.sub.key"
|
||||
install:
|
||||
- go get github.com/lib/pq
|
||||
- go get github.com/go-sql-driver/mysql
|
||||
- go get github.com/mattn/go-sqlite3
|
||||
- go get github.com/bradfitz/gomemcache/memcache
|
||||
- go get github.com/garyburd/redigo/redis
|
||||
- go get github.com/gomodule/redigo/redis
|
||||
- go get github.com/beego/x2j
|
||||
- go get github.com/couchbase/go-couchbase
|
||||
- go get github.com/beego/goyaml2
|
||||
- go get gopkg.in/yaml.v2
|
||||
- go get github.com/belogik/goes
|
||||
- go get github.com/siddontang/ledisdb/config
|
||||
- go get github.com/siddontang/ledisdb/ledis
|
||||
- go get github.com/ledisdb/ledisdb
|
||||
- go get github.com/ssdb/gossdb/ssdb
|
||||
- go get github.com/cloudflare/golz4
|
||||
- go get github.com/gogo/protobuf/proto
|
||||
- go get github.com/Knetic/govaluate
|
||||
- go get github.com/hsluoyz/casbin
|
||||
- go get -u honnef.co/go/tools/cmd/gosimple
|
||||
- go get github.com/casbin/casbin
|
||||
- go get github.com/elazarl/go-bindata-assetfs
|
||||
- go get github.com/OwnLocal/goes
|
||||
- go get github.com/shiena/ansicolor
|
||||
- go get -u honnef.co/go/tools/cmd/staticcheck
|
||||
- go get -u github.com/mdempsky/unconvert
|
||||
- go get -u github.com/gordonklaus/ineffassign
|
||||
- go get -u github.com/golang/lint/golint
|
||||
- go get -u golang.org/x/lint/golint
|
||||
- go get -u github.com/go-redis/redis
|
||||
before_script:
|
||||
|
||||
# -
|
||||
- psql --version
|
||||
# - prepare for orm unit tests
|
||||
- sh -c "if [ '$ORM_DRIVER' = 'postgres' ]; then psql -c 'create database orm_test;' -U postgres; fi"
|
||||
- sh -c "if [ '$ORM_DRIVER' = 'mysql' ]; then mysql -u root -e 'create database orm_test;'; fi"
|
||||
- sh -c "if [ '$ORM_DRIVER' = 'sqlite' ]; then touch $TRAVIS_BUILD_DIR/orm_test.db; fi"
|
||||
- sh -c "if [ $(go version) == *1.[5-9]* ]; then go get github.com/golang/lint/golint; golint ./...; fi"
|
||||
- sh -c "if [ $(go version) == *1.[5-9]* ]; then go tool vet .; fi"
|
||||
- sh -c "go get github.com/golang/lint/golint; golint ./...;"
|
||||
- sh -c "go list ./... | grep -v vendor | xargs go vet -v"
|
||||
- mkdir -p res/var
|
||||
- ./ssdb/ssdb-server ./ssdb/ssdb.conf -d
|
||||
after_script:
|
||||
-killall -w ssdb-server
|
||||
- killall -w ssdb-server
|
||||
- rm -rf ./res/var/*
|
||||
script:
|
||||
- go test -v ./...
|
||||
- gosimple -ignore "$(cat .gosimpleignore)" $(go list ./... | grep -v /vendor/)
|
||||
- go test ./...
|
||||
- staticcheck -show-ignored -checks "-ST1017,-U1000,-ST1005,-S1034,-S1012,-SA4006,-SA6005,-SA1019,-SA1024" ./
|
||||
- unconvert $(go list ./... | grep -v /vendor/)
|
||||
- ineffassign .
|
||||
- find . ! \( -path './vendor' -prune \) -type f -name '*.go' -print0 | xargs -0 gofmt -l -s
|
||||
- golint ./...
|
||||
addons:
|
||||
postgresql: "9.4"
|
||||
postgresql: "9.6"
|
@ -7,17 +7,58 @@ It is the work of hundreds of contributors. We appreciate your help!
|
||||
Here are instructions to get you started. They are probably not perfect,
|
||||
please let us know if anything feels wrong or incomplete.
|
||||
|
||||
## Prepare environment
|
||||
|
||||
Firstly, install some tools. Execute those commands **outside** the project. Or those command will modify go.mod file.
|
||||
|
||||
```shell script
|
||||
go get -u golang.org/x/tools/cmd/goimports
|
||||
|
||||
go get -u github.com/gordonklaus/ineffassign
|
||||
```
|
||||
|
||||
Put those lines into your pre-commit githook script:
|
||||
```shell script
|
||||
goimports -w -format-only ./
|
||||
|
||||
ineffassign .
|
||||
|
||||
staticcheck -show-ignored -checks "-ST1017,-U1000,-ST1005,-S1034,-S1012,-SA4006,-SA6005,-SA1019,-SA1024" ./
|
||||
```
|
||||
|
||||
## Prepare middleware
|
||||
|
||||
Beego uses many middlewares, including MySQL, Redis, SSDB and so on.
|
||||
|
||||
We provide docker compose file to start all middlewares.
|
||||
|
||||
You can run:
|
||||
```shell script
|
||||
docker-compose -f scripts/test_docker_compose.yml up -d
|
||||
```
|
||||
Unit tests read addresses from environment, here is an example:
|
||||
```shell script
|
||||
export ORM_DRIVER=mysql
|
||||
export ORM_SOURCE="beego:test@tcp(192.168.0.105:13306)/orm_test?charset=utf8"
|
||||
export MEMCACHE_ADDR="192.168.0.105:11211"
|
||||
export REDIS_ADDR="192.168.0.105:6379"
|
||||
export SSDB_ADDR="192.168.0.105:8888"
|
||||
```
|
||||
|
||||
|
||||
## Contribution guidelines
|
||||
|
||||
### Pull requests
|
||||
|
||||
First of all. beego follow the gitflow. So please send you pull request
|
||||
to **develop** branch. We will close the pull request to master branch.
|
||||
to **develop-2** branch. We will close the pull request to master branch.
|
||||
|
||||
We are always happy to receive pull requests, and do our best to
|
||||
review them as fast as possible. Not sure if that typo is worth a pull
|
||||
request? Do it! We will appreciate it.
|
||||
|
||||
Don't forget to rebase your commits!
|
||||
|
||||
If your pull request is not accepted on the first try, don't be
|
||||
discouraged! Sometimes we can make a mistake, please do more explaining
|
||||
for us. We will appreciate it.
|
||||
@ -48,5 +89,5 @@ documenting your bug report or improvement proposal. If it does, it
|
||||
never hurts to add a quick "+1" or "I have this problem too". This will
|
||||
help prioritize the most common problems and requests.
|
||||
|
||||
Also if you don't know how to use it. please make sure you have read though
|
||||
Also, if you don't know how to use it. please make sure you have read through
|
||||
the docs in http://beego.me/docs
|
222
README.md
222
README.md
@ -1,4 +1,5 @@
|
||||
# Beego [](https://travis-ci.org/astaxie/beego) [](http://godoc.org/github.com/astaxie/beego) [](http://golangfoundation.org)
|
||||
# Beego [](https://travis-ci.org/astaxie/beego) [](http://godoc.org/github.com/astaxie/beego) [](http://golangfoundation.org) [](https://goreportcard.com/report/github.com/astaxie/beego)
|
||||
|
||||
|
||||
beego is used for rapid development of RESTful APIs, web apps and backend services in Go.
|
||||
It is inspired by Tornado, Sinatra and Flask. beego has some Go-specific features such as interfaces and struct embedding.
|
||||
@ -7,6 +8,21 @@ It is inspired by Tornado, Sinatra and Flask. beego has some Go-specific feature
|
||||
|
||||
## Quick Start
|
||||
|
||||
###### Please see [Documentation](http://beego.me/docs) for more.
|
||||
|
||||
###### [beego-example](https://github.com/beego-dev/beego-example)
|
||||
|
||||
### Web Application
|
||||
|
||||
#### Create `hello` directory, cd `hello` directory
|
||||
|
||||
mkdir hello
|
||||
cd hello
|
||||
|
||||
#### Init module
|
||||
|
||||
go mod init
|
||||
|
||||
#### Download and install
|
||||
|
||||
go get github.com/astaxie/beego
|
||||
@ -15,10 +31,10 @@ It is inspired by Tornado, Sinatra and Flask. beego has some Go-specific feature
|
||||
```go
|
||||
package main
|
||||
|
||||
import "github.com/astaxie/beego"
|
||||
import "github.com/astaxie/beego/server/web"
|
||||
|
||||
func main(){
|
||||
beego.Run()
|
||||
web.Run()
|
||||
}
|
||||
```
|
||||
#### Build and run
|
||||
@ -30,7 +46,204 @@ func main(){
|
||||
|
||||
Congratulations! You've just built your first **beego** app.
|
||||
|
||||
###### Please see [Documentation](http://beego.me/docs) for more.
|
||||
### Using ORM module
|
||||
|
||||
```go
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/client/orm"
|
||||
"github.com/astaxie/beego/core/logs"
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
)
|
||||
|
||||
// User -
|
||||
type User struct {
|
||||
ID int `orm:"column(id)"`
|
||||
Name string `orm:"column(name)"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
// need to register models in init
|
||||
orm.RegisterModel(new(User))
|
||||
|
||||
// need to register db driver
|
||||
orm.RegisterDriver("mysql", orm.DRMySQL)
|
||||
|
||||
// need to register default database
|
||||
orm.RegisterDataBase("default", "mysql", "beego:test@tcp(192.168.0.105:13306)/orm_test?charset=utf8")
|
||||
}
|
||||
|
||||
func main() {
|
||||
// automatically build table
|
||||
orm.RunSyncdb("default", false, true)
|
||||
|
||||
// create orm object, and it will use `default` database
|
||||
o := orm.NewOrm()
|
||||
|
||||
// data
|
||||
user := new(User)
|
||||
user.Name = "mike"
|
||||
|
||||
// insert data
|
||||
id, err := o.Insert(user)
|
||||
if err != nil {
|
||||
logs.Info(err)
|
||||
}
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Using httplib as http client
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/client/httplib"
|
||||
"github.com/astaxie/beego/core/logs"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Get, more methods please read docs
|
||||
req := httplib.Get("http://beego.me/")
|
||||
str, err := req.String()
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
}
|
||||
logs.Info(str)
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
### Using config module
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/astaxie/beego/core/config"
|
||||
"github.com/astaxie/beego/core/logs"
|
||||
)
|
||||
|
||||
var (
|
||||
ConfigFile = "./app.conf"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cfg, err := config.NewConfig("ini", ConfigFile)
|
||||
if err != nil {
|
||||
logs.Critical("An error occurred:", err)
|
||||
panic(err)
|
||||
}
|
||||
res, _ := cfg.String(context.Background(), "name")
|
||||
logs.Info("load config name is", res)
|
||||
}
|
||||
```
|
||||
### Using logs module
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/core/logs"
|
||||
)
|
||||
|
||||
func main() {
|
||||
err := logs.SetLogger(logs.AdapterFile, `{"filename":"project.log","level":7,"maxlines":0,"maxsize":0,"daily":true,"maxdays":10,"color":true}`)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
logs.Info("hello beego")
|
||||
}
|
||||
```
|
||||
### Using timed task
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego/core/logs"
|
||||
"github.com/astaxie/beego/task"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// create a task
|
||||
tk1 := task.NewTask("tk1", "0/3 * * * * *", func(ctx context.Context) error { logs.Info("tk1"); return nil })
|
||||
|
||||
// check task
|
||||
err := tk1.Run(context.Background())
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
}
|
||||
|
||||
// add task to global todolist
|
||||
task.AddTask("tk1", tk1)
|
||||
|
||||
// start tasks
|
||||
task.StartTask()
|
||||
|
||||
// wait 12 second
|
||||
time.Sleep(12 * time.Second)
|
||||
defer task.StopTask()
|
||||
}
|
||||
```
|
||||
|
||||
### Using cache module
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego/client/cache"
|
||||
|
||||
// don't forget this
|
||||
_ "github.com/astaxie/beego/client/cache/redis"
|
||||
|
||||
"github.com/astaxie/beego/core/logs"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// create cache
|
||||
bm, err := cache.NewCache("redis", `{"key":"default", "conn":":6379", "password":"123456", "dbNum":"0"}`)
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
}
|
||||
|
||||
// put
|
||||
isPut := bm.Put(context.Background(), "astaxie", 1, time.Second*10)
|
||||
logs.Info(isPut)
|
||||
|
||||
isPut = bm.Put(context.Background(), "hello", "world", time.Second*10)
|
||||
logs.Info(isPut)
|
||||
|
||||
// get
|
||||
result, _ := bm.Get(context.Background(),"astaxie")
|
||||
logs.Info(string(result.([]byte)))
|
||||
|
||||
multiResult, _ := bm.GetMulti(context.Background(), []string{"astaxie", "hello"})
|
||||
for i := range multiResult {
|
||||
logs.Info(string(multiResult[i].([]byte)))
|
||||
}
|
||||
|
||||
// isExist
|
||||
isExist, _ := bm.IsExist(context.Background(), "astaxie")
|
||||
logs.Info(isExist)
|
||||
|
||||
// delete
|
||||
isDelete := bm.Delete(context.Background(), "astaxie")
|
||||
logs.Info(isDelete)
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
@ -53,6 +266,7 @@ Congratulations! You've just built your first **beego** app.
|
||||
|
||||
* [http://beego.me/community](http://beego.me/community)
|
||||
* Welcome to join us in Slack: [https://beego.slack.com](https://beego.slack.com), you can get invited from [here](https://github.com/beego/beedoc/issues/232)
|
||||
* QQ Group Group ID:523992905
|
||||
|
||||
## License
|
||||
|
||||
|
45
adapter/admin.go
Normal file
45
adapter/admin.go
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package adapter
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
_ "github.com/astaxie/beego/core/governor"
|
||||
"github.com/astaxie/beego/server/web"
|
||||
)
|
||||
|
||||
// FilterMonitorFunc is default monitor filter when admin module is enable.
|
||||
// if this func returns, admin module records qps for this request by condition of this function logic.
|
||||
// usage:
|
||||
// func MyFilterMonitor(method, requestPath string, t time.Duration, pattern string, statusCode int) bool {
|
||||
// if method == "POST" {
|
||||
// return false
|
||||
// }
|
||||
// if t.Nanoseconds() < 100 {
|
||||
// return false
|
||||
// }
|
||||
// if strings.HasPrefix(requestPath, "/astaxie") {
|
||||
// return false
|
||||
// }
|
||||
// return true
|
||||
// }
|
||||
// beego.FilterMonitorFunc = MyFilterMonitor.
|
||||
var FilterMonitorFunc func(string, string, time.Duration, string, int) bool
|
||||
|
||||
// PrintTree prints all registered routers.
|
||||
func PrintTree() M {
|
||||
return (M)(web.BeeApp.PrintTree())
|
||||
}
|
@ -12,20 +12,14 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package beego
|
||||
package adapter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/fcgi"
|
||||
"os"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego/grace"
|
||||
"github.com/astaxie/beego/logs"
|
||||
"github.com/astaxie/beego/utils"
|
||||
context2 "github.com/astaxie/beego/adapter/context"
|
||||
"github.com/astaxie/beego/server/web"
|
||||
"github.com/astaxie/beego/server/web/context"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -35,159 +29,36 @@ var (
|
||||
|
||||
func init() {
|
||||
// create beego application
|
||||
BeeApp = NewApp()
|
||||
BeeApp = (*App)(web.BeeApp)
|
||||
}
|
||||
|
||||
// App defines beego application with a new PatternServeMux.
|
||||
type App struct {
|
||||
Handlers *ControllerRegister
|
||||
Server *http.Server
|
||||
}
|
||||
type App web.HttpServer
|
||||
|
||||
// NewApp returns a new beego application.
|
||||
func NewApp() *App {
|
||||
cr := NewControllerRegister()
|
||||
app := &App{Handlers: cr, Server: &http.Server{}}
|
||||
return app
|
||||
return (*App)(web.NewHttpSever())
|
||||
}
|
||||
|
||||
// MiddleWare function for http.Handler
|
||||
type MiddleWare web.MiddleWare
|
||||
|
||||
// Run beego application.
|
||||
func (app *App) Run() {
|
||||
addr := BConfig.Listen.HTTPAddr
|
||||
func (app *App) Run(mws ...MiddleWare) {
|
||||
newMws := oldMiddlewareToNew(mws)
|
||||
(*web.HttpServer)(app).Run("", newMws...)
|
||||
}
|
||||
|
||||
if BConfig.Listen.HTTPPort != 0 {
|
||||
addr = fmt.Sprintf("%s:%d", BConfig.Listen.HTTPAddr, BConfig.Listen.HTTPPort)
|
||||
func oldMiddlewareToNew(mws []MiddleWare) []web.MiddleWare {
|
||||
newMws := make([]web.MiddleWare, 0, len(mws))
|
||||
for _, old := range mws {
|
||||
newMws = append(newMws, (web.MiddleWare)(old))
|
||||
}
|
||||
|
||||
var (
|
||||
err error
|
||||
l net.Listener
|
||||
endRunning = make(chan bool, 1)
|
||||
)
|
||||
|
||||
// run cgi server
|
||||
if BConfig.Listen.EnableFcgi {
|
||||
if BConfig.Listen.EnableStdIo {
|
||||
if err = fcgi.Serve(nil, app.Handlers); err == nil { // standard I/O
|
||||
logs.Info("Use FCGI via standard I/O")
|
||||
} else {
|
||||
logs.Critical("Cannot use FCGI via standard I/O", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if BConfig.Listen.HTTPPort == 0 {
|
||||
// remove the Socket file before start
|
||||
if utils.FileExists(addr) {
|
||||
os.Remove(addr)
|
||||
}
|
||||
l, err = net.Listen("unix", addr)
|
||||
} else {
|
||||
l, err = net.Listen("tcp", addr)
|
||||
}
|
||||
if err != nil {
|
||||
logs.Critical("Listen: ", err)
|
||||
}
|
||||
if err = fcgi.Serve(l, app.Handlers); err != nil {
|
||||
logs.Critical("fcgi.Serve: ", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
app.Server.Handler = app.Handlers
|
||||
app.Server.ReadTimeout = time.Duration(BConfig.Listen.ServerTimeOut) * time.Second
|
||||
app.Server.WriteTimeout = time.Duration(BConfig.Listen.ServerTimeOut) * time.Second
|
||||
app.Server.ErrorLog = logs.GetLogger("HTTP")
|
||||
|
||||
// run graceful mode
|
||||
if BConfig.Listen.Graceful {
|
||||
httpsAddr := BConfig.Listen.HTTPSAddr
|
||||
app.Server.Addr = httpsAddr
|
||||
if BConfig.Listen.EnableHTTPS {
|
||||
go func() {
|
||||
time.Sleep(20 * time.Microsecond)
|
||||
if BConfig.Listen.HTTPSPort != 0 {
|
||||
httpsAddr = fmt.Sprintf("%s:%d", BConfig.Listen.HTTPSAddr, BConfig.Listen.HTTPSPort)
|
||||
app.Server.Addr = httpsAddr
|
||||
}
|
||||
server := grace.NewServer(httpsAddr, app.Handlers)
|
||||
server.Server.ReadTimeout = app.Server.ReadTimeout
|
||||
server.Server.WriteTimeout = app.Server.WriteTimeout
|
||||
if err := server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile); err != nil {
|
||||
logs.Critical("ListenAndServeTLS: ", err, fmt.Sprintf("%d", os.Getpid()))
|
||||
time.Sleep(100 * time.Microsecond)
|
||||
endRunning <- true
|
||||
}
|
||||
}()
|
||||
}
|
||||
if BConfig.Listen.EnableHTTP {
|
||||
go func() {
|
||||
server := grace.NewServer(addr, app.Handlers)
|
||||
server.Server.ReadTimeout = app.Server.ReadTimeout
|
||||
server.Server.WriteTimeout = app.Server.WriteTimeout
|
||||
if BConfig.Listen.ListenTCP4 {
|
||||
server.Network = "tcp4"
|
||||
}
|
||||
if err := server.ListenAndServe(); err != nil {
|
||||
logs.Critical("ListenAndServe: ", err, fmt.Sprintf("%d", os.Getpid()))
|
||||
time.Sleep(100 * time.Microsecond)
|
||||
endRunning <- true
|
||||
}
|
||||
}()
|
||||
}
|
||||
<-endRunning
|
||||
return
|
||||
}
|
||||
|
||||
// run normal mode
|
||||
if BConfig.Listen.EnableHTTPS {
|
||||
go func() {
|
||||
time.Sleep(20 * time.Microsecond)
|
||||
if BConfig.Listen.HTTPSPort != 0 {
|
||||
app.Server.Addr = fmt.Sprintf("%s:%d", BConfig.Listen.HTTPSAddr, BConfig.Listen.HTTPSPort)
|
||||
} else if BConfig.Listen.EnableHTTP {
|
||||
BeeLogger.Info("Start https server error, confict with http.Please reset https port")
|
||||
return
|
||||
}
|
||||
logs.Info("https server Running on https://%s", app.Server.Addr)
|
||||
if err := app.Server.ListenAndServeTLS(BConfig.Listen.HTTPSCertFile, BConfig.Listen.HTTPSKeyFile); err != nil {
|
||||
logs.Critical("ListenAndServeTLS: ", err)
|
||||
time.Sleep(100 * time.Microsecond)
|
||||
endRunning <- true
|
||||
}
|
||||
}()
|
||||
}
|
||||
if BConfig.Listen.EnableHTTP {
|
||||
go func() {
|
||||
app.Server.Addr = addr
|
||||
logs.Info("http server Running on http://%s", app.Server.Addr)
|
||||
if BConfig.Listen.ListenTCP4 {
|
||||
ln, err := net.Listen("tcp4", app.Server.Addr)
|
||||
if err != nil {
|
||||
logs.Critical("ListenAndServe: ", err)
|
||||
time.Sleep(100 * time.Microsecond)
|
||||
endRunning <- true
|
||||
return
|
||||
}
|
||||
if err = app.Server.Serve(ln); err != nil {
|
||||
logs.Critical("ListenAndServe: ", err)
|
||||
time.Sleep(100 * time.Microsecond)
|
||||
endRunning <- true
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err := app.Server.ListenAndServe(); err != nil {
|
||||
logs.Critical("ListenAndServe: ", err)
|
||||
time.Sleep(100 * time.Microsecond)
|
||||
endRunning <- true
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
<-endRunning
|
||||
return newMws
|
||||
}
|
||||
|
||||
// Router adds a patterned controller handler to BeeApp.
|
||||
// it's an alias method of App.Router.
|
||||
// it's an alias method of HttpServer.Router.
|
||||
// usage:
|
||||
// simple router
|
||||
// beego.Router("/admin", &admin.UserController{})
|
||||
@ -203,8 +74,20 @@ func (app *App) Run() {
|
||||
// beego.Router("/api/update",&RestController{},"put:UpdateFood")
|
||||
// beego.Router("/api/delete",&RestController{},"delete:DeleteFood")
|
||||
func Router(rootpath string, c ControllerInterface, mappingMethods ...string) *App {
|
||||
BeeApp.Handlers.Add(rootpath, c, mappingMethods...)
|
||||
return BeeApp
|
||||
return (*App)(web.Router(rootpath, c, mappingMethods...))
|
||||
}
|
||||
|
||||
// UnregisterFixedRoute unregisters the route with the specified fixedRoute. It is particularly useful
|
||||
// in web applications that inherit most routes from a base webapp via the underscore
|
||||
// import, and aim to overwrite only certain paths.
|
||||
// The method parameter can be empty or "*" for all HTTP methods, or a particular
|
||||
// method type (e.g. "GET" or "POST") for selective removal.
|
||||
//
|
||||
// Usage (replace "GET" with "*" for all methods):
|
||||
// beego.UnregisterFixedRoute("/yourpreviouspath", "GET")
|
||||
// beego.Router("/yourpreviouspath", yourControllerAddress, "get:GetNewPage")
|
||||
func UnregisterFixedRoute(fixedRoute string, method string) *App {
|
||||
return (*App)(web.UnregisterFixedRoute(fixedRoute, method))
|
||||
}
|
||||
|
||||
// Include will generate router file in the router/xxx.go from the controller's comments
|
||||
@ -218,7 +101,7 @@ func Router(rootpath string, c ControllerInterface, mappingMethods ...string) *A
|
||||
// func (b *BankAccount)Mapping(){
|
||||
// b.Mapping("ShowAccount" , b.ShowAccount)
|
||||
// b.Mapping("ModifyAccount", b.ModifyAccount)
|
||||
//}
|
||||
// }
|
||||
//
|
||||
// //@router /account/:id [get]
|
||||
// func (b *BankAccount) ShowAccount(){
|
||||
@ -235,35 +118,39 @@ func Router(rootpath string, c ControllerInterface, mappingMethods ...string) *A
|
||||
// url support all the function Router's pattern
|
||||
// methodlist [get post head put delete options *]
|
||||
func Include(cList ...ControllerInterface) *App {
|
||||
BeeApp.Handlers.Include(cList...)
|
||||
return BeeApp
|
||||
newList := oldToNewCtrlIntfs(cList)
|
||||
return (*App)(web.Include(newList...))
|
||||
}
|
||||
|
||||
func oldToNewCtrlIntfs(cList []ControllerInterface) []web.ControllerInterface {
|
||||
newList := make([]web.ControllerInterface, 0, len(cList))
|
||||
for _, c := range cList {
|
||||
newList = append(newList, c)
|
||||
}
|
||||
return newList
|
||||
}
|
||||
|
||||
// RESTRouter adds a restful controller handler to BeeApp.
|
||||
// its' controller implements beego.ControllerInterface and
|
||||
// defines a param "pattern/:objectId" to visit each resource.
|
||||
func RESTRouter(rootpath string, c ControllerInterface) *App {
|
||||
Router(rootpath, c)
|
||||
Router(path.Join(rootpath, ":objectId"), c)
|
||||
return BeeApp
|
||||
return (*App)(web.RESTRouter(rootpath, c))
|
||||
}
|
||||
|
||||
// AutoRouter adds defined controller handler to BeeApp.
|
||||
// it's same to App.AutoRouter.
|
||||
// it's same to HttpServer.AutoRouter.
|
||||
// if beego.AddAuto(&MainContorlller{}) and MainController has methods List and Page,
|
||||
// visit the url /main/list to exec List function or /main/page to exec Page function.
|
||||
func AutoRouter(c ControllerInterface) *App {
|
||||
BeeApp.Handlers.AddAuto(c)
|
||||
return BeeApp
|
||||
return (*App)(web.AutoRouter(c))
|
||||
}
|
||||
|
||||
// AutoPrefix adds controller handler to BeeApp with prefix.
|
||||
// it's same to App.AutoRouterWithPrefix.
|
||||
// it's same to HttpServer.AutoRouterWithPrefix.
|
||||
// if beego.AutoPrefix("/admin",&MainContorlller{}) and MainController has methods List and Page,
|
||||
// visit the url /admin/main/list to exec List function or /admin/main/page to exec Page function.
|
||||
func AutoPrefix(prefix string, c ControllerInterface) *App {
|
||||
BeeApp.Handlers.AddAutoPrefix(prefix, c)
|
||||
return BeeApp
|
||||
return (*App)(web.AutoPrefix(prefix, c))
|
||||
}
|
||||
|
||||
// Get used to register router for Get method
|
||||
@ -272,8 +159,9 @@ func AutoPrefix(prefix string, c ControllerInterface) *App {
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
func Get(rootpath string, f FilterFunc) *App {
|
||||
BeeApp.Handlers.Get(rootpath, f)
|
||||
return BeeApp
|
||||
return (*App)(web.Get(rootpath, func(ctx *context.Context) {
|
||||
f((*context2.Context)(ctx))
|
||||
}))
|
||||
}
|
||||
|
||||
// Post used to register router for Post method
|
||||
@ -282,8 +170,9 @@ func Get(rootpath string, f FilterFunc) *App {
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
func Post(rootpath string, f FilterFunc) *App {
|
||||
BeeApp.Handlers.Post(rootpath, f)
|
||||
return BeeApp
|
||||
return (*App)(web.Post(rootpath, func(ctx *context.Context) {
|
||||
f((*context2.Context)(ctx))
|
||||
}))
|
||||
}
|
||||
|
||||
// Delete used to register router for Delete method
|
||||
@ -292,8 +181,9 @@ func Post(rootpath string, f FilterFunc) *App {
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
func Delete(rootpath string, f FilterFunc) *App {
|
||||
BeeApp.Handlers.Delete(rootpath, f)
|
||||
return BeeApp
|
||||
return (*App)(web.Delete(rootpath, func(ctx *context.Context) {
|
||||
f((*context2.Context)(ctx))
|
||||
}))
|
||||
}
|
||||
|
||||
// Put used to register router for Put method
|
||||
@ -302,8 +192,9 @@ func Delete(rootpath string, f FilterFunc) *App {
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
func Put(rootpath string, f FilterFunc) *App {
|
||||
BeeApp.Handlers.Put(rootpath, f)
|
||||
return BeeApp
|
||||
return (*App)(web.Put(rootpath, func(ctx *context.Context) {
|
||||
f((*context2.Context)(ctx))
|
||||
}))
|
||||
}
|
||||
|
||||
// Head used to register router for Head method
|
||||
@ -312,8 +203,9 @@ func Put(rootpath string, f FilterFunc) *App {
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
func Head(rootpath string, f FilterFunc) *App {
|
||||
BeeApp.Handlers.Head(rootpath, f)
|
||||
return BeeApp
|
||||
return (*App)(web.Head(rootpath, func(ctx *context.Context) {
|
||||
f((*context2.Context)(ctx))
|
||||
}))
|
||||
}
|
||||
|
||||
// Options used to register router for Options method
|
||||
@ -322,8 +214,9 @@ func Head(rootpath string, f FilterFunc) *App {
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
func Options(rootpath string, f FilterFunc) *App {
|
||||
BeeApp.Handlers.Options(rootpath, f)
|
||||
return BeeApp
|
||||
return (*App)(web.Options(rootpath, func(ctx *context.Context) {
|
||||
f((*context2.Context)(ctx))
|
||||
}))
|
||||
}
|
||||
|
||||
// Patch used to register router for Patch method
|
||||
@ -332,8 +225,9 @@ func Options(rootpath string, f FilterFunc) *App {
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
func Patch(rootpath string, f FilterFunc) *App {
|
||||
BeeApp.Handlers.Patch(rootpath, f)
|
||||
return BeeApp
|
||||
return (*App)(web.Patch(rootpath, func(ctx *context.Context) {
|
||||
f((*context2.Context)(ctx))
|
||||
}))
|
||||
}
|
||||
|
||||
// Any used to register router for all methods
|
||||
@ -342,8 +236,9 @@ func Patch(rootpath string, f FilterFunc) *App {
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
func Any(rootpath string, f FilterFunc) *App {
|
||||
BeeApp.Handlers.Any(rootpath, f)
|
||||
return BeeApp
|
||||
return (*App)(web.Any(rootpath, func(ctx *context.Context) {
|
||||
f((*context2.Context)(ctx))
|
||||
}))
|
||||
}
|
||||
|
||||
// Handler used to register a Handler router
|
||||
@ -352,8 +247,7 @@ func Any(rootpath string, f FilterFunc) *App {
|
||||
// fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
|
||||
// }))
|
||||
func Handler(rootpath string, h http.Handler, options ...interface{}) *App {
|
||||
BeeApp.Handlers.Handler(rootpath, h, options...)
|
||||
return BeeApp
|
||||
return (*App)(web.Handler(rootpath, h, options))
|
||||
}
|
||||
|
||||
// InsertFilter adds a FilterFunc with pattern condition and action constant.
|
||||
@ -361,6 +255,8 @@ func Handler(rootpath string, h http.Handler, options ...interface{}) *App {
|
||||
// beego.BeforeStatic, beego.BeforeRouter, beego.BeforeExec, beego.AfterExec and beego.FinishRouter.
|
||||
// The bool params is for setting the returnOnOutput value (false allows multiple filters to execute)
|
||||
func InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) *App {
|
||||
BeeApp.Handlers.InsertFilter(pattern, pos, filter, params...)
|
||||
return BeeApp
|
||||
opts := oldToNewFilterOpts(params)
|
||||
return (*App)(web.InsertFilter(pattern, pos, func(ctx *context.Context) {
|
||||
filter((*context2.Context)(ctx))
|
||||
}, opts...))
|
||||
}
|
77
adapter/beego.go
Normal file
77
adapter/beego.go
Normal file
@ -0,0 +1,77 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package adapter
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/astaxie/beego/server/web"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
// VERSION represent beego web framework version.
|
||||
VERSION = beego.VERSION
|
||||
|
||||
// DEV is for develop
|
||||
DEV = web.DEV
|
||||
// PROD is for production
|
||||
PROD = web.PROD
|
||||
)
|
||||
|
||||
// M is Map shortcut
|
||||
type M web.M
|
||||
|
||||
// Hook function to run
|
||||
type hookfunc func() error
|
||||
|
||||
var (
|
||||
hooks = make([]hookfunc, 0) // hook function slice to store the hookfunc
|
||||
)
|
||||
|
||||
// AddAPPStartHook is used to register the hookfunc
|
||||
// The hookfuncs will run in beego.Run()
|
||||
// such as initiating session , starting middleware , building template, starting admin control and so on.
|
||||
func AddAPPStartHook(hf ...hookfunc) {
|
||||
for _, f := range hf {
|
||||
web.AddAPPStartHook(func() error {
|
||||
return f()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Run beego application.
|
||||
// beego.Run() default run on HttpPort
|
||||
// beego.Run("localhost")
|
||||
// beego.Run(":8089")
|
||||
// beego.Run("127.0.0.1:8089")
|
||||
func Run(params ...string) {
|
||||
web.Run(params...)
|
||||
}
|
||||
|
||||
// RunWithMiddleWares Run beego application with middlewares.
|
||||
func RunWithMiddleWares(addr string, mws ...MiddleWare) {
|
||||
newMws := oldMiddlewareToNew(mws)
|
||||
web.RunWithMiddleWares(addr, newMws...)
|
||||
}
|
||||
|
||||
// TestBeegoInit is for test package init
|
||||
func TestBeegoInit(ap string) {
|
||||
web.TestBeegoInit(ap)
|
||||
}
|
||||
|
||||
// InitBeegoBeforeTest is for test package init
|
||||
func InitBeegoBeforeTest(appConfigPath string) {
|
||||
web.InitBeegoBeforeTest(appConfigPath)
|
||||
}
|
27
adapter/build_info.go
Normal file
27
adapter/build_info.go
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2020 astaxie
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package adapter
|
||||
|
||||
var (
|
||||
BuildVersion string
|
||||
BuildGitRevision string
|
||||
BuildStatus string
|
||||
BuildTag string
|
||||
BuildTime string
|
||||
|
||||
GoVersion string
|
||||
|
||||
GitBranch string
|
||||
)
|
2
cache/cache.go → adapter/cache/cache.go
vendored
2
cache/cache.go → adapter/cache/cache.go
vendored
@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package cache provide a Cache interface and some implemetn engine
|
||||
// Package cache provide a Cache interface and some implement engine
|
||||
// Usage:
|
||||
//
|
||||
// import(
|
117
adapter/cache/cache_adapter.go
vendored
Normal file
117
adapter/cache/cache_adapter.go
vendored
Normal file
@ -0,0 +1,117 @@
|
||||
// Copyright 2020
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego/client/cache"
|
||||
)
|
||||
|
||||
type newToOldCacheAdapter struct {
|
||||
delegate cache.Cache
|
||||
}
|
||||
|
||||
func (c *newToOldCacheAdapter) Get(key string) interface{} {
|
||||
res, _ := c.delegate.Get(context.Background(), key)
|
||||
return res
|
||||
}
|
||||
|
||||
func (c *newToOldCacheAdapter) GetMulti(keys []string) []interface{} {
|
||||
res, _ := c.delegate.GetMulti(context.Background(), keys)
|
||||
return res
|
||||
}
|
||||
|
||||
func (c *newToOldCacheAdapter) Put(key string, val interface{}, timeout time.Duration) error {
|
||||
return c.delegate.Put(context.Background(), key, val, timeout)
|
||||
}
|
||||
|
||||
func (c *newToOldCacheAdapter) Delete(key string) error {
|
||||
return c.delegate.Delete(context.Background(), key)
|
||||
}
|
||||
|
||||
func (c *newToOldCacheAdapter) Incr(key string) error {
|
||||
return c.delegate.Incr(context.Background(), key)
|
||||
}
|
||||
|
||||
func (c *newToOldCacheAdapter) Decr(key string) error {
|
||||
return c.delegate.Decr(context.Background(), key)
|
||||
}
|
||||
|
||||
func (c *newToOldCacheAdapter) IsExist(key string) bool {
|
||||
res, err := c.delegate.IsExist(context.Background(), key)
|
||||
return res && err == nil
|
||||
}
|
||||
|
||||
func (c *newToOldCacheAdapter) ClearAll() error {
|
||||
return c.delegate.ClearAll(context.Background())
|
||||
}
|
||||
|
||||
func (c *newToOldCacheAdapter) StartAndGC(config string) error {
|
||||
return c.delegate.StartAndGC(config)
|
||||
}
|
||||
|
||||
func CreateNewToOldCacheAdapter(delegate cache.Cache) Cache {
|
||||
return &newToOldCacheAdapter{
|
||||
delegate: delegate,
|
||||
}
|
||||
}
|
||||
|
||||
type oldToNewCacheAdapter struct {
|
||||
old Cache
|
||||
}
|
||||
|
||||
func (o *oldToNewCacheAdapter) Get(ctx context.Context, key string) (interface{}, error) {
|
||||
return o.old.Get(key), nil
|
||||
}
|
||||
|
||||
func (o *oldToNewCacheAdapter) GetMulti(ctx context.Context, keys []string) ([]interface{}, error) {
|
||||
return o.old.GetMulti(keys), nil
|
||||
}
|
||||
|
||||
func (o *oldToNewCacheAdapter) Put(ctx context.Context, key string, val interface{}, timeout time.Duration) error {
|
||||
return o.old.Put(key, val, timeout)
|
||||
}
|
||||
|
||||
func (o *oldToNewCacheAdapter) Delete(ctx context.Context, key string) error {
|
||||
return o.old.Delete(key)
|
||||
}
|
||||
|
||||
func (o *oldToNewCacheAdapter) Incr(ctx context.Context, key string) error {
|
||||
return o.old.Incr(key)
|
||||
}
|
||||
|
||||
func (o *oldToNewCacheAdapter) Decr(ctx context.Context, key string) error {
|
||||
return o.old.Decr(key)
|
||||
}
|
||||
|
||||
func (o *oldToNewCacheAdapter) IsExist(ctx context.Context, key string) (bool, error) {
|
||||
return o.old.IsExist(key), nil
|
||||
}
|
||||
|
||||
func (o *oldToNewCacheAdapter) ClearAll(ctx context.Context) error {
|
||||
return o.old.ClearAll()
|
||||
}
|
||||
|
||||
func (o *oldToNewCacheAdapter) StartAndGC(config string) error {
|
||||
return o.old.StartAndGC(config)
|
||||
}
|
||||
|
||||
func CreateOldToNewAdapter(old Cache) cache.Cache {
|
||||
return &oldToNewCacheAdapter{
|
||||
old: old,
|
||||
}
|
||||
}
|
@ -16,10 +16,33 @@ package cache
|
||||
|
||||
import (
|
||||
"os"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestCacheIncr(t *testing.T) {
|
||||
bm, err := NewCache("memory", `{"interval":20}`)
|
||||
if err != nil {
|
||||
t.Error("init err")
|
||||
}
|
||||
//timeoutDuration := 10 * time.Second
|
||||
|
||||
bm.Put("edwardhey", 0, time.Second*20)
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(10)
|
||||
for i := 0; i < 10; i++ {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
bm.Incr("edwardhey")
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
if bm.Get("edwardhey").(int) != 10 {
|
||||
t.Error("Incr err")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCache(t *testing.T) {
|
||||
bm, err := NewCache("memory", `{"interval":20}`)
|
||||
if err != nil {
|
||||
@ -98,7 +121,7 @@ func TestCache(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFileCache(t *testing.T) {
|
||||
bm, err := NewCache("file", `{"CachePath":"cache","FileSuffix":".bin","DirectoryLevel":2,"EmbedExpiry":0}`)
|
||||
bm, err := NewCache("file", `{"CachePath":"cache","FileSuffix":".bin","DirectoryLevel":"2","EmbedExpiry":"0"}`)
|
||||
if err != nil {
|
||||
t.Error("init err")
|
||||
}
|
44
adapter/cache/conv.go
vendored
Normal file
44
adapter/cache/conv.go
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/client/cache"
|
||||
)
|
||||
|
||||
// GetString convert interface to string.
|
||||
func GetString(v interface{}) string {
|
||||
return cache.GetString(v)
|
||||
}
|
||||
|
||||
// GetInt convert interface to int.
|
||||
func GetInt(v interface{}) int {
|
||||
return cache.GetInt(v)
|
||||
}
|
||||
|
||||
// GetInt64 convert interface to int64.
|
||||
func GetInt64(v interface{}) int64 {
|
||||
return cache.GetInt64(v)
|
||||
}
|
||||
|
||||
// GetFloat64 convert interface to float64.
|
||||
func GetFloat64(v interface{}) float64 {
|
||||
return cache.GetFloat64(v)
|
||||
}
|
||||
|
||||
// GetBool convert interface to bool.
|
||||
func GetBool(v interface{}) bool {
|
||||
return cache.GetBool(v)
|
||||
}
|
30
adapter/cache/file.go
vendored
Normal file
30
adapter/cache/file.go
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/client/cache"
|
||||
)
|
||||
|
||||
// NewFileCache Create new file cache with no config.
|
||||
// the level and expiry need set in method StartAndGC as config string.
|
||||
func NewFileCache() Cache {
|
||||
// return &FileCache{CachePath:FileCachePath, FileSuffix:FileCacheFileSuffix}
|
||||
return CreateNewToOldCacheAdapter(cache.NewFileCache())
|
||||
}
|
||||
|
||||
func init() {
|
||||
Register("file", NewFileCache)
|
||||
}
|
44
adapter/cache/memcache/memcache.go
vendored
Normal file
44
adapter/cache/memcache/memcache.go
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package memcache for cache provider
|
||||
//
|
||||
// depend on github.com/bradfitz/gomemcache/memcache
|
||||
//
|
||||
// go install github.com/bradfitz/gomemcache/memcache
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/astaxie/beego/cache/memcache"
|
||||
// "github.com/astaxie/beego/cache"
|
||||
// )
|
||||
//
|
||||
// bm, err := cache.NewCache("memcache", `{"conn":"127.0.0.1:11211"}`)
|
||||
//
|
||||
// more docs http://beego.me/docs/module/cache.md
|
||||
package memcache
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/adapter/cache"
|
||||
"github.com/astaxie/beego/client/cache/memcache"
|
||||
)
|
||||
|
||||
// NewMemCache create new memcache adapter.
|
||||
func NewMemCache() cache.Cache {
|
||||
return cache.CreateNewToOldCacheAdapter(memcache.NewMemCache())
|
||||
}
|
||||
|
||||
func init() {
|
||||
cache.Register("memcache", NewMemCache)
|
||||
}
|
@ -15,17 +15,23 @@
|
||||
package memcache
|
||||
|
||||
import (
|
||||
_ "github.com/bradfitz/gomemcache/memcache"
|
||||
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego/cache"
|
||||
"github.com/astaxie/beego/adapter/cache"
|
||||
)
|
||||
|
||||
func TestMemcacheCache(t *testing.T) {
|
||||
bm, err := cache.NewCache("memcache", `{"conn": "127.0.0.1:11211"}`)
|
||||
|
||||
addr := os.Getenv("MEMCACHE_ADDR")
|
||||
if addr == "" {
|
||||
addr = "127.0.0.1:11211"
|
||||
}
|
||||
|
||||
bm, err := cache.NewCache("memcache", fmt.Sprintf(`{"conn": "%s"}`, addr))
|
||||
if err != nil {
|
||||
t.Error("init err")
|
||||
}
|
||||
@ -70,7 +76,7 @@ func TestMemcacheCache(t *testing.T) {
|
||||
t.Error("delete err")
|
||||
}
|
||||
|
||||
//test string
|
||||
// test string
|
||||
if err = bm.Put("astaxie", "author", timeoutDuration); err != nil {
|
||||
t.Error("set Error", err)
|
||||
}
|
||||
@ -82,7 +88,7 @@ func TestMemcacheCache(t *testing.T) {
|
||||
t.Error("get err")
|
||||
}
|
||||
|
||||
//test GetMulti
|
||||
// test GetMulti
|
||||
if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil {
|
||||
t.Error("set Error", err)
|
||||
}
|
28
adapter/cache/memory.go
vendored
Normal file
28
adapter/cache/memory.go
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/client/cache"
|
||||
)
|
||||
|
||||
// NewMemoryCache returns a new MemoryCache.
|
||||
func NewMemoryCache() Cache {
|
||||
return CreateNewToOldCacheAdapter(cache.NewMemoryCache())
|
||||
}
|
||||
|
||||
func init() {
|
||||
Register("memory", NewMemoryCache)
|
||||
}
|
49
adapter/cache/redis/redis.go
vendored
Normal file
49
adapter/cache/redis/redis.go
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package redis for cache provider
|
||||
//
|
||||
// depend on github.com/gomodule/redigo/redis
|
||||
//
|
||||
// go install github.com/gomodule/redigo/redis
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/astaxie/beego/cache/redis"
|
||||
// "github.com/astaxie/beego/cache"
|
||||
// )
|
||||
//
|
||||
// bm, err := cache.NewCache("redis", `{"conn":"127.0.0.1:11211"}`)
|
||||
//
|
||||
// more docs http://beego.me/docs/module/cache.md
|
||||
package redis
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/adapter/cache"
|
||||
redis2 "github.com/astaxie/beego/client/cache/redis"
|
||||
)
|
||||
|
||||
var (
|
||||
// DefaultKey the collection name of redis for cache adapter.
|
||||
DefaultKey = "beecacheRedis"
|
||||
)
|
||||
|
||||
// NewRedisCache create new redis cache with default collection name.
|
||||
func NewRedisCache() cache.Cache {
|
||||
return cache.CreateNewToOldCacheAdapter(redis2.NewRedisCache())
|
||||
}
|
||||
|
||||
func init() {
|
||||
cache.Register("redis", NewRedisCache)
|
||||
}
|
@ -15,15 +15,23 @@
|
||||
package redis
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego/cache"
|
||||
"github.com/garyburd/redigo/redis"
|
||||
"github.com/gomodule/redigo/redis"
|
||||
|
||||
"github.com/astaxie/beego/adapter/cache"
|
||||
)
|
||||
|
||||
func TestRedisCache(t *testing.T) {
|
||||
bm, err := cache.NewCache("redis", `{"conn": "127.0.0.1:6379"}`)
|
||||
redisAddr := os.Getenv("REDIS_ADDR")
|
||||
if redisAddr == "" {
|
||||
redisAddr = "127.0.0.1:6379"
|
||||
}
|
||||
|
||||
bm, err := cache.NewCache("redis", fmt.Sprintf(`{"conn": "%s"}`, redisAddr))
|
||||
if err != nil {
|
||||
t.Error("init err")
|
||||
}
|
||||
@ -104,3 +112,24 @@ func TestRedisCache(t *testing.T) {
|
||||
t.Error("clear all err")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCache_Scan(t *testing.T) {
|
||||
timeoutDuration := 10 * time.Second
|
||||
// init
|
||||
bm, err := cache.NewCache("redis", `{"conn": "127.0.0.1:6379"}`)
|
||||
if err != nil {
|
||||
t.Error("init err")
|
||||
}
|
||||
// insert all
|
||||
for i := 0; i < 10000; i++ {
|
||||
if err = bm.Put(fmt.Sprintf("astaxie%d", i), fmt.Sprintf("author%d", i), timeoutDuration); err != nil {
|
||||
t.Error("set Error", err)
|
||||
}
|
||||
}
|
||||
|
||||
// clear all
|
||||
if err = bm.ClearAll(); err != nil {
|
||||
t.Error("clear all err")
|
||||
}
|
||||
|
||||
}
|
15
adapter/cache/ssdb/ssdb.go
vendored
Normal file
15
adapter/cache/ssdb/ssdb.go
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
package ssdb
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/adapter/cache"
|
||||
ssdb2 "github.com/astaxie/beego/client/cache/ssdb"
|
||||
)
|
||||
|
||||
// NewSsdbCache create new ssdb adapter.
|
||||
func NewSsdbCache() cache.Cache {
|
||||
return cache.CreateNewToOldCacheAdapter(ssdb2.NewSsdbCache())
|
||||
}
|
||||
|
||||
func init() {
|
||||
cache.Register("ssdb", NewSsdbCache)
|
||||
}
|
@ -1,15 +1,22 @@
|
||||
package ssdb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego/cache"
|
||||
"github.com/astaxie/beego/adapter/cache"
|
||||
)
|
||||
|
||||
func TestSsdbcacheCache(t *testing.T) {
|
||||
ssdb, err := cache.NewCache("ssdb", `{"conn": "127.0.0.1:8888"}`)
|
||||
ssdbAddr := os.Getenv("SSDB_ADDR")
|
||||
if ssdbAddr == "" {
|
||||
ssdbAddr = "127.0.0.1:8888"
|
||||
}
|
||||
|
||||
ssdb, err := cache.NewCache("ssdb", fmt.Sprintf(`{"conn": "%s"}`, ssdbAddr))
|
||||
if err != nil {
|
||||
t.Error("init err")
|
||||
}
|
177
adapter/config.go
Normal file
177
adapter/config.go
Normal file
@ -0,0 +1,177 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package adapter
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/adapter/session"
|
||||
newCfg "github.com/astaxie/beego/core/config"
|
||||
"github.com/astaxie/beego/server/web"
|
||||
)
|
||||
|
||||
// Config is the main struct for BConfig
|
||||
type Config web.Config
|
||||
|
||||
// Listen holds for http and https related config
|
||||
type Listen web.Listen
|
||||
|
||||
// WebConfig holds web related config
|
||||
type WebConfig web.WebConfig
|
||||
|
||||
// SessionConfig holds session related config
|
||||
type SessionConfig web.SessionConfig
|
||||
|
||||
// LogConfig holds Log related config
|
||||
type LogConfig web.LogConfig
|
||||
|
||||
var (
|
||||
// BConfig is the default config for Application
|
||||
BConfig *Config
|
||||
// AppConfig is the instance of Config, store the config information from file
|
||||
AppConfig *beegoAppConfig
|
||||
// AppPath is the absolute path to the app
|
||||
AppPath string
|
||||
// GlobalSessions is the instance for the session manager
|
||||
GlobalSessions *session.Manager
|
||||
|
||||
// appConfigPath is the path to the config files
|
||||
appConfigPath string
|
||||
// appConfigProvider is the provider for the config, default is ini
|
||||
appConfigProvider = "ini"
|
||||
// WorkPath is the absolute path to project root directory
|
||||
WorkPath string
|
||||
)
|
||||
|
||||
func init() {
|
||||
BConfig = (*Config)(web.BConfig)
|
||||
AppPath = web.AppPath
|
||||
|
||||
WorkPath = web.WorkPath
|
||||
|
||||
AppConfig = &beegoAppConfig{innerConfig: (newCfg.Configer)(web.AppConfig)}
|
||||
}
|
||||
|
||||
// LoadAppConfig allow developer to apply a config file
|
||||
func LoadAppConfig(adapterName, configPath string) error {
|
||||
return web.LoadAppConfig(adapterName, configPath)
|
||||
}
|
||||
|
||||
type beegoAppConfig struct {
|
||||
innerConfig newCfg.Configer
|
||||
}
|
||||
|
||||
func (b *beegoAppConfig) Set(key, val string) error {
|
||||
if err := b.innerConfig.Set(BConfig.RunMode+"::"+key, val); err != nil {
|
||||
return b.innerConfig.Set(key, val)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *beegoAppConfig) String(key string) string {
|
||||
if v, err := b.innerConfig.String(BConfig.RunMode + "::" + key); v != "" && err != nil {
|
||||
return v
|
||||
}
|
||||
res, _ := b.innerConfig.String(key)
|
||||
return res
|
||||
}
|
||||
|
||||
func (b *beegoAppConfig) Strings(key string) []string {
|
||||
if v, err := b.innerConfig.Strings(BConfig.RunMode + "::" + key); len(v) > 0 && err != nil {
|
||||
return v
|
||||
}
|
||||
res, _ := b.innerConfig.Strings(key)
|
||||
return res
|
||||
}
|
||||
|
||||
func (b *beegoAppConfig) Int(key string) (int, error) {
|
||||
if v, err := b.innerConfig.Int(BConfig.RunMode + "::" + key); err == nil {
|
||||
return v, nil
|
||||
}
|
||||
return b.innerConfig.Int(key)
|
||||
}
|
||||
|
||||
func (b *beegoAppConfig) Int64(key string) (int64, error) {
|
||||
if v, err := b.innerConfig.Int64(BConfig.RunMode + "::" + key); err == nil {
|
||||
return v, nil
|
||||
}
|
||||
return b.innerConfig.Int64(key)
|
||||
}
|
||||
|
||||
func (b *beegoAppConfig) Bool(key string) (bool, error) {
|
||||
if v, err := b.innerConfig.Bool(BConfig.RunMode + "::" + key); err == nil {
|
||||
return v, nil
|
||||
}
|
||||
return b.innerConfig.Bool(key)
|
||||
}
|
||||
|
||||
func (b *beegoAppConfig) Float(key string) (float64, error) {
|
||||
if v, err := b.innerConfig.Float(BConfig.RunMode + "::" + key); err == nil {
|
||||
return v, nil
|
||||
}
|
||||
return b.innerConfig.Float(key)
|
||||
}
|
||||
|
||||
func (b *beegoAppConfig) DefaultString(key string, defaultVal string) string {
|
||||
if v := b.String(key); v != "" {
|
||||
return v
|
||||
}
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
func (b *beegoAppConfig) DefaultStrings(key string, defaultVal []string) []string {
|
||||
if v := b.Strings(key); len(v) != 0 {
|
||||
return v
|
||||
}
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
func (b *beegoAppConfig) DefaultInt(key string, defaultVal int) int {
|
||||
if v, err := b.Int(key); err == nil {
|
||||
return v
|
||||
}
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
func (b *beegoAppConfig) DefaultInt64(key string, defaultVal int64) int64 {
|
||||
if v, err := b.Int64(key); err == nil {
|
||||
return v
|
||||
}
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
func (b *beegoAppConfig) DefaultBool(key string, defaultVal bool) bool {
|
||||
if v, err := b.Bool(key); err == nil {
|
||||
return v
|
||||
}
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
func (b *beegoAppConfig) DefaultFloat(key string, defaultVal float64) float64 {
|
||||
if v, err := b.Float(key); err == nil {
|
||||
return v
|
||||
}
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
func (b *beegoAppConfig) DIY(key string) (interface{}, error) {
|
||||
return b.innerConfig.DIY(key)
|
||||
}
|
||||
|
||||
func (b *beegoAppConfig) GetSection(section string) (map[string]string, error) {
|
||||
return b.innerConfig.GetSection(section)
|
||||
}
|
||||
|
||||
func (b *beegoAppConfig) SaveConfigFile(filename string) error {
|
||||
return b.innerConfig.SaveConfigFile(filename)
|
||||
}
|
191
adapter/config/adapter.go
Normal file
191
adapter/config/adapter.go
Normal file
@ -0,0 +1,191 @@
|
||||
// Copyright 2020
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/astaxie/beego/core/config"
|
||||
)
|
||||
|
||||
type newToOldConfigerAdapter struct {
|
||||
delegate config.Configer
|
||||
}
|
||||
|
||||
func (c *newToOldConfigerAdapter) Set(key, val string) error {
|
||||
return c.delegate.Set(key, val)
|
||||
}
|
||||
|
||||
func (c *newToOldConfigerAdapter) String(key string) string {
|
||||
res, _ := c.delegate.String(key)
|
||||
return res
|
||||
}
|
||||
|
||||
func (c *newToOldConfigerAdapter) Strings(key string) []string {
|
||||
res, _ := c.delegate.Strings(key)
|
||||
return res
|
||||
}
|
||||
|
||||
func (c *newToOldConfigerAdapter) Int(key string) (int, error) {
|
||||
return c.delegate.Int(key)
|
||||
}
|
||||
|
||||
func (c *newToOldConfigerAdapter) Int64(key string) (int64, error) {
|
||||
return c.delegate.Int64(key)
|
||||
}
|
||||
|
||||
func (c *newToOldConfigerAdapter) Bool(key string) (bool, error) {
|
||||
return c.delegate.Bool(key)
|
||||
}
|
||||
|
||||
func (c *newToOldConfigerAdapter) Float(key string) (float64, error) {
|
||||
return c.delegate.Float(key)
|
||||
}
|
||||
|
||||
func (c *newToOldConfigerAdapter) DefaultString(key string, defaultVal string) string {
|
||||
return c.delegate.DefaultString(key, defaultVal)
|
||||
}
|
||||
|
||||
func (c *newToOldConfigerAdapter) DefaultStrings(key string, defaultVal []string) []string {
|
||||
return c.delegate.DefaultStrings(key, defaultVal)
|
||||
}
|
||||
|
||||
func (c *newToOldConfigerAdapter) DefaultInt(key string, defaultVal int) int {
|
||||
return c.delegate.DefaultInt(key, defaultVal)
|
||||
}
|
||||
|
||||
func (c *newToOldConfigerAdapter) DefaultInt64(key string, defaultVal int64) int64 {
|
||||
return c.delegate.DefaultInt64(key, defaultVal)
|
||||
}
|
||||
|
||||
func (c *newToOldConfigerAdapter) DefaultBool(key string, defaultVal bool) bool {
|
||||
return c.delegate.DefaultBool(key, defaultVal)
|
||||
}
|
||||
|
||||
func (c *newToOldConfigerAdapter) DefaultFloat(key string, defaultVal float64) float64 {
|
||||
return c.delegate.DefaultFloat(key, defaultVal)
|
||||
}
|
||||
|
||||
func (c *newToOldConfigerAdapter) DIY(key string) (interface{}, error) {
|
||||
return c.delegate.DIY(key)
|
||||
}
|
||||
|
||||
func (c *newToOldConfigerAdapter) GetSection(section string) (map[string]string, error) {
|
||||
return c.delegate.GetSection(section)
|
||||
}
|
||||
|
||||
func (c *newToOldConfigerAdapter) SaveConfigFile(filename string) error {
|
||||
return c.delegate.SaveConfigFile(filename)
|
||||
}
|
||||
|
||||
type oldToNewConfigerAdapter struct {
|
||||
delegate Configer
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigerAdapter) Set(key, val string) error {
|
||||
return o.delegate.Set(key, val)
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigerAdapter) String(key string) (string, error) {
|
||||
return o.delegate.String(key), nil
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigerAdapter) Strings(key string) ([]string, error) {
|
||||
return o.delegate.Strings(key), nil
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigerAdapter) Int(key string) (int, error) {
|
||||
return o.delegate.Int(key)
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigerAdapter) Int64(key string) (int64, error) {
|
||||
return o.delegate.Int64(key)
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigerAdapter) Bool(key string) (bool, error) {
|
||||
return o.delegate.Bool(key)
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigerAdapter) Float(key string) (float64, error) {
|
||||
return o.delegate.Float(key)
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigerAdapter) DefaultString(key string, defaultVal string) string {
|
||||
return o.delegate.DefaultString(key, defaultVal)
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigerAdapter) DefaultStrings(key string, defaultVal []string) []string {
|
||||
return o.delegate.DefaultStrings(key, defaultVal)
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigerAdapter) DefaultInt(key string, defaultVal int) int {
|
||||
return o.delegate.DefaultInt(key, defaultVal)
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigerAdapter) DefaultInt64(key string, defaultVal int64) int64 {
|
||||
return o.delegate.DefaultInt64(key, defaultVal)
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigerAdapter) DefaultBool(key string, defaultVal bool) bool {
|
||||
return o.delegate.DefaultBool(key, defaultVal)
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigerAdapter) DefaultFloat(key string, defaultVal float64) float64 {
|
||||
return o.delegate.DefaultFloat(key, defaultVal)
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigerAdapter) DIY(key string) (interface{}, error) {
|
||||
return o.delegate.DIY(key)
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigerAdapter) GetSection(section string) (map[string]string, error) {
|
||||
return o.delegate.GetSection(section)
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigerAdapter) Unmarshaler(prefix string, obj interface{}, opt ...config.DecodeOption) error {
|
||||
return errors.New("unsupported operation, please use actual config.Configer")
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigerAdapter) Sub(key string) (config.Configer, error) {
|
||||
return nil, errors.New("unsupported operation, please use actual config.Configer")
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigerAdapter) OnChange(key string, fn func(value string)) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigerAdapter) SaveConfigFile(filename string) error {
|
||||
return o.delegate.SaveConfigFile(filename)
|
||||
}
|
||||
|
||||
type oldToNewConfigAdapter struct {
|
||||
delegate Config
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigAdapter) Parse(key string) (config.Configer, error) {
|
||||
old, err := o.delegate.Parse(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &oldToNewConfigerAdapter{delegate: old}, nil
|
||||
}
|
||||
|
||||
func (o *oldToNewConfigAdapter) ParseData(data []byte) (config.Configer, error) {
|
||||
old, err := o.delegate.ParseData(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &oldToNewConfigerAdapter{delegate: old}, nil
|
||||
}
|
151
adapter/config/config.go
Normal file
151
adapter/config/config.go
Normal file
@ -0,0 +1,151 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package config is used to parse config.
|
||||
// Usage:
|
||||
// import "github.com/astaxie/beego/config"
|
||||
// Examples.
|
||||
//
|
||||
// cnf, err := config.NewConfig("ini", "config.conf")
|
||||
//
|
||||
// cnf APIS:
|
||||
//
|
||||
// cnf.Set(key, val string) error
|
||||
// cnf.String(key string) string
|
||||
// cnf.Strings(key string) []string
|
||||
// cnf.Int(key string) (int, error)
|
||||
// cnf.Int64(key string) (int64, error)
|
||||
// cnf.Bool(key string) (bool, error)
|
||||
// cnf.Float(key string) (float64, error)
|
||||
// cnf.DefaultString(key string, defaultVal string) string
|
||||
// cnf.DefaultStrings(key string, defaultVal []string) []string
|
||||
// cnf.DefaultInt(key string, defaultVal int) int
|
||||
// cnf.DefaultInt64(key string, defaultVal int64) int64
|
||||
// cnf.DefaultBool(key string, defaultVal bool) bool
|
||||
// cnf.DefaultFloat(key string, defaultVal float64) float64
|
||||
// cnf.DIY(key string) (interface{}, error)
|
||||
// cnf.GetSection(section string) (map[string]string, error)
|
||||
// cnf.SaveConfigFile(filename string) error
|
||||
// More docs http://beego.me/docs/module/config.md
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/core/config"
|
||||
)
|
||||
|
||||
// Configer defines how to get and set value from configuration raw data.
|
||||
type Configer interface {
|
||||
Set(key, val string) error // support section::key type in given key when using ini type.
|
||||
String(key string) string // support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
|
||||
Strings(key string) []string // get string slice
|
||||
Int(key string) (int, error)
|
||||
Int64(key string) (int64, error)
|
||||
Bool(key string) (bool, error)
|
||||
Float(key string) (float64, error)
|
||||
DefaultString(key string, defaultVal string) string // support section::key type in key string when using ini and json type; Int,Int64,Bool,Float,DIY are same.
|
||||
DefaultStrings(key string, defaultVal []string) []string // get string slice
|
||||
DefaultInt(key string, defaultVal int) int
|
||||
DefaultInt64(key string, defaultVal int64) int64
|
||||
DefaultBool(key string, defaultVal bool) bool
|
||||
DefaultFloat(key string, defaultVal float64) float64
|
||||
DIY(key string) (interface{}, error)
|
||||
GetSection(section string) (map[string]string, error)
|
||||
SaveConfigFile(filename string) error
|
||||
}
|
||||
|
||||
// Config is the adapter interface for parsing config file to get raw data to Configer.
|
||||
type Config interface {
|
||||
Parse(key string) (Configer, error)
|
||||
ParseData(data []byte) (Configer, error)
|
||||
}
|
||||
|
||||
var adapters = make(map[string]Config)
|
||||
|
||||
// Register makes a config adapter available by the adapter name.
|
||||
// If Register is called twice with the same name or if driver is nil,
|
||||
// it panics.
|
||||
func Register(name string, adapter Config) {
|
||||
config.Register(name, &oldToNewConfigAdapter{delegate: adapter})
|
||||
}
|
||||
|
||||
// NewConfig adapterName is ini/json/xml/yaml.
|
||||
// filename is the config file path.
|
||||
func NewConfig(adapterName, filename string) (Configer, error) {
|
||||
cfg, err := config.NewConfig(adapterName, filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// it was registered by using Register method
|
||||
res, ok := cfg.(*oldToNewConfigerAdapter)
|
||||
if ok {
|
||||
return res.delegate, nil
|
||||
}
|
||||
|
||||
return &newToOldConfigerAdapter{
|
||||
delegate: cfg,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// NewConfigData adapterName is ini/json/xml/yaml.
|
||||
// data is the config data.
|
||||
func NewConfigData(adapterName string, data []byte) (Configer, error) {
|
||||
cfg, err := config.NewConfigData(adapterName, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// it was registered by using Register method
|
||||
res, ok := cfg.(*oldToNewConfigerAdapter)
|
||||
if ok {
|
||||
return res.delegate, nil
|
||||
}
|
||||
|
||||
return &newToOldConfigerAdapter{
|
||||
delegate: cfg,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ExpandValueEnvForMap convert all string value with environment variable.
|
||||
func ExpandValueEnvForMap(m map[string]interface{}) map[string]interface{} {
|
||||
return config.ExpandValueEnvForMap(m)
|
||||
}
|
||||
|
||||
// ExpandValueEnv returns value of convert with environment variable.
|
||||
//
|
||||
// Return environment variable if value start with "${" and end with "}".
|
||||
// Return default value if environment variable is empty or not exist.
|
||||
//
|
||||
// It accept value formats "${env}" , "${env||}}" , "${env||defaultValue}" , "defaultvalue".
|
||||
// Examples:
|
||||
// v1 := config.ExpandValueEnv("${GOPATH}") // return the GOPATH environment variable.
|
||||
// v2 := config.ExpandValueEnv("${GOAsta||/usr/local/go}") // return the default value "/usr/local/go/".
|
||||
// v3 := config.ExpandValueEnv("Astaxie") // return the value "Astaxie".
|
||||
func ExpandValueEnv(value string) string {
|
||||
return config.ExpandValueEnv(value)
|
||||
}
|
||||
|
||||
// ParseBool returns the boolean value represented by the string.
|
||||
//
|
||||
// It accepts 1, 1.0, t, T, TRUE, true, True, YES, yes, Yes,Y, y, ON, on, On,
|
||||
// 0, 0.0, f, F, FALSE, false, False, NO, no, No, N,n, OFF, off, Off.
|
||||
// Any other value returns an error.
|
||||
func ParseBool(val interface{}) (value bool, err error) {
|
||||
return config.ParseBool(val)
|
||||
}
|
||||
|
||||
// ToString converts values of any type to string.
|
||||
func ToString(x interface{}) string {
|
||||
return config.ToString(x)
|
||||
}
|
50
adapter/config/env/env.go
vendored
Normal file
50
adapter/config/env/env.go
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
// Copyright 2017 Faissal Elamraoui. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package env is used to parse environment.
|
||||
package env
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/core/config/env"
|
||||
)
|
||||
|
||||
// Get returns a value by key.
|
||||
// If the key does not exist, the default value will be returned.
|
||||
func Get(key string, defVal string) string {
|
||||
return env.Get(key, defVal)
|
||||
}
|
||||
|
||||
// MustGet returns a value by key.
|
||||
// If the key does not exist, it will return an error.
|
||||
func MustGet(key string) (string, error) {
|
||||
return env.MustGet(key)
|
||||
}
|
||||
|
||||
// Set sets a value in the ENV copy.
|
||||
// This does not affect the child process environment.
|
||||
func Set(key string, value string) {
|
||||
env.Set(key, value)
|
||||
}
|
||||
|
||||
// MustSet sets a value in the ENV copy and the child process environment.
|
||||
// It returns an error in case the set operation failed.
|
||||
func MustSet(key string, value string) error {
|
||||
return env.MustSet(key, value)
|
||||
}
|
||||
|
||||
// GetAll returns all keys/values in the current child process environment.
|
||||
func GetAll() map[string]string {
|
||||
return env.GetAll()
|
||||
}
|
25
adapter/config/fake.go
Normal file
25
adapter/config/fake.go
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/core/config"
|
||||
)
|
||||
|
||||
// NewFakeConfig return a fake Configer
|
||||
func NewFakeConfig() Configer {
|
||||
new := config.NewFakeConfig()
|
||||
return &newToOldConfigerAdapter{delegate: new}
|
||||
}
|
@ -12,4 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package testing
|
||||
package config
|
||||
|
||||
import (
|
||||
_ "github.com/astaxie/beego/core/config/json"
|
||||
)
|
@ -216,7 +216,7 @@ func TestJson(t *testing.T) {
|
||||
t.Error("unknown keys should return an error when expecting a Bool")
|
||||
}
|
||||
|
||||
if !jsonconf.DefaultBool("unknow", true) {
|
||||
if !jsonconf.DefaultBool("unknown", true) {
|
||||
t.Error("unknown keys with default value wrong")
|
||||
}
|
||||
}
|
34
adapter/config/xml/xml.go
Normal file
34
adapter/config/xml/xml.go
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package xml for config provider.
|
||||
//
|
||||
// depend on github.com/beego/x2j.
|
||||
//
|
||||
// go install github.com/beego/x2j.
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/astaxie/beego/config/xml"
|
||||
// "github.com/astaxie/beego/config"
|
||||
// )
|
||||
//
|
||||
// cnf, err := config.NewConfig("xml", "config.xml")
|
||||
//
|
||||
// More docs http://beego.me/docs/module/config.md
|
||||
package xml
|
||||
|
||||
import (
|
||||
_ "github.com/astaxie/beego/core/config/xml"
|
||||
)
|
@ -19,7 +19,7 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/astaxie/beego/config"
|
||||
"github.com/astaxie/beego/adapter/config"
|
||||
)
|
||||
|
||||
func TestXML(t *testing.T) {
|
34
adapter/config/yaml/yaml.go
Normal file
34
adapter/config/yaml/yaml.go
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package yaml for config provider
|
||||
//
|
||||
// depend on github.com/beego/goyaml2
|
||||
//
|
||||
// go install github.com/beego/goyaml2
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/astaxie/beego/config/yaml"
|
||||
// "github.com/astaxie/beego/config"
|
||||
// )
|
||||
//
|
||||
// cnf, err := config.NewConfig("yaml", "config.yaml")
|
||||
//
|
||||
// More docs http://beego.me/docs/module/config.md
|
||||
package yaml
|
||||
|
||||
import (
|
||||
_ "github.com/astaxie/beego/core/config/yaml"
|
||||
)
|
@ -19,7 +19,7 @@ import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/astaxie/beego/config"
|
||||
"github.com/astaxie/beego/adapter/config"
|
||||
)
|
||||
|
||||
func TestYaml(t *testing.T) {
|
45
adapter/context/acceptencoder.go
Normal file
45
adapter/context/acceptencoder.go
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright 2015 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package context
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/astaxie/beego/server/web/context"
|
||||
)
|
||||
|
||||
// InitGzip init the gzipcompress
|
||||
func InitGzip(minLength, compressLevel int, methods []string) {
|
||||
context.InitGzip(minLength, compressLevel, methods)
|
||||
}
|
||||
|
||||
// WriteFile reads from file and writes to writer by the specific encoding(gzip/deflate)
|
||||
func WriteFile(encoding string, writer io.Writer, file *os.File) (bool, string, error) {
|
||||
return context.WriteFile(encoding, writer, file)
|
||||
}
|
||||
|
||||
// WriteBody reads writes content to writer by the specific encoding(gzip/deflate)
|
||||
func WriteBody(encoding string, writer io.Writer, content []byte) (bool, string, error) {
|
||||
return context.WriteBody(encoding, writer, content)
|
||||
}
|
||||
|
||||
// ParseEncoding will extract the right encoding for response
|
||||
// the Accept-Encoding's sec is here:
|
||||
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
|
||||
func ParseEncoding(r *http.Request) string {
|
||||
return context.ParseEncoding(r)
|
||||
}
|
146
adapter/context/context.go
Normal file
146
adapter/context/context.go
Normal file
@ -0,0 +1,146 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package context provide the context utils
|
||||
// Usage:
|
||||
//
|
||||
// import "github.com/astaxie/beego/context"
|
||||
//
|
||||
// ctx := context.Context{Request:req,ResponseWriter:rw}
|
||||
//
|
||||
// more docs http://beego.me/docs/module/context.md
|
||||
package context
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/astaxie/beego/server/web/context"
|
||||
)
|
||||
|
||||
// commonly used mime-types
|
||||
const (
|
||||
ApplicationJSON = context.ApplicationJSON
|
||||
ApplicationXML = context.ApplicationXML
|
||||
ApplicationYAML = context.ApplicationYAML
|
||||
TextXML = context.TextXML
|
||||
)
|
||||
|
||||
// NewContext return the Context with Input and Output
|
||||
func NewContext() *Context {
|
||||
return (*Context)(context.NewContext())
|
||||
}
|
||||
|
||||
// Context Http request context struct including BeegoInput, BeegoOutput, http.Request and http.ResponseWriter.
|
||||
// BeegoInput and BeegoOutput provides some api to operate request and response more easily.
|
||||
type Context context.Context
|
||||
|
||||
// Reset init Context, BeegoInput and BeegoOutput
|
||||
func (ctx *Context) Reset(rw http.ResponseWriter, r *http.Request) {
|
||||
(*context.Context)(ctx).Reset(rw, r)
|
||||
}
|
||||
|
||||
// Redirect does redirection to localurl with http header status code.
|
||||
func (ctx *Context) Redirect(status int, localurl string) {
|
||||
(*context.Context)(ctx).Redirect(status, localurl)
|
||||
}
|
||||
|
||||
// Abort stops this request.
|
||||
// if beego.ErrorMaps exists, panic body.
|
||||
func (ctx *Context) Abort(status int, body string) {
|
||||
(*context.Context)(ctx).Abort(status, body)
|
||||
}
|
||||
|
||||
// WriteString Write string to response body.
|
||||
// it sends response body.
|
||||
func (ctx *Context) WriteString(content string) {
|
||||
(*context.Context)(ctx).WriteString(content)
|
||||
}
|
||||
|
||||
// GetCookie Get cookie from request by a given key.
|
||||
// It's alias of BeegoInput.Cookie.
|
||||
func (ctx *Context) GetCookie(key string) string {
|
||||
return (*context.Context)(ctx).GetCookie(key)
|
||||
}
|
||||
|
||||
// SetCookie Set cookie for response.
|
||||
// It's alias of BeegoOutput.Cookie.
|
||||
func (ctx *Context) SetCookie(name string, value string, others ...interface{}) {
|
||||
(*context.Context)(ctx).SetCookie(name, value, others)
|
||||
}
|
||||
|
||||
// GetSecureCookie Get secure cookie from request by a given key.
|
||||
func (ctx *Context) GetSecureCookie(Secret, key string) (string, bool) {
|
||||
return (*context.Context)(ctx).GetSecureCookie(Secret, key)
|
||||
}
|
||||
|
||||
// SetSecureCookie Set Secure cookie for response.
|
||||
func (ctx *Context) SetSecureCookie(Secret, name, value string, others ...interface{}) {
|
||||
(*context.Context)(ctx).SetSecureCookie(Secret, name, value, others)
|
||||
}
|
||||
|
||||
// XSRFToken creates a xsrf token string and returns.
|
||||
func (ctx *Context) XSRFToken(key string, expire int64) string {
|
||||
return (*context.Context)(ctx).XSRFToken(key, expire)
|
||||
}
|
||||
|
||||
// CheckXSRFCookie checks xsrf token in this request is valid or not.
|
||||
// the token can provided in request header "X-Xsrftoken" and "X-CsrfToken"
|
||||
// or in form field value named as "_xsrf".
|
||||
func (ctx *Context) CheckXSRFCookie() bool {
|
||||
return (*context.Context)(ctx).CheckXSRFCookie()
|
||||
}
|
||||
|
||||
// RenderMethodResult renders the return value of a controller method to the output
|
||||
func (ctx *Context) RenderMethodResult(result interface{}) {
|
||||
(*context.Context)(ctx).RenderMethodResult(result)
|
||||
}
|
||||
|
||||
// Response is a wrapper for the http.ResponseWriter
|
||||
// started set to true if response was written to then don't execute other handler
|
||||
type Response context.Response
|
||||
|
||||
// Write writes the data to the connection as part of an HTTP reply,
|
||||
// and sets `started` to true.
|
||||
// started means the response has sent out.
|
||||
func (r *Response) Write(p []byte) (int, error) {
|
||||
return (*context.Response)(r).Write(p)
|
||||
}
|
||||
|
||||
// WriteHeader sends an HTTP response header with status code,
|
||||
// and sets `started` to true.
|
||||
func (r *Response) WriteHeader(code int) {
|
||||
(*context.Response)(r).WriteHeader(code)
|
||||
}
|
||||
|
||||
// Hijack hijacker for http
|
||||
func (r *Response) Hijack() (net.Conn, *bufio.ReadWriter, error) {
|
||||
return (*context.Response)(r).Hijack()
|
||||
}
|
||||
|
||||
// Flush http.Flusher
|
||||
func (r *Response) Flush() {
|
||||
(*context.Response)(r).Flush()
|
||||
}
|
||||
|
||||
// CloseNotify http.CloseNotifier
|
||||
func (r *Response) CloseNotify() <-chan bool {
|
||||
return (*context.Response)(r).CloseNotify()
|
||||
}
|
||||
|
||||
// Pusher http.Pusher
|
||||
func (r *Response) Pusher() (pusher http.Pusher) {
|
||||
return (*context.Response)(r).Pusher()
|
||||
}
|
282
adapter/context/input.go
Normal file
282
adapter/context/input.go
Normal file
@ -0,0 +1,282 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package context
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/server/web/context"
|
||||
)
|
||||
|
||||
// BeegoInput operates the http request header, data, cookie and body.
|
||||
// it also contains router params and current session.
|
||||
type BeegoInput context.BeegoInput
|
||||
|
||||
// NewInput return BeegoInput generated by Context.
|
||||
func NewInput() *BeegoInput {
|
||||
return (*BeegoInput)(context.NewInput())
|
||||
}
|
||||
|
||||
// Reset init the BeegoInput
|
||||
func (input *BeegoInput) Reset(ctx *Context) {
|
||||
(*context.BeegoInput)(input).Reset((*context.Context)(ctx))
|
||||
}
|
||||
|
||||
// Protocol returns request protocol name, such as HTTP/1.1 .
|
||||
func (input *BeegoInput) Protocol() string {
|
||||
return (*context.BeegoInput)(input).Protocol()
|
||||
}
|
||||
|
||||
// URI returns full request url with query string, fragment.
|
||||
func (input *BeegoInput) URI() string {
|
||||
return input.Context.Request.RequestURI
|
||||
}
|
||||
|
||||
// URL returns request url path (without query string, fragment).
|
||||
func (input *BeegoInput) URL() string {
|
||||
return (*context.BeegoInput)(input).URL()
|
||||
}
|
||||
|
||||
// Site returns base site url as scheme://domain type.
|
||||
func (input *BeegoInput) Site() string {
|
||||
return (*context.BeegoInput)(input).Site()
|
||||
}
|
||||
|
||||
// Scheme returns request scheme as "http" or "https".
|
||||
func (input *BeegoInput) Scheme() string {
|
||||
return (*context.BeegoInput)(input).Scheme()
|
||||
}
|
||||
|
||||
// Domain returns host name.
|
||||
// Alias of Host method.
|
||||
func (input *BeegoInput) Domain() string {
|
||||
return (*context.BeegoInput)(input).Domain()
|
||||
}
|
||||
|
||||
// Host returns host name.
|
||||
// if no host info in request, return localhost.
|
||||
func (input *BeegoInput) Host() string {
|
||||
return (*context.BeegoInput)(input).Host()
|
||||
}
|
||||
|
||||
// Method returns http request method.
|
||||
func (input *BeegoInput) Method() string {
|
||||
return (*context.BeegoInput)(input).Method()
|
||||
}
|
||||
|
||||
// Is returns boolean of this request is on given method, such as Is("POST").
|
||||
func (input *BeegoInput) Is(method string) bool {
|
||||
return (*context.BeegoInput)(input).Is(method)
|
||||
}
|
||||
|
||||
// IsGet Is this a GET method request?
|
||||
func (input *BeegoInput) IsGet() bool {
|
||||
return (*context.BeegoInput)(input).IsGet()
|
||||
}
|
||||
|
||||
// IsPost Is this a POST method request?
|
||||
func (input *BeegoInput) IsPost() bool {
|
||||
return (*context.BeegoInput)(input).IsPost()
|
||||
}
|
||||
|
||||
// IsHead Is this a Head method request?
|
||||
func (input *BeegoInput) IsHead() bool {
|
||||
return (*context.BeegoInput)(input).IsHead()
|
||||
}
|
||||
|
||||
// IsOptions Is this a OPTIONS method request?
|
||||
func (input *BeegoInput) IsOptions() bool {
|
||||
return (*context.BeegoInput)(input).IsOptions()
|
||||
}
|
||||
|
||||
// IsPut Is this a PUT method request?
|
||||
func (input *BeegoInput) IsPut() bool {
|
||||
return (*context.BeegoInput)(input).IsPut()
|
||||
}
|
||||
|
||||
// IsDelete Is this a DELETE method request?
|
||||
func (input *BeegoInput) IsDelete() bool {
|
||||
return (*context.BeegoInput)(input).IsDelete()
|
||||
}
|
||||
|
||||
// IsPatch Is this a PATCH method request?
|
||||
func (input *BeegoInput) IsPatch() bool {
|
||||
return (*context.BeegoInput)(input).IsPatch()
|
||||
}
|
||||
|
||||
// IsAjax returns boolean of this request is generated by ajax.
|
||||
func (input *BeegoInput) IsAjax() bool {
|
||||
return (*context.BeegoInput)(input).IsAjax()
|
||||
}
|
||||
|
||||
// IsSecure returns boolean of this request is in https.
|
||||
func (input *BeegoInput) IsSecure() bool {
|
||||
return (*context.BeegoInput)(input).IsSecure()
|
||||
}
|
||||
|
||||
// IsWebsocket returns boolean of this request is in webSocket.
|
||||
func (input *BeegoInput) IsWebsocket() bool {
|
||||
return (*context.BeegoInput)(input).IsWebsocket()
|
||||
}
|
||||
|
||||
// IsUpload returns boolean of whether file uploads in this request or not..
|
||||
func (input *BeegoInput) IsUpload() bool {
|
||||
return (*context.BeegoInput)(input).IsUpload()
|
||||
}
|
||||
|
||||
// AcceptsHTML Checks if request accepts html response
|
||||
func (input *BeegoInput) AcceptsHTML() bool {
|
||||
return (*context.BeegoInput)(input).AcceptsHTML()
|
||||
}
|
||||
|
||||
// AcceptsXML Checks if request accepts xml response
|
||||
func (input *BeegoInput) AcceptsXML() bool {
|
||||
return (*context.BeegoInput)(input).AcceptsXML()
|
||||
}
|
||||
|
||||
// AcceptsJSON Checks if request accepts json response
|
||||
func (input *BeegoInput) AcceptsJSON() bool {
|
||||
return (*context.BeegoInput)(input).AcceptsJSON()
|
||||
}
|
||||
|
||||
// AcceptsYAML Checks if request accepts json response
|
||||
func (input *BeegoInput) AcceptsYAML() bool {
|
||||
return (*context.BeegoInput)(input).AcceptsYAML()
|
||||
}
|
||||
|
||||
// IP returns request client ip.
|
||||
// if in proxy, return first proxy id.
|
||||
// if error, return RemoteAddr.
|
||||
func (input *BeegoInput) IP() string {
|
||||
return (*context.BeegoInput)(input).IP()
|
||||
}
|
||||
|
||||
// Proxy returns proxy client ips slice.
|
||||
func (input *BeegoInput) Proxy() []string {
|
||||
return (*context.BeegoInput)(input).Proxy()
|
||||
}
|
||||
|
||||
// Referer returns http referer header.
|
||||
func (input *BeegoInput) Referer() string {
|
||||
return (*context.BeegoInput)(input).Referer()
|
||||
}
|
||||
|
||||
// Refer returns http referer header.
|
||||
func (input *BeegoInput) Refer() string {
|
||||
return (*context.BeegoInput)(input).Refer()
|
||||
}
|
||||
|
||||
// SubDomains returns sub domain string.
|
||||
// if aa.bb.domain.com, returns aa.bb .
|
||||
func (input *BeegoInput) SubDomains() string {
|
||||
return (*context.BeegoInput)(input).SubDomains()
|
||||
}
|
||||
|
||||
// Port returns request client port.
|
||||
// when error or empty, return 80.
|
||||
func (input *BeegoInput) Port() int {
|
||||
return (*context.BeegoInput)(input).Port()
|
||||
}
|
||||
|
||||
// UserAgent returns request client user agent string.
|
||||
func (input *BeegoInput) UserAgent() string {
|
||||
return (*context.BeegoInput)(input).UserAgent()
|
||||
}
|
||||
|
||||
// ParamsLen return the length of the params
|
||||
func (input *BeegoInput) ParamsLen() int {
|
||||
return (*context.BeegoInput)(input).ParamsLen()
|
||||
}
|
||||
|
||||
// Param returns router param by a given key.
|
||||
func (input *BeegoInput) Param(key string) string {
|
||||
return (*context.BeegoInput)(input).Param(key)
|
||||
}
|
||||
|
||||
// Params returns the map[key]value.
|
||||
func (input *BeegoInput) Params() map[string]string {
|
||||
return (*context.BeegoInput)(input).Params()
|
||||
}
|
||||
|
||||
// SetParam will set the param with key and value
|
||||
func (input *BeegoInput) SetParam(key, val string) {
|
||||
(*context.BeegoInput)(input).SetParam(key, val)
|
||||
}
|
||||
|
||||
// ResetParams clears any of the input's Params
|
||||
// This function is used to clear parameters so they may be reset between filter
|
||||
// passes.
|
||||
func (input *BeegoInput) ResetParams() {
|
||||
(*context.BeegoInput)(input).ResetParams()
|
||||
}
|
||||
|
||||
// Query returns input data item string by a given string.
|
||||
func (input *BeegoInput) Query(key string) string {
|
||||
return (*context.BeegoInput)(input).Query(key)
|
||||
}
|
||||
|
||||
// Header returns request header item string by a given string.
|
||||
// if non-existed, return empty string.
|
||||
func (input *BeegoInput) Header(key string) string {
|
||||
return (*context.BeegoInput)(input).Header(key)
|
||||
}
|
||||
|
||||
// Cookie returns request cookie item string by a given key.
|
||||
// if non-existed, return empty string.
|
||||
func (input *BeegoInput) Cookie(key string) string {
|
||||
return (*context.BeegoInput)(input).Cookie(key)
|
||||
}
|
||||
|
||||
// Session returns current session item value by a given key.
|
||||
// if non-existed, return nil.
|
||||
func (input *BeegoInput) Session(key interface{}) interface{} {
|
||||
return (*context.BeegoInput)(input).Session(key)
|
||||
}
|
||||
|
||||
// CopyBody returns the raw request body data as bytes.
|
||||
func (input *BeegoInput) CopyBody(MaxMemory int64) []byte {
|
||||
return (*context.BeegoInput)(input).CopyBody(MaxMemory)
|
||||
}
|
||||
|
||||
// Data return the implicit data in the input
|
||||
func (input *BeegoInput) Data() map[interface{}]interface{} {
|
||||
return (*context.BeegoInput)(input).Data()
|
||||
}
|
||||
|
||||
// GetData returns the stored data in this context.
|
||||
func (input *BeegoInput) GetData(key interface{}) interface{} {
|
||||
return (*context.BeegoInput)(input).GetData(key)
|
||||
}
|
||||
|
||||
// SetData stores data with given key in this context.
|
||||
// This data are only available in this context.
|
||||
func (input *BeegoInput) SetData(key, val interface{}) {
|
||||
(*context.BeegoInput)(input).SetData(key, val)
|
||||
}
|
||||
|
||||
// ParseFormOrMulitForm parseForm or parseMultiForm based on Content-type
|
||||
func (input *BeegoInput) ParseFormOrMulitForm(maxMemory int64) error {
|
||||
return (*context.BeegoInput)(input).ParseFormOrMultiForm(maxMemory)
|
||||
}
|
||||
|
||||
// Bind data from request.Form[key] to dest
|
||||
// like /?id=123&isok=true&ft=1.2&ol[0]=1&ol[1]=2&ul[]=str&ul[]=array&user.Name=astaxie
|
||||
// var id int beegoInput.Bind(&id, "id") id ==123
|
||||
// var isok bool beegoInput.Bind(&isok, "isok") isok ==true
|
||||
// var ft float64 beegoInput.Bind(&ft, "ft") ft ==1.2
|
||||
// ol := make([]int, 0, 2) beegoInput.Bind(&ol, "ol") ol ==[1 2]
|
||||
// ul := make([]string, 0, 2) beegoInput.Bind(&ul, "ul") ul ==[str array]
|
||||
// user struct{Name} beegoInput.Bind(&user, "user") user == {Name:"astaxie"}
|
||||
func (input *BeegoInput) Bind(dest interface{}, key string) error {
|
||||
return (*context.BeegoInput)(input).Bind(dest, key)
|
||||
}
|
154
adapter/context/output.go
Normal file
154
adapter/context/output.go
Normal file
@ -0,0 +1,154 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package context
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/server/web/context"
|
||||
)
|
||||
|
||||
// BeegoOutput does work for sending response header.
|
||||
type BeegoOutput context.BeegoOutput
|
||||
|
||||
// NewOutput returns new BeegoOutput.
|
||||
// it contains nothing now.
|
||||
func NewOutput() *BeegoOutput {
|
||||
return (*BeegoOutput)(context.NewOutput())
|
||||
}
|
||||
|
||||
// Reset init BeegoOutput
|
||||
func (output *BeegoOutput) Reset(ctx *Context) {
|
||||
(*context.BeegoOutput)(output).Reset((*context.Context)(ctx))
|
||||
}
|
||||
|
||||
// Header sets response header item string via given key.
|
||||
func (output *BeegoOutput) Header(key, val string) {
|
||||
(*context.BeegoOutput)(output).Header(key, val)
|
||||
}
|
||||
|
||||
// Body sets response body content.
|
||||
// if EnableGzip, compress content string.
|
||||
// it sends out response body directly.
|
||||
func (output *BeegoOutput) Body(content []byte) error {
|
||||
return (*context.BeegoOutput)(output).Body(content)
|
||||
}
|
||||
|
||||
// Cookie sets cookie value via given key.
|
||||
// others are ordered as cookie's max age time, path,domain, secure and httponly.
|
||||
func (output *BeegoOutput) Cookie(name string, value string, others ...interface{}) {
|
||||
(*context.BeegoOutput)(output).Cookie(name, value, others)
|
||||
}
|
||||
|
||||
// JSON writes json to response body.
|
||||
// if encoding is true, it converts utf-8 to \u0000 type.
|
||||
func (output *BeegoOutput) JSON(data interface{}, hasIndent bool, encoding bool) error {
|
||||
return (*context.BeegoOutput)(output).JSON(data, hasIndent, encoding)
|
||||
}
|
||||
|
||||
// YAML writes yaml to response body.
|
||||
func (output *BeegoOutput) YAML(data interface{}) error {
|
||||
return (*context.BeegoOutput)(output).YAML(data)
|
||||
}
|
||||
|
||||
// JSONP writes jsonp to response body.
|
||||
func (output *BeegoOutput) JSONP(data interface{}, hasIndent bool) error {
|
||||
return (*context.BeegoOutput)(output).JSONP(data, hasIndent)
|
||||
}
|
||||
|
||||
// XML writes xml string to response body.
|
||||
func (output *BeegoOutput) XML(data interface{}, hasIndent bool) error {
|
||||
return (*context.BeegoOutput)(output).XML(data, hasIndent)
|
||||
}
|
||||
|
||||
// ServeFormatted serve YAML, XML OR JSON, depending on the value of the Accept header
|
||||
func (output *BeegoOutput) ServeFormatted(data interface{}, hasIndent bool, hasEncode ...bool) {
|
||||
(*context.BeegoOutput)(output).ServeFormatted(data, hasIndent, hasEncode...)
|
||||
}
|
||||
|
||||
// Download forces response for download file.
|
||||
// it prepares the download response header automatically.
|
||||
func (output *BeegoOutput) Download(file string, filename ...string) {
|
||||
(*context.BeegoOutput)(output).Download(file, filename...)
|
||||
}
|
||||
|
||||
// ContentType sets the content type from ext string.
|
||||
// MIME type is given in mime package.
|
||||
func (output *BeegoOutput) ContentType(ext string) {
|
||||
(*context.BeegoOutput)(output).ContentType(ext)
|
||||
}
|
||||
|
||||
// SetStatus sets response status code.
|
||||
// It writes response header directly.
|
||||
func (output *BeegoOutput) SetStatus(status int) {
|
||||
(*context.BeegoOutput)(output).SetStatus(status)
|
||||
}
|
||||
|
||||
// IsCachable returns boolean of this request is cached.
|
||||
// HTTP 304 means cached.
|
||||
func (output *BeegoOutput) IsCachable() bool {
|
||||
return (*context.BeegoOutput)(output).IsCachable()
|
||||
}
|
||||
|
||||
// IsEmpty returns boolean of this request is empty.
|
||||
// HTTP 201,204 and 304 means empty.
|
||||
func (output *BeegoOutput) IsEmpty() bool {
|
||||
return (*context.BeegoOutput)(output).IsEmpty()
|
||||
}
|
||||
|
||||
// IsOk returns boolean of this request runs well.
|
||||
// HTTP 200 means ok.
|
||||
func (output *BeegoOutput) IsOk() bool {
|
||||
return (*context.BeegoOutput)(output).IsOk()
|
||||
}
|
||||
|
||||
// IsSuccessful returns boolean of this request runs successfully.
|
||||
// HTTP 2xx means ok.
|
||||
func (output *BeegoOutput) IsSuccessful() bool {
|
||||
return (*context.BeegoOutput)(output).IsSuccessful()
|
||||
}
|
||||
|
||||
// IsRedirect returns boolean of this request is redirection header.
|
||||
// HTTP 301,302,307 means redirection.
|
||||
func (output *BeegoOutput) IsRedirect() bool {
|
||||
return (*context.BeegoOutput)(output).IsRedirect()
|
||||
}
|
||||
|
||||
// IsForbidden returns boolean of this request is forbidden.
|
||||
// HTTP 403 means forbidden.
|
||||
func (output *BeegoOutput) IsForbidden() bool {
|
||||
return (*context.BeegoOutput)(output).IsForbidden()
|
||||
}
|
||||
|
||||
// IsNotFound returns boolean of this request is not found.
|
||||
// HTTP 404 means not found.
|
||||
func (output *BeegoOutput) IsNotFound() bool {
|
||||
return (*context.BeegoOutput)(output).IsNotFound()
|
||||
}
|
||||
|
||||
// IsClientError returns boolean of this request client sends error data.
|
||||
// HTTP 4xx means client error.
|
||||
func (output *BeegoOutput) IsClientError() bool {
|
||||
return (*context.BeegoOutput)(output).IsClientError()
|
||||
}
|
||||
|
||||
// IsServerError returns boolean of this server handler errors.
|
||||
// HTTP 5xx means server internal error.
|
||||
func (output *BeegoOutput) IsServerError() bool {
|
||||
return (*context.BeegoOutput)(output).IsServerError()
|
||||
}
|
||||
|
||||
// Session sets session item value with given key.
|
||||
func (output *BeegoOutput) Session(name interface{}, value interface{}) {
|
||||
(*context.BeegoOutput)(output).Session(name, value)
|
||||
}
|
8
adapter/context/renderer.go
Normal file
8
adapter/context/renderer.go
Normal file
@ -0,0 +1,8 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/server/web/context"
|
||||
)
|
||||
|
||||
// Renderer defines an http response renderer
|
||||
type Renderer context.Renderer
|
@ -1,16 +1,15 @@
|
||||
package context
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"net/http"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
//BadRequest indicates http error 400
|
||||
// BadRequest indicates http error 400
|
||||
BadRequest StatusCode = http.StatusBadRequest
|
||||
|
||||
//NotFound indicates http error 404
|
||||
// NotFound indicates http error 404
|
||||
NotFound StatusCode = http.StatusNotFound
|
||||
)
|
||||
|
399
adapter/controller.go
Normal file
399
adapter/controller.go
Normal file
@ -0,0 +1,399 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package adapter
|
||||
|
||||
import (
|
||||
"mime/multipart"
|
||||
"net/url"
|
||||
|
||||
"github.com/astaxie/beego/adapter/session"
|
||||
webContext "github.com/astaxie/beego/server/web/context"
|
||||
|
||||
"github.com/astaxie/beego/server/web"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrAbort custom error when user stop request handler manually.
|
||||
ErrAbort = web.ErrAbort
|
||||
// GlobalControllerRouter store comments with controller. pkgpath+controller:comments
|
||||
GlobalControllerRouter = web.GlobalControllerRouter
|
||||
)
|
||||
|
||||
// ControllerFilter store the filter for controller
|
||||
type ControllerFilter web.ControllerFilter
|
||||
|
||||
// ControllerFilterComments store the comment for controller level filter
|
||||
type ControllerFilterComments web.ControllerFilterComments
|
||||
|
||||
// ControllerImportComments store the import comment for controller needed
|
||||
type ControllerImportComments web.ControllerImportComments
|
||||
|
||||
// ControllerComments store the comment for the controller method
|
||||
type ControllerComments web.ControllerComments
|
||||
|
||||
// ControllerCommentsSlice implements the sort interface
|
||||
type ControllerCommentsSlice web.ControllerCommentsSlice
|
||||
|
||||
func (p ControllerCommentsSlice) Len() int {
|
||||
return (web.ControllerCommentsSlice)(p).Len()
|
||||
}
|
||||
func (p ControllerCommentsSlice) Less(i, j int) bool {
|
||||
return (web.ControllerCommentsSlice)(p).Less(i, j)
|
||||
}
|
||||
func (p ControllerCommentsSlice) Swap(i, j int) {
|
||||
(web.ControllerCommentsSlice)(p).Swap(i, j)
|
||||
}
|
||||
|
||||
// Controller defines some basic http request handler operations, such as
|
||||
// http context, template and view, session and xsrf.
|
||||
type Controller web.Controller
|
||||
|
||||
func (c *Controller) Init(ctx *webContext.Context, controllerName, actionName string, app interface{}) {
|
||||
(*web.Controller)(c).Init(ctx, controllerName, actionName, app)
|
||||
}
|
||||
|
||||
// ControllerInterface is an interface to uniform all controller handler.
|
||||
type ControllerInterface web.ControllerInterface
|
||||
|
||||
// Prepare runs after Init before request function execution.
|
||||
func (c *Controller) Prepare() {
|
||||
(*web.Controller)(c).Prepare()
|
||||
}
|
||||
|
||||
// Finish runs after request function execution.
|
||||
func (c *Controller) Finish() {
|
||||
(*web.Controller)(c).Finish()
|
||||
}
|
||||
|
||||
// Get adds a request function to handle GET request.
|
||||
func (c *Controller) Get() {
|
||||
(*web.Controller)(c).Get()
|
||||
}
|
||||
|
||||
// Post adds a request function to handle POST request.
|
||||
func (c *Controller) Post() {
|
||||
(*web.Controller)(c).Post()
|
||||
}
|
||||
|
||||
// Delete adds a request function to handle DELETE request.
|
||||
func (c *Controller) Delete() {
|
||||
(*web.Controller)(c).Delete()
|
||||
}
|
||||
|
||||
// Put adds a request function to handle PUT request.
|
||||
func (c *Controller) Put() {
|
||||
(*web.Controller)(c).Put()
|
||||
}
|
||||
|
||||
// Head adds a request function to handle HEAD request.
|
||||
func (c *Controller) Head() {
|
||||
(*web.Controller)(c).Head()
|
||||
}
|
||||
|
||||
// Patch adds a request function to handle PATCH request.
|
||||
func (c *Controller) Patch() {
|
||||
(*web.Controller)(c).Patch()
|
||||
}
|
||||
|
||||
// Options adds a request function to handle OPTIONS request.
|
||||
func (c *Controller) Options() {
|
||||
(*web.Controller)(c).Options()
|
||||
}
|
||||
|
||||
// Trace adds a request function to handle Trace request.
|
||||
// this method SHOULD NOT be overridden.
|
||||
// https://tools.ietf.org/html/rfc7231#section-4.3.8
|
||||
// The TRACE method requests a remote, application-level loop-back of
|
||||
// the request message. The final recipient of the request SHOULD
|
||||
// reflect the message received, excluding some fields described below,
|
||||
// back to the client as the message body of a 200 (OK) response with a
|
||||
// Content-Type of "message/http" (Section 8.3.1 of [RFC7230]).
|
||||
func (c *Controller) Trace() {
|
||||
(*web.Controller)(c).Trace()
|
||||
}
|
||||
|
||||
// HandlerFunc call function with the name
|
||||
func (c *Controller) HandlerFunc(fnname string) bool {
|
||||
return (*web.Controller)(c).HandlerFunc(fnname)
|
||||
}
|
||||
|
||||
// URLMapping register the internal Controller router.
|
||||
func (c *Controller) URLMapping() {
|
||||
(*web.Controller)(c).URLMapping()
|
||||
}
|
||||
|
||||
// Mapping the method to function
|
||||
func (c *Controller) Mapping(method string, fn func()) {
|
||||
(*web.Controller)(c).Mapping(method, fn)
|
||||
}
|
||||
|
||||
// Render sends the response with rendered template bytes as text/html type.
|
||||
func (c *Controller) Render() error {
|
||||
return (*web.Controller)(c).Render()
|
||||
}
|
||||
|
||||
// RenderString returns the rendered template string. Do not send out response.
|
||||
func (c *Controller) RenderString() (string, error) {
|
||||
return (*web.Controller)(c).RenderString()
|
||||
}
|
||||
|
||||
// RenderBytes returns the bytes of rendered template string. Do not send out response.
|
||||
func (c *Controller) RenderBytes() ([]byte, error) {
|
||||
return (*web.Controller)(c).RenderBytes()
|
||||
}
|
||||
|
||||
// Redirect sends the redirection response to url with status code.
|
||||
func (c *Controller) Redirect(url string, code int) {
|
||||
(*web.Controller)(c).Redirect(url, code)
|
||||
}
|
||||
|
||||
// SetData set the data depending on the accepted
|
||||
func (c *Controller) SetData(data interface{}) {
|
||||
(*web.Controller)(c).SetData(data)
|
||||
}
|
||||
|
||||
// Abort stops controller handler and show the error data if code is defined in ErrorMap or code string.
|
||||
func (c *Controller) Abort(code string) {
|
||||
(*web.Controller)(c).Abort(code)
|
||||
}
|
||||
|
||||
// CustomAbort stops controller handler and show the error data, it's similar Aborts, but support status code and body.
|
||||
func (c *Controller) CustomAbort(status int, body string) {
|
||||
(*web.Controller)(c).CustomAbort(status, body)
|
||||
}
|
||||
|
||||
// StopRun makes panic of USERSTOPRUN error and go to recover function if defined.
|
||||
func (c *Controller) StopRun() {
|
||||
(*web.Controller)(c).StopRun()
|
||||
}
|
||||
|
||||
// URLFor does another controller handler in this request function.
|
||||
// it goes to this controller method if endpoint is not clear.
|
||||
func (c *Controller) URLFor(endpoint string, values ...interface{}) string {
|
||||
return (*web.Controller)(c).URLFor(endpoint, values...)
|
||||
}
|
||||
|
||||
// ServeJSON sends a json response with encoding charset.
|
||||
func (c *Controller) ServeJSON(encoding ...bool) {
|
||||
(*web.Controller)(c).ServeJSON(encoding...)
|
||||
}
|
||||
|
||||
// ServeJSONP sends a jsonp response.
|
||||
func (c *Controller) ServeJSONP() {
|
||||
(*web.Controller)(c).ServeJSONP()
|
||||
}
|
||||
|
||||
// ServeXML sends xml response.
|
||||
func (c *Controller) ServeXML() {
|
||||
(*web.Controller)(c).ServeXML()
|
||||
}
|
||||
|
||||
// ServeYAML sends yaml response.
|
||||
func (c *Controller) ServeYAML() {
|
||||
(*web.Controller)(c).ServeYAML()
|
||||
}
|
||||
|
||||
// ServeFormatted serve YAML, XML OR JSON, depending on the value of the Accept header
|
||||
func (c *Controller) ServeFormatted(encoding ...bool) {
|
||||
(*web.Controller)(c).ServeFormatted(encoding...)
|
||||
}
|
||||
|
||||
// Input returns the input data map from POST or PUT request body and query string.
|
||||
func (c *Controller) Input() url.Values {
|
||||
return (*web.Controller)(c).Input()
|
||||
}
|
||||
|
||||
// ParseForm maps input data map to obj struct.
|
||||
func (c *Controller) ParseForm(obj interface{}) error {
|
||||
return (*web.Controller)(c).ParseForm(obj)
|
||||
}
|
||||
|
||||
// GetString returns the input value by key string or the default value while it's present and input is blank
|
||||
func (c *Controller) GetString(key string, def ...string) string {
|
||||
return (*web.Controller)(c).GetString(key, def...)
|
||||
}
|
||||
|
||||
// GetStrings returns the input string slice by key string or the default value while it's present and input is blank
|
||||
// it's designed for multi-value input field such as checkbox(input[type=checkbox]), multi-selection.
|
||||
func (c *Controller) GetStrings(key string, def ...[]string) []string {
|
||||
return (*web.Controller)(c).GetStrings(key, def...)
|
||||
}
|
||||
|
||||
// GetInt returns input as an int or the default value while it's present and input is blank
|
||||
func (c *Controller) GetInt(key string, def ...int) (int, error) {
|
||||
return (*web.Controller)(c).GetInt(key, def...)
|
||||
}
|
||||
|
||||
// GetInt8 return input as an int8 or the default value while it's present and input is blank
|
||||
func (c *Controller) GetInt8(key string, def ...int8) (int8, error) {
|
||||
return (*web.Controller)(c).GetInt8(key, def...)
|
||||
}
|
||||
|
||||
// GetUint8 return input as an uint8 or the default value while it's present and input is blank
|
||||
func (c *Controller) GetUint8(key string, def ...uint8) (uint8, error) {
|
||||
return (*web.Controller)(c).GetUint8(key, def...)
|
||||
}
|
||||
|
||||
// GetInt16 returns input as an int16 or the default value while it's present and input is blank
|
||||
func (c *Controller) GetInt16(key string, def ...int16) (int16, error) {
|
||||
return (*web.Controller)(c).GetInt16(key, def...)
|
||||
}
|
||||
|
||||
// GetUint16 returns input as an uint16 or the default value while it's present and input is blank
|
||||
func (c *Controller) GetUint16(key string, def ...uint16) (uint16, error) {
|
||||
return (*web.Controller)(c).GetUint16(key, def...)
|
||||
}
|
||||
|
||||
// GetInt32 returns input as an int32 or the default value while it's present and input is blank
|
||||
func (c *Controller) GetInt32(key string, def ...int32) (int32, error) {
|
||||
return (*web.Controller)(c).GetInt32(key, def...)
|
||||
}
|
||||
|
||||
// GetUint32 returns input as an uint32 or the default value while it's present and input is blank
|
||||
func (c *Controller) GetUint32(key string, def ...uint32) (uint32, error) {
|
||||
return (*web.Controller)(c).GetUint32(key, def...)
|
||||
}
|
||||
|
||||
// GetInt64 returns input value as int64 or the default value while it's present and input is blank.
|
||||
func (c *Controller) GetInt64(key string, def ...int64) (int64, error) {
|
||||
return (*web.Controller)(c).GetInt64(key, def...)
|
||||
}
|
||||
|
||||
// GetUint64 returns input value as uint64 or the default value while it's present and input is blank.
|
||||
func (c *Controller) GetUint64(key string, def ...uint64) (uint64, error) {
|
||||
return (*web.Controller)(c).GetUint64(key, def...)
|
||||
}
|
||||
|
||||
// GetBool returns input value as bool or the default value while it's present and input is blank.
|
||||
func (c *Controller) GetBool(key string, def ...bool) (bool, error) {
|
||||
return (*web.Controller)(c).GetBool(key, def...)
|
||||
}
|
||||
|
||||
// GetFloat returns input value as float64 or the default value while it's present and input is blank.
|
||||
func (c *Controller) GetFloat(key string, def ...float64) (float64, error) {
|
||||
return (*web.Controller)(c).GetFloat(key, def...)
|
||||
}
|
||||
|
||||
// GetFile returns the file data in file upload field named as key.
|
||||
// it returns the first one of multi-uploaded files.
|
||||
func (c *Controller) GetFile(key string) (multipart.File, *multipart.FileHeader, error) {
|
||||
return (*web.Controller)(c).GetFile(key)
|
||||
}
|
||||
|
||||
// GetFiles return multi-upload files
|
||||
// files, err:=c.GetFiles("myfiles")
|
||||
// if err != nil {
|
||||
// http.Error(w, err.Error(), http.StatusNoContent)
|
||||
// return
|
||||
// }
|
||||
// for i, _ := range files {
|
||||
// //for each fileheader, get a handle to the actual file
|
||||
// file, err := files[i].Open()
|
||||
// defer file.Close()
|
||||
// if err != nil {
|
||||
// http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
// return
|
||||
// }
|
||||
// //create destination file making sure the path is writeable.
|
||||
// dst, err := os.Create("upload/" + files[i].Filename)
|
||||
// defer dst.Close()
|
||||
// if err != nil {
|
||||
// http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
// return
|
||||
// }
|
||||
// //copy the uploaded file to the destination file
|
||||
// if _, err := io.Copy(dst, file); err != nil {
|
||||
// http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
func (c *Controller) GetFiles(key string) ([]*multipart.FileHeader, error) {
|
||||
return (*web.Controller)(c).GetFiles(key)
|
||||
}
|
||||
|
||||
// SaveToFile saves uploaded file to new path.
|
||||
// it only operates the first one of mutil-upload form file field.
|
||||
func (c *Controller) SaveToFile(fromfile, tofile string) error {
|
||||
return (*web.Controller)(c).SaveToFile(fromfile, tofile)
|
||||
}
|
||||
|
||||
// StartSession starts session and load old session data info this controller.
|
||||
func (c *Controller) StartSession() session.Store {
|
||||
s := (*web.Controller)(c).StartSession()
|
||||
return session.CreateNewToOldStoreAdapter(s)
|
||||
}
|
||||
|
||||
// SetSession puts value into session.
|
||||
func (c *Controller) SetSession(name interface{}, value interface{}) {
|
||||
(*web.Controller)(c).SetSession(name, value)
|
||||
}
|
||||
|
||||
// GetSession gets value from session.
|
||||
func (c *Controller) GetSession(name interface{}) interface{} {
|
||||
return (*web.Controller)(c).GetSession(name)
|
||||
}
|
||||
|
||||
// DelSession removes value from session.
|
||||
func (c *Controller) DelSession(name interface{}) {
|
||||
(*web.Controller)(c).DelSession(name)
|
||||
}
|
||||
|
||||
// SessionRegenerateID regenerates session id for this session.
|
||||
// the session data have no changes.
|
||||
func (c *Controller) SessionRegenerateID() {
|
||||
(*web.Controller)(c).SessionRegenerateID()
|
||||
}
|
||||
|
||||
// DestroySession cleans session data and session cookie.
|
||||
func (c *Controller) DestroySession() {
|
||||
(*web.Controller)(c).DestroySession()
|
||||
}
|
||||
|
||||
// IsAjax returns this request is ajax or not.
|
||||
func (c *Controller) IsAjax() bool {
|
||||
return (*web.Controller)(c).IsAjax()
|
||||
}
|
||||
|
||||
// GetSecureCookie returns decoded cookie value from encoded browser cookie values.
|
||||
func (c *Controller) GetSecureCookie(Secret, key string) (string, bool) {
|
||||
return (*web.Controller)(c).GetSecureCookie(Secret, key)
|
||||
}
|
||||
|
||||
// SetSecureCookie puts value into cookie after encoded the value.
|
||||
func (c *Controller) SetSecureCookie(Secret, name, value string, others ...interface{}) {
|
||||
(*web.Controller)(c).SetSecureCookie(Secret, name, value, others...)
|
||||
}
|
||||
|
||||
// XSRFToken creates a CSRF token string and returns.
|
||||
func (c *Controller) XSRFToken() string {
|
||||
return (*web.Controller)(c).XSRFToken()
|
||||
}
|
||||
|
||||
// CheckXSRFCookie checks xsrf token in this request is valid or not.
|
||||
// the token can provided in request header "X-Xsrftoken" and "X-CsrfToken"
|
||||
// or in form field value named as "_xsrf".
|
||||
func (c *Controller) CheckXSRFCookie() bool {
|
||||
return (*web.Controller)(c).CheckXSRFCookie()
|
||||
}
|
||||
|
||||
// XSRFFormHTML writes an input field contains xsrf token value.
|
||||
func (c *Controller) XSRFFormHTML() string {
|
||||
return (*web.Controller)(c).XSRFFormHTML()
|
||||
}
|
||||
|
||||
// GetControllerAndAction gets the executing controller name and action name.
|
||||
func (c *Controller) GetControllerAndAction() (string, string) {
|
||||
return (*web.Controller)(c).GetControllerAndAction()
|
||||
}
|
16
adapter/doc.go
Normal file
16
adapter/doc.go
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright 2020
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// used to keep compatible with v1.x
|
||||
package adapter
|
202
adapter/error.go
Normal file
202
adapter/error.go
Normal file
@ -0,0 +1,202 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package adapter
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/astaxie/beego/adapter/context"
|
||||
beecontext "github.com/astaxie/beego/server/web/context"
|
||||
|
||||
"github.com/astaxie/beego/server/web"
|
||||
)
|
||||
|
||||
const (
|
||||
errorTypeHandler = iota
|
||||
errorTypeController
|
||||
)
|
||||
|
||||
var tpl = `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<title>beego application error</title>
|
||||
<style>
|
||||
html, body, body * {padding: 0; margin: 0;}
|
||||
#header {background:#ffd; border-bottom:solid 2px #A31515; padding: 20px 10px;}
|
||||
#header h2{ }
|
||||
#footer {border-top:solid 1px #aaa; padding: 5px 10px; font-size: 12px; color:green;}
|
||||
#content {padding: 5px;}
|
||||
#content .stack b{ font-size: 13px; color: red;}
|
||||
#content .stack pre{padding-left: 10px;}
|
||||
table {}
|
||||
td.t {text-align: right; padding-right: 5px; color: #888;}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="header">
|
||||
<h2>{{.AppError}}</h2>
|
||||
</div>
|
||||
<div id="content">
|
||||
<table>
|
||||
<tr>
|
||||
<td class="t">Request Method: </td><td>{{.RequestMethod}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="t">Request URL: </td><td>{{.RequestURL}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="t">RemoteAddr: </td><td>{{.RemoteAddr }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<div class="stack">
|
||||
<b>Stack</b>
|
||||
<pre>{{.Stack}}</pre>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<p>beego {{ .BeegoVersion }} (beego framework)</p>
|
||||
<p>golang version: {{.GoVersion}}</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
|
||||
var errtpl = `
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>{{.Title}}</title>
|
||||
<style type="text/css">
|
||||
* {
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color:#EFEFEF;
|
||||
font: .9em "Lucida Sans Unicode", "Lucida Grande", sans-serif;
|
||||
}
|
||||
|
||||
#wrapper{
|
||||
width:600px;
|
||||
margin:40px auto 0;
|
||||
text-align:center;
|
||||
-moz-box-shadow: 5px 5px 10px rgba(0,0,0,0.3);
|
||||
-webkit-box-shadow: 5px 5px 10px rgba(0,0,0,0.3);
|
||||
box-shadow: 5px 5px 10px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
#wrapper h1{
|
||||
color:#FFF;
|
||||
text-align:center;
|
||||
margin-bottom:20px;
|
||||
}
|
||||
|
||||
#wrapper a{
|
||||
display:block;
|
||||
font-size:.9em;
|
||||
padding-top:20px;
|
||||
color:#FFF;
|
||||
text-decoration:none;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
#container {
|
||||
width:600px;
|
||||
padding-bottom:15px;
|
||||
background-color:#FFFFFF;
|
||||
}
|
||||
|
||||
.navtop{
|
||||
height:40px;
|
||||
background-color:#24B2EB;
|
||||
padding:13px;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding:10px 10px 25px;
|
||||
background: #FFFFFF;
|
||||
margin:;
|
||||
color:#333;
|
||||
}
|
||||
|
||||
a.button{
|
||||
color:white;
|
||||
padding:15px 20px;
|
||||
text-shadow:1px 1px 0 #00A5FF;
|
||||
font-weight:bold;
|
||||
text-align:center;
|
||||
border:1px solid #24B2EB;
|
||||
margin:0px 200px;
|
||||
clear:both;
|
||||
background-color: #24B2EB;
|
||||
border-radius:100px;
|
||||
-moz-border-radius:100px;
|
||||
-webkit-border-radius:100px;
|
||||
}
|
||||
|
||||
a.button:hover{
|
||||
text-decoration:none;
|
||||
background-color: #24B2EB;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
<div id="container">
|
||||
<div class="navtop">
|
||||
<h1>{{.Title}}</h1>
|
||||
</div>
|
||||
<div id="content">
|
||||
{{.Content}}
|
||||
<a href="/" title="Home" class="button">Go Home</a><br />
|
||||
|
||||
<br>Powered by beego {{.BeegoVersion}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
`
|
||||
|
||||
// ErrorMaps holds map of http handlers for each error string.
|
||||
// there is 10 kinds default error(40x and 50x)
|
||||
var ErrorMaps = web.ErrorMaps
|
||||
|
||||
// ErrorHandler registers http.HandlerFunc to each http err code string.
|
||||
// usage:
|
||||
// beego.ErrorHandler("404",NotFound)
|
||||
// beego.ErrorHandler("500",InternalServerError)
|
||||
func ErrorHandler(code string, h http.HandlerFunc) *App {
|
||||
return (*App)(web.ErrorHandler(code, h))
|
||||
}
|
||||
|
||||
// ErrorController registers ControllerInterface to each http err code string.
|
||||
// usage:
|
||||
// beego.ErrorController(&controllers.ErrorController{})
|
||||
func ErrorController(c ControllerInterface) *App {
|
||||
return (*App)(web.ErrorController(c))
|
||||
}
|
||||
|
||||
// Exception Write HttpStatus with errCode and Exec error handler if exist.
|
||||
func Exception(errCode uint64, ctx *context.Context) {
|
||||
web.Exception(errCode, (*beecontext.Context)(ctx))
|
||||
}
|
@ -12,9 +12,13 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package beego
|
||||
package adapter
|
||||
|
||||
import "github.com/astaxie/beego/context"
|
||||
import (
|
||||
"github.com/astaxie/beego/adapter/context"
|
||||
"github.com/astaxie/beego/server/web"
|
||||
beecontext "github.com/astaxie/beego/server/web/context"
|
||||
)
|
||||
|
||||
// FilterFunc defines a filter function which is invoked before the controller handler is executed.
|
||||
type FilterFunc func(*context.Context)
|
||||
@ -22,23 +26,11 @@ type FilterFunc func(*context.Context)
|
||||
// FilterRouter defines a filter operation which is invoked before the controller handler is executed.
|
||||
// It can match the URL against a pattern, and execute a filter function
|
||||
// when a request with a matching URL arrives.
|
||||
type FilterRouter struct {
|
||||
filterFunc FilterFunc
|
||||
tree *Tree
|
||||
pattern string
|
||||
returnOnOutput bool
|
||||
resetParams bool
|
||||
}
|
||||
type FilterRouter web.FilterRouter
|
||||
|
||||
// ValidRouter checks if the current request is matched by this filter.
|
||||
// If the request is matched, the values of the URL parameters defined
|
||||
// by the filter pattern are also returned.
|
||||
func (f *FilterRouter) ValidRouter(url string, ctx *context.Context) bool {
|
||||
isOk := f.tree.Match(url, ctx)
|
||||
if isOk != nil {
|
||||
if b, ok := isOk.(bool); ok {
|
||||
return b
|
||||
}
|
||||
}
|
||||
return false
|
||||
return (*web.FilterRouter)(f).ValidRouter(url, (*beecontext.Context)(ctx))
|
||||
}
|
63
adapter/flash.go
Normal file
63
adapter/flash.go
Normal file
@ -0,0 +1,63 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package adapter
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/server/web"
|
||||
)
|
||||
|
||||
// FlashData is a tools to maintain data when using across request.
|
||||
type FlashData web.FlashData
|
||||
|
||||
// NewFlash return a new empty FlashData struct.
|
||||
func NewFlash() *FlashData {
|
||||
return (*FlashData)(web.NewFlash())
|
||||
}
|
||||
|
||||
// Set message to flash
|
||||
func (fd *FlashData) Set(key string, msg string, args ...interface{}) {
|
||||
(*web.FlashData)(fd).Set(key, msg, args...)
|
||||
}
|
||||
|
||||
// Success writes success message to flash.
|
||||
func (fd *FlashData) Success(msg string, args ...interface{}) {
|
||||
(*web.FlashData)(fd).Success(msg, args...)
|
||||
}
|
||||
|
||||
// Notice writes notice message to flash.
|
||||
func (fd *FlashData) Notice(msg string, args ...interface{}) {
|
||||
(*web.FlashData)(fd).Notice(msg, args...)
|
||||
}
|
||||
|
||||
// Warning writes warning message to flash.
|
||||
func (fd *FlashData) Warning(msg string, args ...interface{}) {
|
||||
(*web.FlashData)(fd).Warning(msg, args...)
|
||||
}
|
||||
|
||||
// Error writes error message to flash.
|
||||
func (fd *FlashData) Error(msg string, args ...interface{}) {
|
||||
(*web.FlashData)(fd).Error(msg, args...)
|
||||
}
|
||||
|
||||
// Store does the saving operation of flash data.
|
||||
// the data are encoded and saved in cookie.
|
||||
func (fd *FlashData) Store(c *Controller) {
|
||||
(*web.FlashData)(fd).Store((*web.Controller)(c))
|
||||
}
|
||||
|
||||
// ReadFromRequest parsed flash data from encoded values in cookie.
|
||||
func ReadFromRequest(c *Controller) *FlashData {
|
||||
return (*FlashData)(web.ReadFromRequest((*web.Controller)(c)))
|
||||
}
|
35
adapter/fs.go
Normal file
35
adapter/fs.go
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright 2020
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package adapter
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/astaxie/beego/server/web"
|
||||
)
|
||||
|
||||
type FileSystem web.FileSystem
|
||||
|
||||
func (d FileSystem) Open(name string) (http.File, error) {
|
||||
return (web.FileSystem)(d).Open(name)
|
||||
}
|
||||
|
||||
// Walk walks the file tree rooted at root in filesystem, calling walkFn for each file or
|
||||
// directory in the tree, including root. All errors that arise visiting files
|
||||
// and directories are filtered by walkFn.
|
||||
func Walk(fs http.FileSystem, root string, walkFn filepath.WalkFunc) error {
|
||||
return web.Walk(fs, root, walkFn)
|
||||
}
|
94
adapter/grace/grace.go
Normal file
94
adapter/grace/grace.go
Normal file
@ -0,0 +1,94 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package grace use to hot reload
|
||||
// Description: http://grisha.org/blog/2014/06/03/graceful-restart-in-golang/
|
||||
//
|
||||
// Usage:
|
||||
//
|
||||
// import(
|
||||
// "log"
|
||||
// "net/http"
|
||||
// "os"
|
||||
//
|
||||
// "github.com/astaxie/beego/grace"
|
||||
// )
|
||||
//
|
||||
// func handler(w http.ResponseWriter, r *http.Request) {
|
||||
// w.Write([]byte("WORLD!"))
|
||||
// }
|
||||
//
|
||||
// func main() {
|
||||
// mux := http.NewServeMux()
|
||||
// mux.HandleFunc("/hello", handler)
|
||||
//
|
||||
// err := grace.ListenAndServe("localhost:8080", mux)
|
||||
// if err != nil {
|
||||
// log.Println(err)
|
||||
// }
|
||||
// log.Println("Server on 8080 stopped")
|
||||
// os.Exit(0)
|
||||
// }
|
||||
package grace
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego/server/web/grace"
|
||||
)
|
||||
|
||||
const (
|
||||
// PreSignal is the position to add filter before signal
|
||||
PreSignal = iota
|
||||
// PostSignal is the position to add filter after signal
|
||||
PostSignal
|
||||
// StateInit represent the application inited
|
||||
StateInit
|
||||
// StateRunning represent the application is running
|
||||
StateRunning
|
||||
// StateShuttingDown represent the application is shutting down
|
||||
StateShuttingDown
|
||||
// StateTerminate represent the application is killed
|
||||
StateTerminate
|
||||
)
|
||||
|
||||
var (
|
||||
|
||||
// DefaultReadTimeOut is the HTTP read timeout
|
||||
DefaultReadTimeOut time.Duration
|
||||
// DefaultWriteTimeOut is the HTTP Write timeout
|
||||
DefaultWriteTimeOut time.Duration
|
||||
// DefaultMaxHeaderBytes is the Max HTTP Header size, default is 0, no limit
|
||||
DefaultMaxHeaderBytes int
|
||||
// DefaultTimeout is the shutdown server's timeout. default is 60s
|
||||
DefaultTimeout = grace.DefaultTimeout
|
||||
)
|
||||
|
||||
// NewServer returns a new graceServer.
|
||||
func NewServer(addr string, handler http.Handler) (srv *Server) {
|
||||
return (*Server)(grace.NewServer(addr, handler))
|
||||
}
|
||||
|
||||
// ListenAndServe refer http.ListenAndServe
|
||||
func ListenAndServe(addr string, handler http.Handler) error {
|
||||
server := NewServer(addr, handler)
|
||||
return server.ListenAndServe()
|
||||
}
|
||||
|
||||
// ListenAndServeTLS refer http.ListenAndServeTLS
|
||||
func ListenAndServeTLS(addr string, certFile string, keyFile string, handler http.Handler) error {
|
||||
server := NewServer(addr, handler)
|
||||
return server.ListenAndServeTLS(certFile, keyFile)
|
||||
}
|
48
adapter/grace/server.go
Normal file
48
adapter/grace/server.go
Normal file
@ -0,0 +1,48 @@
|
||||
package grace
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/astaxie/beego/server/web/grace"
|
||||
)
|
||||
|
||||
// Server embedded http.Server
|
||||
type Server grace.Server
|
||||
|
||||
// Serve accepts incoming connections on the Listener l,
|
||||
// creating a new service goroutine for each.
|
||||
// The service goroutines read requests and then call srv.Handler to reply to them.
|
||||
func (srv *Server) Serve() (err error) {
|
||||
return (*grace.Server)(srv).Serve()
|
||||
}
|
||||
|
||||
// ListenAndServe listens on the TCP network address srv.Addr and then calls Serve
|
||||
// to handle requests on incoming connections. If srv.Addr is blank, ":http" is
|
||||
// used.
|
||||
func (srv *Server) ListenAndServe() (err error) {
|
||||
return (*grace.Server)(srv).ListenAndServe()
|
||||
}
|
||||
|
||||
// ListenAndServeTLS listens on the TCP network address srv.Addr and then calls
|
||||
// Serve to handle requests on incoming TLS connections.
|
||||
//
|
||||
// Filenames containing a certificate and matching private key for the server must
|
||||
// be provided. If the certificate is signed by a certificate authority, the
|
||||
// certFile should be the concatenation of the server's certificate followed by the
|
||||
// CA's certificate.
|
||||
//
|
||||
// If srv.Addr is blank, ":https" is used.
|
||||
func (srv *Server) ListenAndServeTLS(certFile, keyFile string) error {
|
||||
return (*grace.Server)(srv).ListenAndServeTLS(certFile, keyFile)
|
||||
}
|
||||
|
||||
// ListenAndServeMutualTLS listens on the TCP network address srv.Addr and then calls
|
||||
// Serve to handle requests on incoming mutual TLS connections.
|
||||
func (srv *Server) ListenAndServeMutualTLS(certFile, keyFile, trustFile string) error {
|
||||
return (*grace.Server)(srv).ListenAndServeMutualTLS(certFile, keyFile, trustFile)
|
||||
}
|
||||
|
||||
// RegisterSignalHook registers a function to be run PreSignal or PostSignal for a given signal.
|
||||
func (srv *Server) RegisterSignalHook(ppFlag int, sig os.Signal, f func()) error {
|
||||
return (*grace.Server)(srv).RegisterSignalHook(ppFlag, sig, f)
|
||||
}
|
300
adapter/httplib/httplib.go
Normal file
300
adapter/httplib/httplib.go
Normal file
@ -0,0 +1,300 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package httplib is used as http.Client
|
||||
// Usage:
|
||||
//
|
||||
// import "github.com/astaxie/beego/httplib"
|
||||
//
|
||||
// b := httplib.Post("http://beego.me/")
|
||||
// b.Param("username","astaxie")
|
||||
// b.Param("password","123456")
|
||||
// b.PostFile("uploadfile1", "httplib.pdf")
|
||||
// b.PostFile("uploadfile2", "httplib.txt")
|
||||
// str, err := b.String()
|
||||
// if err != nil {
|
||||
// t.Fatal(err)
|
||||
// }
|
||||
// fmt.Println(str)
|
||||
//
|
||||
// more docs http://beego.me/docs/module/httplib.md
|
||||
package httplib
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego/client/httplib"
|
||||
)
|
||||
|
||||
// SetDefaultSetting Overwrite default settings
|
||||
func SetDefaultSetting(setting BeegoHTTPSettings) {
|
||||
httplib.SetDefaultSetting(httplib.BeegoHTTPSettings(setting))
|
||||
}
|
||||
|
||||
// NewBeegoRequest return *BeegoHttpRequest with specific method
|
||||
func NewBeegoRequest(rawurl, method string) *BeegoHTTPRequest {
|
||||
return &BeegoHTTPRequest{
|
||||
delegate: httplib.NewBeegoRequest(rawurl, method),
|
||||
}
|
||||
}
|
||||
|
||||
// Get returns *BeegoHttpRequest with GET method.
|
||||
func Get(url string) *BeegoHTTPRequest {
|
||||
return NewBeegoRequest(url, "GET")
|
||||
}
|
||||
|
||||
// Post returns *BeegoHttpRequest with POST method.
|
||||
func Post(url string) *BeegoHTTPRequest {
|
||||
return NewBeegoRequest(url, "POST")
|
||||
}
|
||||
|
||||
// Put returns *BeegoHttpRequest with PUT method.
|
||||
func Put(url string) *BeegoHTTPRequest {
|
||||
return NewBeegoRequest(url, "PUT")
|
||||
}
|
||||
|
||||
// Delete returns *BeegoHttpRequest DELETE method.
|
||||
func Delete(url string) *BeegoHTTPRequest {
|
||||
return NewBeegoRequest(url, "DELETE")
|
||||
}
|
||||
|
||||
// Head returns *BeegoHttpRequest with HEAD method.
|
||||
func Head(url string) *BeegoHTTPRequest {
|
||||
return NewBeegoRequest(url, "HEAD")
|
||||
}
|
||||
|
||||
// BeegoHTTPSettings is the http.Client setting
|
||||
type BeegoHTTPSettings httplib.BeegoHTTPSettings
|
||||
|
||||
// BeegoHTTPRequest provides more useful methods for requesting one url than http.Request.
|
||||
type BeegoHTTPRequest struct {
|
||||
delegate *httplib.BeegoHTTPRequest
|
||||
}
|
||||
|
||||
// GetRequest return the request object
|
||||
func (b *BeegoHTTPRequest) GetRequest() *http.Request {
|
||||
return b.delegate.GetRequest()
|
||||
}
|
||||
|
||||
// Setting Change request settings
|
||||
func (b *BeegoHTTPRequest) Setting(setting BeegoHTTPSettings) *BeegoHTTPRequest {
|
||||
b.delegate.Setting(httplib.BeegoHTTPSettings(setting))
|
||||
return b
|
||||
}
|
||||
|
||||
// SetBasicAuth sets the request's Authorization header to use HTTP Basic Authentication with the provided username and password.
|
||||
func (b *BeegoHTTPRequest) SetBasicAuth(username, password string) *BeegoHTTPRequest {
|
||||
b.delegate.SetBasicAuth(username, password)
|
||||
return b
|
||||
}
|
||||
|
||||
// SetEnableCookie sets enable/disable cookiejar
|
||||
func (b *BeegoHTTPRequest) SetEnableCookie(enable bool) *BeegoHTTPRequest {
|
||||
b.delegate.SetEnableCookie(enable)
|
||||
return b
|
||||
}
|
||||
|
||||
// SetUserAgent sets User-Agent header field
|
||||
func (b *BeegoHTTPRequest) SetUserAgent(useragent string) *BeegoHTTPRequest {
|
||||
b.delegate.SetUserAgent(useragent)
|
||||
return b
|
||||
}
|
||||
|
||||
// Debug sets show debug or not when executing request.
|
||||
func (b *BeegoHTTPRequest) Debug(isdebug bool) *BeegoHTTPRequest {
|
||||
b.delegate.Debug(isdebug)
|
||||
return b
|
||||
}
|
||||
|
||||
// Retries sets Retries times.
|
||||
// default is 0 means no retried.
|
||||
// -1 means retried forever.
|
||||
// others means retried times.
|
||||
func (b *BeegoHTTPRequest) Retries(times int) *BeegoHTTPRequest {
|
||||
b.delegate.Retries(times)
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *BeegoHTTPRequest) RetryDelay(delay time.Duration) *BeegoHTTPRequest {
|
||||
b.delegate.RetryDelay(delay)
|
||||
return b
|
||||
}
|
||||
|
||||
// DumpBody setting whether need to Dump the Body.
|
||||
func (b *BeegoHTTPRequest) DumpBody(isdump bool) *BeegoHTTPRequest {
|
||||
b.delegate.DumpBody(isdump)
|
||||
return b
|
||||
}
|
||||
|
||||
// DumpRequest return the DumpRequest
|
||||
func (b *BeegoHTTPRequest) DumpRequest() []byte {
|
||||
return b.delegate.DumpRequest()
|
||||
}
|
||||
|
||||
// SetTimeout sets connect time out and read-write time out for BeegoRequest.
|
||||
func (b *BeegoHTTPRequest) SetTimeout(connectTimeout, readWriteTimeout time.Duration) *BeegoHTTPRequest {
|
||||
b.delegate.SetTimeout(connectTimeout, readWriteTimeout)
|
||||
return b
|
||||
}
|
||||
|
||||
// SetTLSClientConfig sets tls connection configurations if visiting https url.
|
||||
func (b *BeegoHTTPRequest) SetTLSClientConfig(config *tls.Config) *BeegoHTTPRequest {
|
||||
b.delegate.SetTLSClientConfig(config)
|
||||
return b
|
||||
}
|
||||
|
||||
// Header add header item string in request.
|
||||
func (b *BeegoHTTPRequest) Header(key, value string) *BeegoHTTPRequest {
|
||||
b.delegate.Header(key, value)
|
||||
return b
|
||||
}
|
||||
|
||||
// SetHost set the request host
|
||||
func (b *BeegoHTTPRequest) SetHost(host string) *BeegoHTTPRequest {
|
||||
b.delegate.SetHost(host)
|
||||
return b
|
||||
}
|
||||
|
||||
// SetProtocolVersion Set the protocol version for incoming requests.
|
||||
// Client requests always use HTTP/1.1.
|
||||
func (b *BeegoHTTPRequest) SetProtocolVersion(vers string) *BeegoHTTPRequest {
|
||||
b.delegate.SetProtocolVersion(vers)
|
||||
return b
|
||||
}
|
||||
|
||||
// SetCookie add cookie into request.
|
||||
func (b *BeegoHTTPRequest) SetCookie(cookie *http.Cookie) *BeegoHTTPRequest {
|
||||
b.delegate.SetCookie(cookie)
|
||||
return b
|
||||
}
|
||||
|
||||
// SetTransport set the setting transport
|
||||
func (b *BeegoHTTPRequest) SetTransport(transport http.RoundTripper) *BeegoHTTPRequest {
|
||||
b.delegate.SetTransport(transport)
|
||||
return b
|
||||
}
|
||||
|
||||
// SetProxy set the http proxy
|
||||
// example:
|
||||
//
|
||||
// func(req *http.Request) (*url.URL, error) {
|
||||
// u, _ := url.ParseRequestURI("http://127.0.0.1:8118")
|
||||
// return u, nil
|
||||
// }
|
||||
func (b *BeegoHTTPRequest) SetProxy(proxy func(*http.Request) (*url.URL, error)) *BeegoHTTPRequest {
|
||||
b.delegate.SetProxy(proxy)
|
||||
return b
|
||||
}
|
||||
|
||||
// SetCheckRedirect specifies the policy for handling redirects.
|
||||
//
|
||||
// If CheckRedirect is nil, the Client uses its default policy,
|
||||
// which is to stop after 10 consecutive requests.
|
||||
func (b *BeegoHTTPRequest) SetCheckRedirect(redirect func(req *http.Request, via []*http.Request) error) *BeegoHTTPRequest {
|
||||
b.delegate.SetCheckRedirect(redirect)
|
||||
return b
|
||||
}
|
||||
|
||||
// Param adds query param in to request.
|
||||
// params build query string as ?key1=value1&key2=value2...
|
||||
func (b *BeegoHTTPRequest) Param(key, value string) *BeegoHTTPRequest {
|
||||
b.delegate.Param(key, value)
|
||||
return b
|
||||
}
|
||||
|
||||
// PostFile add a post file to the request
|
||||
func (b *BeegoHTTPRequest) PostFile(formname, filename string) *BeegoHTTPRequest {
|
||||
b.delegate.PostFile(formname, filename)
|
||||
return b
|
||||
}
|
||||
|
||||
// Body adds request raw body.
|
||||
// it supports string and []byte.
|
||||
func (b *BeegoHTTPRequest) Body(data interface{}) *BeegoHTTPRequest {
|
||||
b.delegate.Body(data)
|
||||
return b
|
||||
}
|
||||
|
||||
// XMLBody adds request raw body encoding by XML.
|
||||
func (b *BeegoHTTPRequest) XMLBody(obj interface{}) (*BeegoHTTPRequest, error) {
|
||||
_, err := b.delegate.XMLBody(obj)
|
||||
return b, err
|
||||
}
|
||||
|
||||
// YAMLBody adds request raw body encoding by YAML.
|
||||
func (b *BeegoHTTPRequest) YAMLBody(obj interface{}) (*BeegoHTTPRequest, error) {
|
||||
_, err := b.delegate.YAMLBody(obj)
|
||||
return b, err
|
||||
}
|
||||
|
||||
// JSONBody adds request raw body encoding by JSON.
|
||||
func (b *BeegoHTTPRequest) JSONBody(obj interface{}) (*BeegoHTTPRequest, error) {
|
||||
_, err := b.delegate.JSONBody(obj)
|
||||
return b, err
|
||||
}
|
||||
|
||||
// DoRequest will do the client.Do
|
||||
func (b *BeegoHTTPRequest) DoRequest() (resp *http.Response, err error) {
|
||||
return b.delegate.DoRequest()
|
||||
}
|
||||
|
||||
// String returns the body string in response.
|
||||
// it calls Response inner.
|
||||
func (b *BeegoHTTPRequest) String() (string, error) {
|
||||
return b.delegate.String()
|
||||
}
|
||||
|
||||
// Bytes returns the body []byte in response.
|
||||
// it calls Response inner.
|
||||
func (b *BeegoHTTPRequest) Bytes() ([]byte, error) {
|
||||
return b.delegate.Bytes()
|
||||
}
|
||||
|
||||
// ToFile saves the body data in response to one file.
|
||||
// it calls Response inner.
|
||||
func (b *BeegoHTTPRequest) ToFile(filename string) error {
|
||||
return b.delegate.ToFile(filename)
|
||||
}
|
||||
|
||||
// ToJSON returns the map that marshals from the body bytes as json in response .
|
||||
// it calls Response inner.
|
||||
func (b *BeegoHTTPRequest) ToJSON(v interface{}) error {
|
||||
return b.delegate.ToJSON(v)
|
||||
}
|
||||
|
||||
// ToXML returns the map that marshals from the body bytes as xml in response .
|
||||
// it calls Response inner.
|
||||
func (b *BeegoHTTPRequest) ToXML(v interface{}) error {
|
||||
return b.delegate.ToXML(v)
|
||||
}
|
||||
|
||||
// ToYAML returns the map that marshals from the body bytes as yaml in response .
|
||||
// it calls Response inner.
|
||||
func (b *BeegoHTTPRequest) ToYAML(v interface{}) error {
|
||||
return b.delegate.ToYAML(v)
|
||||
}
|
||||
|
||||
// Response executes request client gets response mannually.
|
||||
func (b *BeegoHTTPRequest) Response() (*http.Response, error) {
|
||||
return b.delegate.Response()
|
||||
}
|
||||
|
||||
// TimeoutDialer returns functions of connection dialer with timeout settings for http.Transport Dial field.
|
||||
func TimeoutDialer(cTimeout time.Duration, rwTimeout time.Duration) func(net, addr string) (c net.Conn, err error) {
|
||||
return httplib.TimeoutDialer(cTimeout, rwTimeout)
|
||||
}
|
@ -15,7 +15,10 @@
|
||||
package httplib
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
@ -31,6 +34,34 @@ func TestResponse(t *testing.T) {
|
||||
t.Log(resp)
|
||||
}
|
||||
|
||||
func TestDoRequest(t *testing.T) {
|
||||
req := Get("https://goolnk.com/33BD2j")
|
||||
retryAmount := 1
|
||||
req.Retries(1)
|
||||
req.RetryDelay(1400 * time.Millisecond)
|
||||
retryDelay := 1400 * time.Millisecond
|
||||
|
||||
req.SetCheckRedirect(func(redirectReq *http.Request, redirectVia []*http.Request) error {
|
||||
return errors.New("Redirect triggered")
|
||||
})
|
||||
|
||||
startTime := time.Now().UnixNano() / int64(time.Millisecond)
|
||||
|
||||
_, err := req.Response()
|
||||
if err == nil {
|
||||
t.Fatal("Response should have yielded an error")
|
||||
}
|
||||
|
||||
endTime := time.Now().UnixNano() / int64(time.Millisecond)
|
||||
elapsedTime := endTime - startTime
|
||||
delayedTime := int64(retryAmount) * retryDelay.Milliseconds()
|
||||
|
||||
if elapsedTime < delayedTime {
|
||||
t.Errorf("Not enough retries. Took %dms. Delay was meant to take %dms", elapsedTime, delayedTime)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
req := Get("http://httpbin.org/get")
|
||||
b, err := req.Bytes()
|
||||
@ -67,7 +98,7 @@ func TestSimplePost(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
//func TestPostFile(t *testing.T) {
|
||||
// func TestPostFile(t *testing.T) {
|
||||
// v := "smallfish"
|
||||
// req := Post("http://httpbin.org/post")
|
||||
// req.Debug(true)
|
||||
@ -84,7 +115,7 @@ func TestSimplePost(t *testing.T) {
|
||||
// if n == -1 {
|
||||
// t.Fatal(v + " not found in post")
|
||||
// }
|
||||
//}
|
||||
// }
|
||||
|
||||
func TestSimplePut(t *testing.T) {
|
||||
str, err := Put("http://httpbin.org/put").String()
|
||||
@ -161,7 +192,16 @@ func TestWithSetting(t *testing.T) {
|
||||
var setting BeegoHTTPSettings
|
||||
setting.EnableCookie = true
|
||||
setting.UserAgent = v
|
||||
setting.Transport = nil
|
||||
setting.Transport = &http.Transport{
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
DualStack: true,
|
||||
}).DialContext,
|
||||
MaxIdleConns: 50,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
}
|
||||
setting.ReadWriteTimeout = 5 * time.Second
|
||||
SetDefaultSetting(setting)
|
||||
|
||||
@ -195,10 +235,16 @@ func TestToJson(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Log(ip.Origin)
|
||||
|
||||
if n := strings.Count(ip.Origin, "."); n != 3 {
|
||||
ips := strings.Split(ip.Origin, ",")
|
||||
if len(ips) == 0 {
|
||||
t.Fatal("response is not valid ip")
|
||||
}
|
||||
for i := range ips {
|
||||
if net.ParseIP(strings.TrimSpace(ips[i])).To4() == nil {
|
||||
t.Fatal("response is not valid ip")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestToFile(t *testing.T) {
|
||||
@ -215,6 +261,20 @@ func TestToFile(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestToFileDir(t *testing.T) {
|
||||
f := "./files/beego_testfile"
|
||||
req := Get("http://httpbin.org/ip")
|
||||
err := req.ToFile(f)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer os.RemoveAll("./files")
|
||||
b, err := ioutil.ReadFile(f)
|
||||
if n := strings.Index(string(b), "origin"); n == -1 {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeader(t *testing.T) {
|
||||
req := Get("http://httpbin.org/headers")
|
||||
req.Header("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36")
|
@ -12,96 +12,114 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package beego
|
||||
package adapter
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/astaxie/beego/logs"
|
||||
"github.com/astaxie/beego/core/logs"
|
||||
|
||||
webLog "github.com/astaxie/beego/core/logs"
|
||||
)
|
||||
|
||||
// Log levels to control the logging output.
|
||||
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||
const (
|
||||
LevelEmergency = iota
|
||||
LevelAlert
|
||||
LevelCritical
|
||||
LevelError
|
||||
LevelWarning
|
||||
LevelNotice
|
||||
LevelInformational
|
||||
LevelDebug
|
||||
LevelEmergency = webLog.LevelEmergency
|
||||
LevelAlert = webLog.LevelAlert
|
||||
LevelCritical = webLog.LevelCritical
|
||||
LevelError = webLog.LevelError
|
||||
LevelWarning = webLog.LevelWarning
|
||||
LevelNotice = webLog.LevelNotice
|
||||
LevelInformational = webLog.LevelInformational
|
||||
LevelDebug = webLog.LevelDebug
|
||||
)
|
||||
|
||||
// BeeLogger references the used application logger.
|
||||
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||
var BeeLogger = logs.GetBeeLogger()
|
||||
|
||||
// SetLevel sets the global log level used by the simple logger.
|
||||
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||
func SetLevel(l int) {
|
||||
logs.SetLevel(l)
|
||||
}
|
||||
|
||||
// SetLogFuncCall set the CallDepth, default is 3
|
||||
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||
func SetLogFuncCall(b bool) {
|
||||
logs.SetLogFuncCall(b)
|
||||
}
|
||||
|
||||
// SetLogger sets a new logger.
|
||||
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||
func SetLogger(adaptername string, config string) error {
|
||||
return logs.SetLogger(adaptername, config)
|
||||
}
|
||||
|
||||
// Emergency logs a message at emergency level.
|
||||
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||
func Emergency(v ...interface{}) {
|
||||
logs.Emergency(generateFmtStr(len(v)), v...)
|
||||
}
|
||||
|
||||
// Alert logs a message at alert level.
|
||||
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||
func Alert(v ...interface{}) {
|
||||
logs.Alert(generateFmtStr(len(v)), v...)
|
||||
}
|
||||
|
||||
// Critical logs a message at critical level.
|
||||
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||
func Critical(v ...interface{}) {
|
||||
logs.Critical(generateFmtStr(len(v)), v...)
|
||||
}
|
||||
|
||||
// Error logs a message at error level.
|
||||
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||
func Error(v ...interface{}) {
|
||||
logs.Error(generateFmtStr(len(v)), v...)
|
||||
}
|
||||
|
||||
// Warning logs a message at warning level.
|
||||
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||
func Warning(v ...interface{}) {
|
||||
logs.Warning(generateFmtStr(len(v)), v...)
|
||||
}
|
||||
|
||||
// Warn compatibility alias for Warning()
|
||||
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||
func Warn(v ...interface{}) {
|
||||
logs.Warn(generateFmtStr(len(v)), v...)
|
||||
}
|
||||
|
||||
// Notice logs a message at notice level.
|
||||
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||
func Notice(v ...interface{}) {
|
||||
logs.Notice(generateFmtStr(len(v)), v...)
|
||||
}
|
||||
|
||||
// Informational logs a message at info level.
|
||||
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||
func Informational(v ...interface{}) {
|
||||
logs.Informational(generateFmtStr(len(v)), v...)
|
||||
}
|
||||
|
||||
// Info compatibility alias for Warning()
|
||||
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||
func Info(v ...interface{}) {
|
||||
logs.Info(generateFmtStr(len(v)), v...)
|
||||
}
|
||||
|
||||
// Debug logs a message at debug level.
|
||||
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||
func Debug(v ...interface{}) {
|
||||
logs.Debug(generateFmtStr(len(v)), v...)
|
||||
}
|
||||
|
||||
// Trace logs a message at trace level.
|
||||
// compatibility alias for Warning()
|
||||
// Deprecated: use github.com/astaxie/beego/logs instead.
|
||||
func Trace(v ...interface{}) {
|
||||
logs.Trace(generateFmtStr(len(v)), v...)
|
||||
}
|
27
adapter/logs/accesslog.go
Normal file
27
adapter/logs/accesslog.go
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package logs
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/core/logs"
|
||||
)
|
||||
|
||||
// AccessLogRecord struct for holding access log data.
|
||||
type AccessLogRecord logs.AccessLogRecord
|
||||
|
||||
// AccessLog - Format and print access log.
|
||||
func AccessLog(r *AccessLogRecord, format string) {
|
||||
logs.AccessLog((*logs.AccessLogRecord)(r), format)
|
||||
}
|
5
adapter/logs/alils/alils.go
Normal file
5
adapter/logs/alils/alils.go
Normal file
@ -0,0 +1,5 @@
|
||||
package alils
|
||||
|
||||
import (
|
||||
_ "github.com/astaxie/beego/core/logs/alils"
|
||||
)
|
5
adapter/logs/es/es.go
Normal file
5
adapter/logs/es/es.go
Normal file
@ -0,0 +1,5 @@
|
||||
package es
|
||||
|
||||
import (
|
||||
_ "github.com/astaxie/beego/core/logs/es"
|
||||
)
|
347
adapter/logs/log.go
Normal file
347
adapter/logs/log.go
Normal file
@ -0,0 +1,347 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package logs provide a general log interface
|
||||
// Usage:
|
||||
//
|
||||
// import "github.com/astaxie/beego/logs"
|
||||
//
|
||||
// log := NewLogger(10000)
|
||||
// log.SetLogger("console", "")
|
||||
//
|
||||
// > the first params stand for how many channel
|
||||
//
|
||||
// Use it like this:
|
||||
//
|
||||
// log.Trace("trace")
|
||||
// log.Info("info")
|
||||
// log.Warn("warning")
|
||||
// log.Debug("debug")
|
||||
// log.Critical("critical")
|
||||
//
|
||||
// more docs http://beego.me/docs/module/logs.md
|
||||
package logs
|
||||
|
||||
import (
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego/core/logs"
|
||||
)
|
||||
|
||||
// RFC5424 log message levels.
|
||||
const (
|
||||
LevelEmergency = iota
|
||||
LevelAlert
|
||||
LevelCritical
|
||||
LevelError
|
||||
LevelWarning
|
||||
LevelNotice
|
||||
LevelInformational
|
||||
LevelDebug
|
||||
)
|
||||
|
||||
// levelLogLogger is defined to implement log.Logger
|
||||
// the real log level will be LevelEmergency
|
||||
const levelLoggerImpl = -1
|
||||
|
||||
// Name for adapter with beego official support
|
||||
const (
|
||||
AdapterConsole = "console"
|
||||
AdapterFile = "file"
|
||||
AdapterMultiFile = "multifile"
|
||||
AdapterMail = "smtp"
|
||||
AdapterConn = "conn"
|
||||
AdapterEs = "es"
|
||||
AdapterJianLiao = "jianliao"
|
||||
AdapterSlack = "slack"
|
||||
AdapterAliLS = "alils"
|
||||
)
|
||||
|
||||
// Legacy log level constants to ensure backwards compatibility.
|
||||
const (
|
||||
LevelInfo = LevelInformational
|
||||
LevelTrace = LevelDebug
|
||||
LevelWarn = LevelWarning
|
||||
)
|
||||
|
||||
type newLoggerFunc func() Logger
|
||||
|
||||
// Logger defines the behavior of a log provider.
|
||||
type Logger interface {
|
||||
Init(config string) error
|
||||
WriteMsg(when time.Time, msg string, level int) error
|
||||
Destroy()
|
||||
Flush()
|
||||
}
|
||||
|
||||
// Register makes a log provide available by the provided name.
|
||||
// If Register is called twice with the same name or if driver is nil,
|
||||
// it panics.
|
||||
func Register(name string, log newLoggerFunc) {
|
||||
logs.Register(name, func() logs.Logger {
|
||||
return &oldToNewAdapter{
|
||||
old: log(),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// BeeLogger is default logger in beego application.
|
||||
// it can contain several providers and log message into all providers.
|
||||
type BeeLogger logs.BeeLogger
|
||||
|
||||
const defaultAsyncMsgLen = 1e3
|
||||
|
||||
// NewLogger returns a new BeeLogger.
|
||||
// channelLen means the number of messages in chan(used where asynchronous is true).
|
||||
// if the buffering chan is full, logger adapters write to file or other way.
|
||||
func NewLogger(channelLens ...int64) *BeeLogger {
|
||||
return (*BeeLogger)(logs.NewLogger(channelLens...))
|
||||
}
|
||||
|
||||
// Async set the log to asynchronous and start the goroutine
|
||||
func (bl *BeeLogger) Async(msgLen ...int64) *BeeLogger {
|
||||
(*logs.BeeLogger)(bl).Async(msgLen...)
|
||||
return bl
|
||||
}
|
||||
|
||||
// SetLogger provides a given logger adapter into BeeLogger with config string.
|
||||
// config need to be correct JSON as string: {"interval":360}.
|
||||
func (bl *BeeLogger) SetLogger(adapterName string, configs ...string) error {
|
||||
return (*logs.BeeLogger)(bl).SetLogger(adapterName, configs...)
|
||||
}
|
||||
|
||||
// DelLogger remove a logger adapter in BeeLogger.
|
||||
func (bl *BeeLogger) DelLogger(adapterName string) error {
|
||||
return (*logs.BeeLogger)(bl).DelLogger(adapterName)
|
||||
}
|
||||
|
||||
func (bl *BeeLogger) Write(p []byte) (n int, err error) {
|
||||
return (*logs.BeeLogger)(bl).Write(p)
|
||||
}
|
||||
|
||||
// SetLevel Set log message level.
|
||||
// If message level (such as LevelDebug) is higher than logger level (such as LevelWarning),
|
||||
// log providers will not even be sent the message.
|
||||
func (bl *BeeLogger) SetLevel(l int) {
|
||||
(*logs.BeeLogger)(bl).SetLevel(l)
|
||||
}
|
||||
|
||||
// GetLevel Get Current log message level.
|
||||
func (bl *BeeLogger) GetLevel() int {
|
||||
return (*logs.BeeLogger)(bl).GetLevel()
|
||||
}
|
||||
|
||||
// SetLogFuncCallDepth set log funcCallDepth
|
||||
func (bl *BeeLogger) SetLogFuncCallDepth(d int) {
|
||||
(*logs.BeeLogger)(bl).SetLogFuncCallDepth(d)
|
||||
}
|
||||
|
||||
// GetLogFuncCallDepth return log funcCallDepth for wrapper
|
||||
func (bl *BeeLogger) GetLogFuncCallDepth() int {
|
||||
return (*logs.BeeLogger)(bl).GetLogFuncCallDepth()
|
||||
}
|
||||
|
||||
// EnableFuncCallDepth enable log funcCallDepth
|
||||
func (bl *BeeLogger) EnableFuncCallDepth(b bool) {
|
||||
(*logs.BeeLogger)(bl).EnableFuncCallDepth(b)
|
||||
}
|
||||
|
||||
// set prefix
|
||||
func (bl *BeeLogger) SetPrefix(s string) {
|
||||
(*logs.BeeLogger)(bl).SetPrefix(s)
|
||||
}
|
||||
|
||||
// Emergency Log EMERGENCY level message.
|
||||
func (bl *BeeLogger) Emergency(format string, v ...interface{}) {
|
||||
(*logs.BeeLogger)(bl).Emergency(format, v...)
|
||||
}
|
||||
|
||||
// Alert Log ALERT level message.
|
||||
func (bl *BeeLogger) Alert(format string, v ...interface{}) {
|
||||
(*logs.BeeLogger)(bl).Alert(format, v...)
|
||||
}
|
||||
|
||||
// Critical Log CRITICAL level message.
|
||||
func (bl *BeeLogger) Critical(format string, v ...interface{}) {
|
||||
(*logs.BeeLogger)(bl).Critical(format, v...)
|
||||
}
|
||||
|
||||
// Error Log ERROR level message.
|
||||
func (bl *BeeLogger) Error(format string, v ...interface{}) {
|
||||
(*logs.BeeLogger)(bl).Error(format, v...)
|
||||
}
|
||||
|
||||
// Warning Log WARNING level message.
|
||||
func (bl *BeeLogger) Warning(format string, v ...interface{}) {
|
||||
(*logs.BeeLogger)(bl).Warning(format, v...)
|
||||
}
|
||||
|
||||
// Notice Log NOTICE level message.
|
||||
func (bl *BeeLogger) Notice(format string, v ...interface{}) {
|
||||
(*logs.BeeLogger)(bl).Notice(format, v...)
|
||||
}
|
||||
|
||||
// Informational Log INFORMATIONAL level message.
|
||||
func (bl *BeeLogger) Informational(format string, v ...interface{}) {
|
||||
(*logs.BeeLogger)(bl).Informational(format, v...)
|
||||
}
|
||||
|
||||
// Debug Log DEBUG level message.
|
||||
func (bl *BeeLogger) Debug(format string, v ...interface{}) {
|
||||
(*logs.BeeLogger)(bl).Debug(format, v...)
|
||||
}
|
||||
|
||||
// Warn Log WARN level message.
|
||||
// compatibility alias for Warning()
|
||||
func (bl *BeeLogger) Warn(format string, v ...interface{}) {
|
||||
(*logs.BeeLogger)(bl).Warn(format, v...)
|
||||
}
|
||||
|
||||
// Info Log INFO level message.
|
||||
// compatibility alias for Informational()
|
||||
func (bl *BeeLogger) Info(format string, v ...interface{}) {
|
||||
(*logs.BeeLogger)(bl).Info(format, v...)
|
||||
}
|
||||
|
||||
// Trace Log TRACE level message.
|
||||
// compatibility alias for Debug()
|
||||
func (bl *BeeLogger) Trace(format string, v ...interface{}) {
|
||||
(*logs.BeeLogger)(bl).Trace(format, v...)
|
||||
}
|
||||
|
||||
// Flush flush all chan data.
|
||||
func (bl *BeeLogger) Flush() {
|
||||
(*logs.BeeLogger)(bl).Flush()
|
||||
}
|
||||
|
||||
// Close close logger, flush all chan data and destroy all adapters in BeeLogger.
|
||||
func (bl *BeeLogger) Close() {
|
||||
(*logs.BeeLogger)(bl).Close()
|
||||
}
|
||||
|
||||
// Reset close all outputs, and set bl.outputs to nil
|
||||
func (bl *BeeLogger) Reset() {
|
||||
(*logs.BeeLogger)(bl).Reset()
|
||||
}
|
||||
|
||||
// GetBeeLogger returns the default BeeLogger
|
||||
func GetBeeLogger() *BeeLogger {
|
||||
return (*BeeLogger)(logs.GetBeeLogger())
|
||||
}
|
||||
|
||||
// GetLogger returns the default BeeLogger
|
||||
func GetLogger(prefixes ...string) *log.Logger {
|
||||
return logs.GetLogger(prefixes...)
|
||||
}
|
||||
|
||||
// Reset will remove all the adapter
|
||||
func Reset() {
|
||||
logs.Reset()
|
||||
}
|
||||
|
||||
// Async set the beelogger with Async mode and hold msglen messages
|
||||
func Async(msgLen ...int64) *BeeLogger {
|
||||
return (*BeeLogger)(logs.Async(msgLen...))
|
||||
}
|
||||
|
||||
// SetLevel sets the global log level used by the simple logger.
|
||||
func SetLevel(l int) {
|
||||
logs.SetLevel(l)
|
||||
}
|
||||
|
||||
// SetPrefix sets the prefix
|
||||
func SetPrefix(s string) {
|
||||
logs.SetPrefix(s)
|
||||
}
|
||||
|
||||
// EnableFuncCallDepth enable log funcCallDepth
|
||||
func EnableFuncCallDepth(b bool) {
|
||||
logs.EnableFuncCallDepth(b)
|
||||
}
|
||||
|
||||
// SetLogFuncCall set the CallDepth, default is 4
|
||||
func SetLogFuncCall(b bool) {
|
||||
logs.SetLogFuncCall(b)
|
||||
}
|
||||
|
||||
// SetLogFuncCallDepth set log funcCallDepth
|
||||
func SetLogFuncCallDepth(d int) {
|
||||
logs.SetLogFuncCallDepth(d)
|
||||
}
|
||||
|
||||
// SetLogger sets a new logger.
|
||||
func SetLogger(adapter string, config ...string) error {
|
||||
return logs.SetLogger(adapter, config...)
|
||||
}
|
||||
|
||||
// Emergency logs a message at emergency level.
|
||||
func Emergency(f interface{}, v ...interface{}) {
|
||||
logs.Emergency(f, v...)
|
||||
}
|
||||
|
||||
// Alert logs a message at alert level.
|
||||
func Alert(f interface{}, v ...interface{}) {
|
||||
logs.Alert(f, v...)
|
||||
}
|
||||
|
||||
// Critical logs a message at critical level.
|
||||
func Critical(f interface{}, v ...interface{}) {
|
||||
logs.Critical(f, v...)
|
||||
}
|
||||
|
||||
// Error logs a message at error level.
|
||||
func Error(f interface{}, v ...interface{}) {
|
||||
logs.Error(f, v...)
|
||||
}
|
||||
|
||||
// Warning logs a message at warning level.
|
||||
func Warning(f interface{}, v ...interface{}) {
|
||||
logs.Warning(f, v...)
|
||||
}
|
||||
|
||||
// Warn compatibility alias for Warning()
|
||||
func Warn(f interface{}, v ...interface{}) {
|
||||
logs.Warn(f, v...)
|
||||
}
|
||||
|
||||
// Notice logs a message at notice level.
|
||||
func Notice(f interface{}, v ...interface{}) {
|
||||
logs.Notice(f, v...)
|
||||
}
|
||||
|
||||
// Informational logs a message at info level.
|
||||
func Informational(f interface{}, v ...interface{}) {
|
||||
logs.Informational(f, v...)
|
||||
}
|
||||
|
||||
// Info compatibility alias for Warning()
|
||||
func Info(f interface{}, v ...interface{}) {
|
||||
logs.Info(f, v...)
|
||||
}
|
||||
|
||||
// Debug logs a message at debug level.
|
||||
func Debug(f interface{}, v ...interface{}) {
|
||||
logs.Debug(f, v...)
|
||||
}
|
||||
|
||||
// Trace logs a message at trace level.
|
||||
// compatibility alias for Warning()
|
||||
func Trace(f interface{}, v ...interface{}) {
|
||||
logs.Trace(f, v...)
|
||||
}
|
||||
|
||||
func init() {
|
||||
SetLogFuncCallDepth(4)
|
||||
}
|
69
adapter/logs/log_adapter.go
Normal file
69
adapter/logs/log_adapter.go
Normal file
@ -0,0 +1,69 @@
|
||||
// Copyright 2020
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package logs
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego/core/logs"
|
||||
)
|
||||
|
||||
type oldToNewAdapter struct {
|
||||
old Logger
|
||||
}
|
||||
|
||||
func (o *oldToNewAdapter) Init(config string) error {
|
||||
return o.old.Init(config)
|
||||
}
|
||||
|
||||
func (o *oldToNewAdapter) WriteMsg(lm *logs.LogMsg) error {
|
||||
return o.old.WriteMsg(lm.When, lm.OldStyleFormat(), lm.Level)
|
||||
}
|
||||
|
||||
func (o *oldToNewAdapter) Destroy() {
|
||||
o.old.Destroy()
|
||||
}
|
||||
|
||||
func (o *oldToNewAdapter) Flush() {
|
||||
o.old.Flush()
|
||||
}
|
||||
|
||||
func (o *oldToNewAdapter) SetFormatter(f logs.LogFormatter) {
|
||||
panic("unsupported operation, you should not invoke this method")
|
||||
}
|
||||
|
||||
type newToOldAdapter struct {
|
||||
n logs.Logger
|
||||
}
|
||||
|
||||
func (n *newToOldAdapter) Init(config string) error {
|
||||
return n.n.Init(config)
|
||||
}
|
||||
|
||||
func (n *newToOldAdapter) WriteMsg(when time.Time, msg string, level int) error {
|
||||
return n.n.WriteMsg(&logs.LogMsg{
|
||||
When: when,
|
||||
Msg: msg,
|
||||
Level: level,
|
||||
})
|
||||
}
|
||||
|
||||
func (n *newToOldAdapter) Destroy() {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (n *newToOldAdapter) Flush() {
|
||||
panic("implement me")
|
||||
}
|
@ -12,25 +12,27 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package orm
|
||||
package logs
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"github.com/astaxie/beego/core/logs"
|
||||
)
|
||||
|
||||
func TestCamelString(t *testing.T) {
|
||||
snake := []string{"pic_url", "hello_world_", "hello__World", "_HelLO_Word", "pic_url_1", "pic_url__1"}
|
||||
camel := []string{"PicUrl", "HelloWorld", "HelloWorld", "HelLOWord", "PicUrl1", "PicUrl1"}
|
||||
|
||||
answer := make(map[string]string)
|
||||
for i, v := range snake {
|
||||
answer[v] = camel[i]
|
||||
}
|
||||
|
||||
for _, v := range snake {
|
||||
res := camelString(v)
|
||||
if res != answer[v] {
|
||||
t.Error("Unit Test Fail:", v, res, answer[v])
|
||||
}
|
||||
}
|
||||
// ColorByStatus return color by http code
|
||||
// 2xx return Green
|
||||
// 3xx return White
|
||||
// 4xx return Yellow
|
||||
// 5xx return Red
|
||||
func ColorByStatus(code int) string {
|
||||
return logs.ColorByStatus(code)
|
||||
}
|
||||
|
||||
// ColorByMethod return color by http code
|
||||
func ColorByMethod(method string) string {
|
||||
return logs.ColorByMethod(method)
|
||||
}
|
||||
|
||||
// ResetColor return reset color
|
||||
func ResetColor() string {
|
||||
return logs.ResetColor()
|
||||
}
|
24
adapter/logs/logger_test.go
Normal file
24
adapter/logs/logger_test.go
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright 2016 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package logs
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBeeLogger_Info(t *testing.T) {
|
||||
log := NewLogger(1000)
|
||||
log.SetLogger("file", `{"net":"tcp","addr":":7020"}`)
|
||||
}
|
100
adapter/metric/prometheus.go
Normal file
100
adapter/metric/prometheus.go
Normal file
@ -0,0 +1,100 @@
|
||||
// Copyright 2020 astaxie
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package metric
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/astaxie/beego/core/logs"
|
||||
"github.com/astaxie/beego/server/web"
|
||||
)
|
||||
|
||||
func PrometheusMiddleWare(next http.Handler) http.Handler {
|
||||
summaryVec := prometheus.NewSummaryVec(prometheus.SummaryOpts{
|
||||
Name: "beego",
|
||||
Subsystem: "http_request",
|
||||
ConstLabels: map[string]string{
|
||||
"server": web.BConfig.ServerName,
|
||||
"env": web.BConfig.RunMode,
|
||||
"appname": web.BConfig.AppName,
|
||||
},
|
||||
Help: "The statics info for http request",
|
||||
}, []string{"pattern", "method", "status", "duration"})
|
||||
|
||||
prometheus.MustRegister(summaryVec)
|
||||
|
||||
registerBuildInfo()
|
||||
|
||||
return http.HandlerFunc(func(writer http.ResponseWriter, q *http.Request) {
|
||||
start := time.Now()
|
||||
next.ServeHTTP(writer, q)
|
||||
end := time.Now()
|
||||
go report(end.Sub(start), writer, q, summaryVec)
|
||||
})
|
||||
}
|
||||
|
||||
func registerBuildInfo() {
|
||||
buildInfo := prometheus.NewGaugeVec(prometheus.GaugeOpts{
|
||||
Name: "beego",
|
||||
Subsystem: "build_info",
|
||||
Help: "The building information",
|
||||
ConstLabels: map[string]string{
|
||||
"appname": web.BConfig.AppName,
|
||||
"build_version": beego.BuildVersion,
|
||||
"build_revision": beego.BuildGitRevision,
|
||||
"build_status": beego.BuildStatus,
|
||||
"build_tag": beego.BuildTag,
|
||||
"build_time": strings.Replace(beego.BuildTime, "--", " ", 1),
|
||||
"go_version": beego.GoVersion,
|
||||
"git_branch": beego.GitBranch,
|
||||
"start_time": time.Now().Format("2006-01-02 15:04:05"),
|
||||
},
|
||||
}, []string{})
|
||||
|
||||
prometheus.MustRegister(buildInfo)
|
||||
buildInfo.WithLabelValues().Set(1)
|
||||
}
|
||||
|
||||
func report(dur time.Duration, writer http.ResponseWriter, q *http.Request, vec *prometheus.SummaryVec) {
|
||||
ctrl := web.BeeApp.Handlers
|
||||
ctx := ctrl.GetContext()
|
||||
ctx.Reset(writer, q)
|
||||
defer ctrl.GiveBackContext(ctx)
|
||||
|
||||
// We cannot read the status code from q.Response.StatusCode
|
||||
// since the http server does not set q.Response. So q.Response is nil
|
||||
// Thus, we use reflection to read the status from writer whose concrete type is http.response
|
||||
responseVal := reflect.ValueOf(writer).Elem()
|
||||
field := responseVal.FieldByName("status")
|
||||
status := -1
|
||||
if field.IsValid() && field.Kind() == reflect.Int {
|
||||
status = int(field.Int())
|
||||
}
|
||||
ptn := "UNKNOWN"
|
||||
if rt, found := ctrl.FindRouter(ctx); found {
|
||||
ptn = rt.GetPattern()
|
||||
} else {
|
||||
logs.Warn("we can not find the router info for this request, so request will be recorded as UNKNOWN: " + q.URL.String())
|
||||
}
|
||||
ms := dur / time.Millisecond
|
||||
vec.WithLabelValues(ptn, q.Method, strconv.Itoa(status), strconv.Itoa(int(ms))).Observe(float64(ms))
|
||||
}
|
42
adapter/metric/prometheus_test.go
Normal file
42
adapter/metric/prometheus_test.go
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2020 astaxie
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package metric
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
"github.com/astaxie/beego/adapter/context"
|
||||
)
|
||||
|
||||
func TestPrometheusMiddleWare(t *testing.T) {
|
||||
middleware := PrometheusMiddleWare(http.HandlerFunc(func(http.ResponseWriter, *http.Request) {}))
|
||||
writer := &context.Response{}
|
||||
request := &http.Request{
|
||||
URL: &url.URL{
|
||||
Host: "localhost",
|
||||
RawPath: "/a/b/c",
|
||||
},
|
||||
Method: "POST",
|
||||
}
|
||||
vec := prometheus.NewSummaryVec(prometheus.SummaryOpts{}, []string{"pattern", "method", "status", "duration"})
|
||||
|
||||
report(time.Second, writer, request, vec)
|
||||
middleware.ServeHTTP(writer, request)
|
||||
}
|
198
adapter/migration/ddl.go
Normal file
198
adapter/migration/ddl.go
Normal file
@ -0,0 +1,198 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package migration
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/client/orm/migration"
|
||||
)
|
||||
|
||||
// Index struct defines the structure of Index Columns
|
||||
type Index migration.Index
|
||||
|
||||
// Unique struct defines a single unique key combination
|
||||
type Unique migration.Unique
|
||||
|
||||
// Column struct defines a single column of a table
|
||||
type Column migration.Column
|
||||
|
||||
// Foreign struct defines a single foreign relationship
|
||||
type Foreign migration.Foreign
|
||||
|
||||
// RenameColumn struct allows renaming of columns
|
||||
type RenameColumn migration.RenameColumn
|
||||
|
||||
// CreateTable creates the table on system
|
||||
func (m *Migration) CreateTable(tablename, engine, charset string, p ...func()) {
|
||||
(*migration.Migration)(m).CreateTable(tablename, engine, charset, p...)
|
||||
}
|
||||
|
||||
// AlterTable set the ModifyType to alter
|
||||
func (m *Migration) AlterTable(tablename string) {
|
||||
(*migration.Migration)(m).AlterTable(tablename)
|
||||
}
|
||||
|
||||
// NewCol creates a new standard column and attaches it to m struct
|
||||
func (m *Migration) NewCol(name string) *Column {
|
||||
return (*Column)((*migration.Migration)(m).NewCol(name))
|
||||
}
|
||||
|
||||
// PriCol creates a new primary column and attaches it to m struct
|
||||
func (m *Migration) PriCol(name string) *Column {
|
||||
return (*Column)((*migration.Migration)(m).PriCol(name))
|
||||
}
|
||||
|
||||
// UniCol creates / appends columns to specified unique key and attaches it to m struct
|
||||
func (m *Migration) UniCol(uni, name string) *Column {
|
||||
return (*Column)((*migration.Migration)(m).UniCol(uni, name))
|
||||
}
|
||||
|
||||
// ForeignCol creates a new foreign column and returns the instance of column
|
||||
func (m *Migration) ForeignCol(colname, foreigncol, foreigntable string) (foreign *Foreign) {
|
||||
return (*Foreign)((*migration.Migration)(m).ForeignCol(colname, foreigncol, foreigntable))
|
||||
}
|
||||
|
||||
// SetOnDelete sets the on delete of foreign
|
||||
func (foreign *Foreign) SetOnDelete(del string) *Foreign {
|
||||
(*migration.Foreign)(foreign).SetOnDelete(del)
|
||||
return foreign
|
||||
}
|
||||
|
||||
// SetOnUpdate sets the on update of foreign
|
||||
func (foreign *Foreign) SetOnUpdate(update string) *Foreign {
|
||||
(*migration.Foreign)(foreign).SetOnUpdate(update)
|
||||
return foreign
|
||||
}
|
||||
|
||||
// Remove marks the columns to be removed.
|
||||
// it allows reverse m to create the column.
|
||||
func (c *Column) Remove() {
|
||||
(*migration.Column)(c).Remove()
|
||||
}
|
||||
|
||||
// SetAuto enables auto_increment of column (can be used once)
|
||||
func (c *Column) SetAuto(inc bool) *Column {
|
||||
(*migration.Column)(c).SetAuto(inc)
|
||||
return c
|
||||
}
|
||||
|
||||
// SetNullable sets the column to be null
|
||||
func (c *Column) SetNullable(null bool) *Column {
|
||||
(*migration.Column)(c).SetNullable(null)
|
||||
return c
|
||||
}
|
||||
|
||||
// SetDefault sets the default value, prepend with "DEFAULT "
|
||||
func (c *Column) SetDefault(def string) *Column {
|
||||
(*migration.Column)(c).SetDefault(def)
|
||||
return c
|
||||
}
|
||||
|
||||
// SetUnsigned sets the column to be unsigned int
|
||||
func (c *Column) SetUnsigned(unsign bool) *Column {
|
||||
(*migration.Column)(c).SetUnsigned(unsign)
|
||||
return c
|
||||
}
|
||||
|
||||
// SetDataType sets the dataType of the column
|
||||
func (c *Column) SetDataType(dataType string) *Column {
|
||||
(*migration.Column)(c).SetDataType(dataType)
|
||||
return c
|
||||
}
|
||||
|
||||
// SetOldNullable allows reverting to previous nullable on reverse ms
|
||||
func (c *RenameColumn) SetOldNullable(null bool) *RenameColumn {
|
||||
(*migration.RenameColumn)(c).SetOldNullable(null)
|
||||
return c
|
||||
}
|
||||
|
||||
// SetOldDefault allows reverting to previous default on reverse ms
|
||||
func (c *RenameColumn) SetOldDefault(def string) *RenameColumn {
|
||||
(*migration.RenameColumn)(c).SetOldDefault(def)
|
||||
return c
|
||||
}
|
||||
|
||||
// SetOldUnsigned allows reverting to previous unsgined on reverse ms
|
||||
func (c *RenameColumn) SetOldUnsigned(unsign bool) *RenameColumn {
|
||||
(*migration.RenameColumn)(c).SetOldUnsigned(unsign)
|
||||
return c
|
||||
}
|
||||
|
||||
// SetOldDataType allows reverting to previous datatype on reverse ms
|
||||
func (c *RenameColumn) SetOldDataType(dataType string) *RenameColumn {
|
||||
(*migration.RenameColumn)(c).SetOldDataType(dataType)
|
||||
return c
|
||||
}
|
||||
|
||||
// SetPrimary adds the columns to the primary key (can only be used any number of times in only one m)
|
||||
func (c *Column) SetPrimary(m *Migration) *Column {
|
||||
(*migration.Column)(c).SetPrimary((*migration.Migration)(m))
|
||||
return c
|
||||
}
|
||||
|
||||
// AddColumnsToUnique adds the columns to Unique Struct
|
||||
func (unique *Unique) AddColumnsToUnique(columns ...*Column) *Unique {
|
||||
cls := toNewColumnsArray(columns)
|
||||
(*migration.Unique)(unique).AddColumnsToUnique(cls...)
|
||||
return unique
|
||||
}
|
||||
|
||||
// AddColumns adds columns to m struct
|
||||
func (m *Migration) AddColumns(columns ...*Column) *Migration {
|
||||
cls := toNewColumnsArray(columns)
|
||||
(*migration.Migration)(m).AddColumns(cls...)
|
||||
return m
|
||||
}
|
||||
|
||||
func toNewColumnsArray(columns []*Column) []*migration.Column {
|
||||
cls := make([]*migration.Column, 0, len(columns))
|
||||
for _, c := range columns {
|
||||
cls = append(cls, (*migration.Column)(c))
|
||||
}
|
||||
return cls
|
||||
}
|
||||
|
||||
// AddPrimary adds the column to primary in m struct
|
||||
func (m *Migration) AddPrimary(primary *Column) *Migration {
|
||||
(*migration.Migration)(m).AddPrimary((*migration.Column)(primary))
|
||||
return m
|
||||
}
|
||||
|
||||
// AddUnique adds the column to unique in m struct
|
||||
func (m *Migration) AddUnique(unique *Unique) *Migration {
|
||||
(*migration.Migration)(m).AddUnique((*migration.Unique)(unique))
|
||||
return m
|
||||
}
|
||||
|
||||
// AddForeign adds the column to foreign in m struct
|
||||
func (m *Migration) AddForeign(foreign *Foreign) *Migration {
|
||||
(*migration.Migration)(m).AddForeign((*migration.Foreign)(foreign))
|
||||
return m
|
||||
}
|
||||
|
||||
// AddIndex adds the column to index in m struct
|
||||
func (m *Migration) AddIndex(index *Index) *Migration {
|
||||
(*migration.Migration)(m).AddIndex((*migration.Index)(index))
|
||||
return m
|
||||
}
|
||||
|
||||
// RenameColumn allows renaming of columns
|
||||
func (m *Migration) RenameColumn(from, to string) *RenameColumn {
|
||||
return (*RenameColumn)((*migration.Migration)(m).RenameColumn(from, to))
|
||||
}
|
||||
|
||||
// GetSQL returns the generated sql depending on ModifyType
|
||||
func (m *Migration) GetSQL() (sql string) {
|
||||
return (*migration.Migration)(m).GetSQL()
|
||||
}
|
32
adapter/migration/doc.go
Normal file
32
adapter/migration/doc.go
Normal file
@ -0,0 +1,32 @@
|
||||
// Package migration enables you to generate migrations back and forth. It generates both migrations.
|
||||
//
|
||||
// //Creates a table
|
||||
// m.CreateTable("tablename","InnoDB","utf8");
|
||||
//
|
||||
// //Alter a table
|
||||
// m.AlterTable("tablename")
|
||||
//
|
||||
// Standard Column Methods
|
||||
// * SetDataType
|
||||
// * SetNullable
|
||||
// * SetDefault
|
||||
// * SetUnsigned (use only on integer types unless produces error)
|
||||
//
|
||||
// //Sets a primary column, multiple calls allowed, standard column methods available
|
||||
// m.PriCol("id").SetAuto(true).SetNullable(false).SetDataType("INT(10)").SetUnsigned(true)
|
||||
//
|
||||
// //UniCol Can be used multiple times, allows standard Column methods. Use same "index" string to add to same index
|
||||
// m.UniCol("index","column")
|
||||
//
|
||||
// //Standard Column Initialisation, can call .Remove() after NewCol("") on alter to remove
|
||||
// m.NewCol("name").SetDataType("VARCHAR(255) COLLATE utf8_unicode_ci").SetNullable(false)
|
||||
// m.NewCol("value").SetDataType("DOUBLE(8,2)").SetNullable(false)
|
||||
//
|
||||
// //Rename Columns , only use with Alter table, doesn't works with Create, prefix standard column methods with "Old" to
|
||||
// //create a true reversible migration eg: SetOldDataType("DOUBLE(12,3)")
|
||||
// m.RenameColumn("from","to")...
|
||||
//
|
||||
// //Foreign Columns, single columns are only supported, SetOnDelete & SetOnUpdate are available, call appropriately.
|
||||
// //Supports standard column methods, automatic reverse.
|
||||
// m.ForeignCol("local_col","foreign_col","foreign_table")
|
||||
package migration
|
111
adapter/migration/migration.go
Normal file
111
adapter/migration/migration.go
Normal file
@ -0,0 +1,111 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package migration is used for migration
|
||||
//
|
||||
// The table structure is as follow:
|
||||
//
|
||||
// CREATE TABLE `migrations` (
|
||||
// `id_migration` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'surrogate key',
|
||||
// `name` varchar(255) DEFAULT NULL COMMENT 'migration name, unique',
|
||||
// `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'date migrated or rolled back',
|
||||
// `statements` longtext COMMENT 'SQL statements for this migration',
|
||||
// `rollback_statements` longtext,
|
||||
// `status` enum('update','rollback') DEFAULT NULL COMMENT 'update indicates it is a normal migration while rollback means this migration is rolled back',
|
||||
// PRIMARY KEY (`id_migration`)
|
||||
// ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
package migration
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/client/orm/migration"
|
||||
)
|
||||
|
||||
// const the data format for the bee generate migration datatype
|
||||
const (
|
||||
DateFormat = "20060102_150405"
|
||||
DBDateFormat = "2006-01-02 15:04:05"
|
||||
)
|
||||
|
||||
// Migrationer is an interface for all Migration struct
|
||||
type Migrationer interface {
|
||||
Up()
|
||||
Down()
|
||||
Reset()
|
||||
Exec(name, status string) error
|
||||
GetCreated() int64
|
||||
}
|
||||
|
||||
// Migration defines the migrations by either SQL or DDL
|
||||
type Migration migration.Migration
|
||||
|
||||
// Up implement in the Inheritance struct for upgrade
|
||||
func (m *Migration) Up() {
|
||||
(*migration.Migration)(m).Up()
|
||||
}
|
||||
|
||||
// Down implement in the Inheritance struct for down
|
||||
func (m *Migration) Down() {
|
||||
(*migration.Migration)(m).Down()
|
||||
}
|
||||
|
||||
// Migrate adds the SQL to the execution list
|
||||
func (m *Migration) Migrate(migrationType string) {
|
||||
(*migration.Migration)(m).Migrate(migrationType)
|
||||
}
|
||||
|
||||
// SQL add sql want to execute
|
||||
func (m *Migration) SQL(sql string) {
|
||||
(*migration.Migration)(m).SQL(sql)
|
||||
}
|
||||
|
||||
// Reset the sqls
|
||||
func (m *Migration) Reset() {
|
||||
(*migration.Migration)(m).Reset()
|
||||
}
|
||||
|
||||
// Exec execute the sql already add in the sql
|
||||
func (m *Migration) Exec(name, status string) error {
|
||||
return (*migration.Migration)(m).Exec(name, status)
|
||||
}
|
||||
|
||||
// GetCreated get the unixtime from the Created
|
||||
func (m *Migration) GetCreated() int64 {
|
||||
return (*migration.Migration)(m).GetCreated()
|
||||
}
|
||||
|
||||
// Register register the Migration in the map
|
||||
func Register(name string, m Migrationer) error {
|
||||
return migration.Register(name, m)
|
||||
}
|
||||
|
||||
// Upgrade upgrade the migration from lasttime
|
||||
func Upgrade(lasttime int64) error {
|
||||
return migration.Upgrade(lasttime)
|
||||
}
|
||||
|
||||
// Rollback rollback the migration by the name
|
||||
func Rollback(name string) error {
|
||||
return migration.Rollback(name)
|
||||
}
|
||||
|
||||
// Reset reset all migration
|
||||
// run all migration's down function
|
||||
func Reset() error {
|
||||
return migration.Reset()
|
||||
}
|
||||
|
||||
// Refresh first Reset, then Upgrade
|
||||
func Refresh() error {
|
||||
return migration.Refresh()
|
||||
}
|
378
adapter/namespace.go
Normal file
378
adapter/namespace.go
Normal file
@ -0,0 +1,378 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package adapter
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
adtContext "github.com/astaxie/beego/adapter/context"
|
||||
"github.com/astaxie/beego/server/web/context"
|
||||
|
||||
"github.com/astaxie/beego/server/web"
|
||||
)
|
||||
|
||||
type namespaceCond func(*adtContext.Context) bool
|
||||
|
||||
// LinkNamespace used as link action
|
||||
type LinkNamespace func(*Namespace)
|
||||
|
||||
// Namespace is store all the info
|
||||
type Namespace web.Namespace
|
||||
|
||||
// NewNamespace get new Namespace
|
||||
func NewNamespace(prefix string, params ...LinkNamespace) *Namespace {
|
||||
nps := oldToNewLinkNs(params)
|
||||
return (*Namespace)(web.NewNamespace(prefix, nps...))
|
||||
}
|
||||
|
||||
func oldToNewLinkNs(params []LinkNamespace) []web.LinkNamespace {
|
||||
nps := make([]web.LinkNamespace, 0, len(params))
|
||||
for _, p := range params {
|
||||
nps = append(nps, func(namespace *web.Namespace) {
|
||||
p((*Namespace)(namespace))
|
||||
})
|
||||
}
|
||||
return nps
|
||||
}
|
||||
|
||||
// Cond set condition function
|
||||
// if cond return true can run this namespace, else can't
|
||||
// usage:
|
||||
// ns.Cond(func (ctx *context.Context) bool{
|
||||
// if ctx.Input.Domain() == "api.beego.me" {
|
||||
// return true
|
||||
// }
|
||||
// return false
|
||||
// })
|
||||
// Cond as the first filter
|
||||
func (n *Namespace) Cond(cond namespaceCond) *Namespace {
|
||||
(*web.Namespace)(n).Cond(func(context *context.Context) bool {
|
||||
return cond((*adtContext.Context)(context))
|
||||
})
|
||||
return n
|
||||
}
|
||||
|
||||
// Filter add filter in the Namespace
|
||||
// action has before & after
|
||||
// FilterFunc
|
||||
// usage:
|
||||
// Filter("before", func (ctx *context.Context){
|
||||
// _, ok := ctx.Input.Session("uid").(int)
|
||||
// if !ok && ctx.Request.RequestURI != "/login" {
|
||||
// ctx.Redirect(302, "/login")
|
||||
// }
|
||||
// })
|
||||
func (n *Namespace) Filter(action string, filter ...FilterFunc) *Namespace {
|
||||
nfs := oldToNewFilter(filter)
|
||||
(*web.Namespace)(n).Filter(action, nfs...)
|
||||
return n
|
||||
}
|
||||
|
||||
func oldToNewFilter(filter []FilterFunc) []web.FilterFunc {
|
||||
nfs := make([]web.FilterFunc, 0, len(filter))
|
||||
for _, f := range filter {
|
||||
nfs = append(nfs, func(ctx *context.Context) {
|
||||
f((*adtContext.Context)(ctx))
|
||||
})
|
||||
}
|
||||
return nfs
|
||||
}
|
||||
|
||||
// Router same as beego.Rourer
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Router
|
||||
func (n *Namespace) Router(rootpath string, c ControllerInterface, mappingMethods ...string) *Namespace {
|
||||
(*web.Namespace)(n).Router(rootpath, c, mappingMethods...)
|
||||
return n
|
||||
}
|
||||
|
||||
// AutoRouter same as beego.AutoRouter
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#AutoRouter
|
||||
func (n *Namespace) AutoRouter(c ControllerInterface) *Namespace {
|
||||
(*web.Namespace)(n).AutoRouter(c)
|
||||
return n
|
||||
}
|
||||
|
||||
// AutoPrefix same as beego.AutoPrefix
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#AutoPrefix
|
||||
func (n *Namespace) AutoPrefix(prefix string, c ControllerInterface) *Namespace {
|
||||
(*web.Namespace)(n).AutoPrefix(prefix, c)
|
||||
return n
|
||||
}
|
||||
|
||||
// Get same as beego.Get
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Get
|
||||
func (n *Namespace) Get(rootpath string, f FilterFunc) *Namespace {
|
||||
(*web.Namespace)(n).Get(rootpath, func(ctx *context.Context) {
|
||||
f((*adtContext.Context)(ctx))
|
||||
})
|
||||
return n
|
||||
}
|
||||
|
||||
// Post same as beego.Post
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Post
|
||||
func (n *Namespace) Post(rootpath string, f FilterFunc) *Namespace {
|
||||
(*web.Namespace)(n).Post(rootpath, func(ctx *context.Context) {
|
||||
f((*adtContext.Context)(ctx))
|
||||
})
|
||||
return n
|
||||
}
|
||||
|
||||
// Delete same as beego.Delete
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Delete
|
||||
func (n *Namespace) Delete(rootpath string, f FilterFunc) *Namespace {
|
||||
(*web.Namespace)(n).Delete(rootpath, func(ctx *context.Context) {
|
||||
f((*adtContext.Context)(ctx))
|
||||
})
|
||||
return n
|
||||
}
|
||||
|
||||
// Put same as beego.Put
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Put
|
||||
func (n *Namespace) Put(rootpath string, f FilterFunc) *Namespace {
|
||||
(*web.Namespace)(n).Put(rootpath, func(ctx *context.Context) {
|
||||
f((*adtContext.Context)(ctx))
|
||||
})
|
||||
return n
|
||||
}
|
||||
|
||||
// Head same as beego.Head
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Head
|
||||
func (n *Namespace) Head(rootpath string, f FilterFunc) *Namespace {
|
||||
(*web.Namespace)(n).Head(rootpath, func(ctx *context.Context) {
|
||||
f((*adtContext.Context)(ctx))
|
||||
})
|
||||
return n
|
||||
}
|
||||
|
||||
// Options same as beego.Options
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Options
|
||||
func (n *Namespace) Options(rootpath string, f FilterFunc) *Namespace {
|
||||
(*web.Namespace)(n).Options(rootpath, func(ctx *context.Context) {
|
||||
f((*adtContext.Context)(ctx))
|
||||
})
|
||||
return n
|
||||
}
|
||||
|
||||
// Patch same as beego.Patch
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Patch
|
||||
func (n *Namespace) Patch(rootpath string, f FilterFunc) *Namespace {
|
||||
(*web.Namespace)(n).Patch(rootpath, func(ctx *context.Context) {
|
||||
f((*adtContext.Context)(ctx))
|
||||
})
|
||||
return n
|
||||
}
|
||||
|
||||
// Any same as beego.Any
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Any
|
||||
func (n *Namespace) Any(rootpath string, f FilterFunc) *Namespace {
|
||||
(*web.Namespace)(n).Any(rootpath, func(ctx *context.Context) {
|
||||
f((*adtContext.Context)(ctx))
|
||||
})
|
||||
return n
|
||||
}
|
||||
|
||||
// Handler same as beego.Handler
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Handler
|
||||
func (n *Namespace) Handler(rootpath string, h http.Handler) *Namespace {
|
||||
(*web.Namespace)(n).Handler(rootpath, h)
|
||||
return n
|
||||
}
|
||||
|
||||
// Include add include class
|
||||
// refer: https://godoc.org/github.com/astaxie/beego#Include
|
||||
func (n *Namespace) Include(cList ...ControllerInterface) *Namespace {
|
||||
nL := oldToNewCtrlIntfs(cList)
|
||||
(*web.Namespace)(n).Include(nL...)
|
||||
return n
|
||||
}
|
||||
|
||||
// Namespace add nest Namespace
|
||||
// usage:
|
||||
// ns := beego.NewNamespace(“/v1”).
|
||||
// Namespace(
|
||||
// beego.NewNamespace("/shop").
|
||||
// Get("/:id", func(ctx *context.Context) {
|
||||
// ctx.Output.Body([]byte("shopinfo"))
|
||||
// }),
|
||||
// beego.NewNamespace("/order").
|
||||
// Get("/:id", func(ctx *context.Context) {
|
||||
// ctx.Output.Body([]byte("orderinfo"))
|
||||
// }),
|
||||
// beego.NewNamespace("/crm").
|
||||
// Get("/:id", func(ctx *context.Context) {
|
||||
// ctx.Output.Body([]byte("crminfo"))
|
||||
// }),
|
||||
// )
|
||||
func (n *Namespace) Namespace(ns ...*Namespace) *Namespace {
|
||||
nns := oldToNewNs(ns)
|
||||
(*web.Namespace)(n).Namespace(nns...)
|
||||
return n
|
||||
}
|
||||
|
||||
func oldToNewNs(ns []*Namespace) []*web.Namespace {
|
||||
nns := make([]*web.Namespace, 0, len(ns))
|
||||
for _, n := range ns {
|
||||
nns = append(nns, (*web.Namespace)(n))
|
||||
}
|
||||
return nns
|
||||
}
|
||||
|
||||
// AddNamespace register Namespace into beego.Handler
|
||||
// support multi Namespace
|
||||
func AddNamespace(nl ...*Namespace) {
|
||||
nnl := oldToNewNs(nl)
|
||||
web.AddNamespace(nnl...)
|
||||
}
|
||||
|
||||
// NSCond is Namespace Condition
|
||||
func NSCond(cond namespaceCond) LinkNamespace {
|
||||
return func(namespace *Namespace) {
|
||||
web.NSCond(func(b *context.Context) bool {
|
||||
return cond((*adtContext.Context)(b))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// NSBefore Namespace BeforeRouter filter
|
||||
func NSBefore(filterList ...FilterFunc) LinkNamespace {
|
||||
return func(namespace *Namespace) {
|
||||
nfs := oldToNewFilter(filterList)
|
||||
web.NSBefore(nfs...)
|
||||
}
|
||||
}
|
||||
|
||||
// NSAfter add Namespace FinishRouter filter
|
||||
func NSAfter(filterList ...FilterFunc) LinkNamespace {
|
||||
return func(namespace *Namespace) {
|
||||
nfs := oldToNewFilter(filterList)
|
||||
web.NSAfter(nfs...)
|
||||
}
|
||||
}
|
||||
|
||||
// NSInclude Namespace Include ControllerInterface
|
||||
func NSInclude(cList ...ControllerInterface) LinkNamespace {
|
||||
return func(namespace *Namespace) {
|
||||
nfs := oldToNewCtrlIntfs(cList)
|
||||
web.NSInclude(nfs...)
|
||||
}
|
||||
}
|
||||
|
||||
// NSRouter call Namespace Router
|
||||
func NSRouter(rootpath string, c ControllerInterface, mappingMethods ...string) LinkNamespace {
|
||||
return func(namespace *Namespace) {
|
||||
web.Router(rootpath, c, mappingMethods...)
|
||||
}
|
||||
}
|
||||
|
||||
// NSGet call Namespace Get
|
||||
func NSGet(rootpath string, f FilterFunc) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
web.NSGet(rootpath, func(ctx *context.Context) {
|
||||
f((*adtContext.Context)(ctx))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// NSPost call Namespace Post
|
||||
func NSPost(rootpath string, f FilterFunc) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
web.Post(rootpath, func(ctx *context.Context) {
|
||||
f((*adtContext.Context)(ctx))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// NSHead call Namespace Head
|
||||
func NSHead(rootpath string, f FilterFunc) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
web.NSHead(rootpath, func(ctx *context.Context) {
|
||||
f((*adtContext.Context)(ctx))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// NSPut call Namespace Put
|
||||
func NSPut(rootpath string, f FilterFunc) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
web.NSPut(rootpath, func(ctx *context.Context) {
|
||||
f((*adtContext.Context)(ctx))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// NSDelete call Namespace Delete
|
||||
func NSDelete(rootpath string, f FilterFunc) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
web.NSDelete(rootpath, func(ctx *context.Context) {
|
||||
f((*adtContext.Context)(ctx))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// NSAny call Namespace Any
|
||||
func NSAny(rootpath string, f FilterFunc) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
web.NSAny(rootpath, func(ctx *context.Context) {
|
||||
f((*adtContext.Context)(ctx))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// NSOptions call Namespace Options
|
||||
func NSOptions(rootpath string, f FilterFunc) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
web.NSOptions(rootpath, func(ctx *context.Context) {
|
||||
f((*adtContext.Context)(ctx))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// NSPatch call Namespace Patch
|
||||
func NSPatch(rootpath string, f FilterFunc) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
web.NSPatch(rootpath, func(ctx *context.Context) {
|
||||
f((*adtContext.Context)(ctx))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// NSAutoRouter call Namespace AutoRouter
|
||||
func NSAutoRouter(c ControllerInterface) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
web.NSAutoRouter(c)
|
||||
}
|
||||
}
|
||||
|
||||
// NSAutoPrefix call Namespace AutoPrefix
|
||||
func NSAutoPrefix(prefix string, c ControllerInterface) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
web.NSAutoPrefix(prefix, c)
|
||||
}
|
||||
}
|
||||
|
||||
// NSNamespace add sub Namespace
|
||||
func NSNamespace(prefix string, params ...LinkNamespace) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
nps := oldToNewLinkNs(params)
|
||||
web.NSNamespace(prefix, nps...)
|
||||
}
|
||||
}
|
||||
|
||||
// NSHandler add handler
|
||||
func NSHandler(rootpath string, h http.Handler) LinkNamespace {
|
||||
return func(ns *Namespace) {
|
||||
web.NSHandler(rootpath, h)
|
||||
}
|
||||
}
|
28
adapter/orm/cmd.go
Normal file
28
adapter/orm/cmd.go
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package orm
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/client/orm"
|
||||
)
|
||||
|
||||
// RunCommand listen for orm command and then run it if command arguments passed.
|
||||
func RunCommand() {
|
||||
orm.RunCommand()
|
||||
}
|
||||
|
||||
func RunSyncdb(name string, force bool, verbose bool) error {
|
||||
return orm.RunSyncdb(name, force, verbose)
|
||||
}
|
@ -12,17 +12,13 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build !windows
|
||||
package orm
|
||||
|
||||
package logs
|
||||
import (
|
||||
"github.com/astaxie/beego/client/orm"
|
||||
)
|
||||
|
||||
import "io"
|
||||
|
||||
type ansiColorWriter struct {
|
||||
w io.Writer
|
||||
mode outputMode
|
||||
}
|
||||
|
||||
func (cw *ansiColorWriter) Write(p []byte) (int, error) {
|
||||
return cw.w.Write(p)
|
||||
}
|
||||
var (
|
||||
// ErrMissPK missing pk error
|
||||
ErrMissPK = orm.ErrMissPK
|
||||
)
|
121
adapter/orm/db_alias.go
Normal file
121
adapter/orm/db_alias.go
Normal file
@ -0,0 +1,121 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package orm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego/client/orm"
|
||||
)
|
||||
|
||||
// DriverType database driver constant int.
|
||||
type DriverType orm.DriverType
|
||||
|
||||
// Enum the Database driver
|
||||
const (
|
||||
DRMySQL = DriverType(orm.DRMySQL)
|
||||
DRSqlite = DriverType(orm.DRSqlite) // sqlite
|
||||
DROracle = DriverType(orm.DROracle) // oracle
|
||||
DRPostgres = DriverType(orm.DRPostgres) // pgsql
|
||||
DRTiDB = DriverType(orm.DRTiDB) // TiDB
|
||||
)
|
||||
|
||||
type DB orm.DB
|
||||
|
||||
func (d *DB) Begin() (*sql.Tx, error) {
|
||||
return (*orm.DB)(d).Begin()
|
||||
}
|
||||
|
||||
func (d *DB) BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error) {
|
||||
return (*orm.DB)(d).BeginTx(ctx, opts)
|
||||
}
|
||||
|
||||
func (d *DB) Prepare(query string) (*sql.Stmt, error) {
|
||||
return (*orm.DB)(d).Prepare(query)
|
||||
}
|
||||
|
||||
func (d *DB) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) {
|
||||
return (*orm.DB)(d).PrepareContext(ctx, query)
|
||||
}
|
||||
|
||||
func (d *DB) Exec(query string, args ...interface{}) (sql.Result, error) {
|
||||
return (*orm.DB)(d).Exec(query, args...)
|
||||
}
|
||||
|
||||
func (d *DB) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
|
||||
return (*orm.DB)(d).ExecContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (d *DB) Query(query string, args ...interface{}) (*sql.Rows, error) {
|
||||
return (*orm.DB)(d).Query(query, args...)
|
||||
}
|
||||
|
||||
func (d *DB) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) {
|
||||
return (*orm.DB)(d).QueryContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
func (d *DB) QueryRow(query string, args ...interface{}) *sql.Row {
|
||||
return (*orm.DB)(d).QueryRow(query, args)
|
||||
}
|
||||
|
||||
func (d *DB) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row {
|
||||
return (*orm.DB)(d).QueryRowContext(ctx, query, args...)
|
||||
}
|
||||
|
||||
// AddAliasWthDB add a aliasName for the drivename
|
||||
func AddAliasWthDB(aliasName, driverName string, db *sql.DB) error {
|
||||
return orm.AddAliasWthDB(aliasName, driverName, db)
|
||||
}
|
||||
|
||||
// RegisterDataBase Setting the database connect params. Use the database driver self dataSource args.
|
||||
func RegisterDataBase(aliasName, driverName, dataSource string, params ...int) error {
|
||||
opts := make([]orm.DBOption, 0, 2)
|
||||
if len(params) > 0 {
|
||||
opts = append(opts, orm.MaxIdleConnections(params[0]))
|
||||
}
|
||||
|
||||
if len(params) > 1 {
|
||||
opts = append(opts, orm.MaxOpenConnections(params[1]))
|
||||
}
|
||||
return orm.RegisterDataBase(aliasName, driverName, dataSource, opts...)
|
||||
}
|
||||
|
||||
// RegisterDriver Register a database driver use specify driver name, this can be definition the driver is which database type.
|
||||
func RegisterDriver(driverName string, typ DriverType) error {
|
||||
return orm.RegisterDriver(driverName, orm.DriverType(typ))
|
||||
}
|
||||
|
||||
// SetDataBaseTZ Change the database default used timezone
|
||||
func SetDataBaseTZ(aliasName string, tz *time.Location) error {
|
||||
return orm.SetDataBaseTZ(aliasName, tz)
|
||||
}
|
||||
|
||||
// SetMaxIdleConns Change the max idle conns for *sql.DB, use specify database alias name
|
||||
func SetMaxIdleConns(aliasName string, maxIdleConns int) {
|
||||
orm.SetMaxIdleConns(aliasName, maxIdleConns)
|
||||
}
|
||||
|
||||
// SetMaxOpenConns Change the max open conns for *sql.DB, use specify database alias name
|
||||
func SetMaxOpenConns(aliasName string, maxOpenConns int) {
|
||||
orm.SetMaxOpenConns(aliasName, maxOpenConns)
|
||||
}
|
||||
|
||||
// GetDB Get *sql.DB from registered database by db alias name.
|
||||
// Use "default" as alias name if you not set.
|
||||
func GetDB(aliasNames ...string) (*sql.DB, error) {
|
||||
return orm.GetDB(aliasNames...)
|
||||
}
|
25
adapter/orm/models.go
Normal file
25
adapter/orm/models.go
Normal file
@ -0,0 +1,25 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package orm
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/client/orm"
|
||||
)
|
||||
|
||||
// ResetModelCache Clean model cache. Then you can re-RegisterModel.
|
||||
// Common use this api for test case.
|
||||
func ResetModelCache() {
|
||||
orm.ResetModelCache()
|
||||
}
|
40
adapter/orm/models_boot.go
Normal file
40
adapter/orm/models_boot.go
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package orm
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/client/orm"
|
||||
)
|
||||
|
||||
// RegisterModel register models
|
||||
func RegisterModel(models ...interface{}) {
|
||||
orm.RegisterModel(models...)
|
||||
}
|
||||
|
||||
// RegisterModelWithPrefix register models with a prefix
|
||||
func RegisterModelWithPrefix(prefix string, models ...interface{}) {
|
||||
orm.RegisterModelWithPrefix(prefix, models)
|
||||
}
|
||||
|
||||
// RegisterModelWithSuffix register models with a suffix
|
||||
func RegisterModelWithSuffix(suffix string, models ...interface{}) {
|
||||
orm.RegisterModelWithSuffix(suffix, models...)
|
||||
}
|
||||
|
||||
// BootStrap bootstrap models.
|
||||
// make all model parsed and can not add more models
|
||||
func BootStrap() {
|
||||
orm.BootStrap()
|
||||
}
|
625
adapter/orm/models_fields.go
Normal file
625
adapter/orm/models_fields.go
Normal file
@ -0,0 +1,625 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package orm
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego/client/orm"
|
||||
)
|
||||
|
||||
// Define the Type enum
|
||||
const (
|
||||
TypeBooleanField = orm.TypeBooleanField
|
||||
TypeVarCharField = orm.TypeVarCharField
|
||||
TypeCharField = orm.TypeCharField
|
||||
TypeTextField = orm.TypeTextField
|
||||
TypeTimeField = orm.TypeTimeField
|
||||
TypeDateField = orm.TypeDateField
|
||||
TypeDateTimeField = orm.TypeDateTimeField
|
||||
TypeBitField = orm.TypeBitField
|
||||
TypeSmallIntegerField = orm.TypeSmallIntegerField
|
||||
TypeIntegerField = orm.TypeIntegerField
|
||||
TypeBigIntegerField = orm.TypeBigIntegerField
|
||||
TypePositiveBitField = orm.TypePositiveBitField
|
||||
TypePositiveSmallIntegerField = orm.TypePositiveSmallIntegerField
|
||||
TypePositiveIntegerField = orm.TypePositiveIntegerField
|
||||
TypePositiveBigIntegerField = orm.TypePositiveBigIntegerField
|
||||
TypeFloatField = orm.TypeFloatField
|
||||
TypeDecimalField = orm.TypeDecimalField
|
||||
TypeJSONField = orm.TypeJSONField
|
||||
TypeJsonbField = orm.TypeJsonbField
|
||||
RelForeignKey = orm.RelForeignKey
|
||||
RelOneToOne = orm.RelOneToOne
|
||||
RelManyToMany = orm.RelManyToMany
|
||||
RelReverseOne = orm.RelReverseOne
|
||||
RelReverseMany = orm.RelReverseMany
|
||||
)
|
||||
|
||||
// Define some logic enum
|
||||
const (
|
||||
IsIntegerField = orm.IsIntegerField
|
||||
IsPositiveIntegerField = orm.IsPositiveIntegerField
|
||||
IsRelField = orm.IsRelField
|
||||
IsFieldType = orm.IsFieldType
|
||||
)
|
||||
|
||||
// BooleanField A true/false field.
|
||||
type BooleanField orm.BooleanField
|
||||
|
||||
// Value return the BooleanField
|
||||
func (e BooleanField) Value() bool {
|
||||
return orm.BooleanField(e).Value()
|
||||
}
|
||||
|
||||
// Set will set the BooleanField
|
||||
func (e *BooleanField) Set(d bool) {
|
||||
(*orm.BooleanField)(e).Set(d)
|
||||
}
|
||||
|
||||
// String format the Bool to string
|
||||
func (e *BooleanField) String() string {
|
||||
return (*orm.BooleanField)(e).String()
|
||||
}
|
||||
|
||||
// FieldType return BooleanField the type
|
||||
func (e *BooleanField) FieldType() int {
|
||||
return (*orm.BooleanField)(e).FieldType()
|
||||
}
|
||||
|
||||
// SetRaw set the interface to bool
|
||||
func (e *BooleanField) SetRaw(value interface{}) error {
|
||||
return (*orm.BooleanField)(e).SetRaw(value)
|
||||
}
|
||||
|
||||
// RawValue return the current value
|
||||
func (e *BooleanField) RawValue() interface{} {
|
||||
return (*orm.BooleanField)(e).RawValue()
|
||||
}
|
||||
|
||||
// verify the BooleanField implement the Fielder interface
|
||||
var _ Fielder = new(BooleanField)
|
||||
|
||||
// CharField A string field
|
||||
// required values tag: size
|
||||
// The size is enforced at the database level and in models’s validation.
|
||||
// eg: `orm:"size(120)"`
|
||||
type CharField orm.CharField
|
||||
|
||||
// Value return the CharField's Value
|
||||
func (e CharField) Value() string {
|
||||
return orm.CharField(e).Value()
|
||||
}
|
||||
|
||||
// Set CharField value
|
||||
func (e *CharField) Set(d string) {
|
||||
(*orm.CharField)(e).Set(d)
|
||||
}
|
||||
|
||||
// String return the CharField
|
||||
func (e *CharField) String() string {
|
||||
return (*orm.CharField)(e).String()
|
||||
}
|
||||
|
||||
// FieldType return the enum type
|
||||
func (e *CharField) FieldType() int {
|
||||
return (*orm.CharField)(e).FieldType()
|
||||
}
|
||||
|
||||
// SetRaw set the interface to string
|
||||
func (e *CharField) SetRaw(value interface{}) error {
|
||||
return (*orm.CharField)(e).SetRaw(value)
|
||||
}
|
||||
|
||||
// RawValue return the CharField value
|
||||
func (e *CharField) RawValue() interface{} {
|
||||
return (*orm.CharField)(e).RawValue()
|
||||
}
|
||||
|
||||
// verify CharField implement Fielder
|
||||
var _ Fielder = new(CharField)
|
||||
|
||||
// TimeField A time, represented in go by a time.Time instance.
|
||||
// only time values like 10:00:00
|
||||
// Has a few extra, optional attr tag:
|
||||
//
|
||||
// auto_now:
|
||||
// Automatically set the field to now every time the object is saved. Useful for “last-modified” timestamps.
|
||||
// Note that the current date is always used; it’s not just a default value that you can override.
|
||||
//
|
||||
// auto_now_add:
|
||||
// Automatically set the field to now when the object is first created. Useful for creation of timestamps.
|
||||
// Note that the current date is always used; it’s not just a default value that you can override.
|
||||
//
|
||||
// eg: `orm:"auto_now"` or `orm:"auto_now_add"`
|
||||
type TimeField orm.TimeField
|
||||
|
||||
// Value return the time.Time
|
||||
func (e TimeField) Value() time.Time {
|
||||
return orm.TimeField(e).Value()
|
||||
}
|
||||
|
||||
// Set set the TimeField's value
|
||||
func (e *TimeField) Set(d time.Time) {
|
||||
(*orm.TimeField)(e).Set(d)
|
||||
}
|
||||
|
||||
// String convert time to string
|
||||
func (e *TimeField) String() string {
|
||||
return (*orm.TimeField)(e).String()
|
||||
}
|
||||
|
||||
// FieldType return enum type Date
|
||||
func (e *TimeField) FieldType() int {
|
||||
return (*orm.TimeField)(e).FieldType()
|
||||
}
|
||||
|
||||
// SetRaw convert the interface to time.Time. Allow string and time.Time
|
||||
func (e *TimeField) SetRaw(value interface{}) error {
|
||||
return (*orm.TimeField)(e).SetRaw(value)
|
||||
}
|
||||
|
||||
// RawValue return time value
|
||||
func (e *TimeField) RawValue() interface{} {
|
||||
return (*orm.TimeField)(e).RawValue()
|
||||
}
|
||||
|
||||
var _ Fielder = new(TimeField)
|
||||
|
||||
// DateField A date, represented in go by a time.Time instance.
|
||||
// only date values like 2006-01-02
|
||||
// Has a few extra, optional attr tag:
|
||||
//
|
||||
// auto_now:
|
||||
// Automatically set the field to now every time the object is saved. Useful for “last-modified” timestamps.
|
||||
// Note that the current date is always used; it’s not just a default value that you can override.
|
||||
//
|
||||
// auto_now_add:
|
||||
// Automatically set the field to now when the object is first created. Useful for creation of timestamps.
|
||||
// Note that the current date is always used; it’s not just a default value that you can override.
|
||||
//
|
||||
// eg: `orm:"auto_now"` or `orm:"auto_now_add"`
|
||||
type DateField orm.DateField
|
||||
|
||||
// Value return the time.Time
|
||||
func (e DateField) Value() time.Time {
|
||||
return orm.DateField(e).Value()
|
||||
}
|
||||
|
||||
// Set set the DateField's value
|
||||
func (e *DateField) Set(d time.Time) {
|
||||
(*orm.DateField)(e).Set(d)
|
||||
}
|
||||
|
||||
// String convert datetime to string
|
||||
func (e *DateField) String() string {
|
||||
return (*orm.DateField)(e).String()
|
||||
}
|
||||
|
||||
// FieldType return enum type Date
|
||||
func (e *DateField) FieldType() int {
|
||||
return (*orm.DateField)(e).FieldType()
|
||||
}
|
||||
|
||||
// SetRaw convert the interface to time.Time. Allow string and time.Time
|
||||
func (e *DateField) SetRaw(value interface{}) error {
|
||||
return (*orm.DateField)(e).SetRaw(value)
|
||||
}
|
||||
|
||||
// RawValue return Date value
|
||||
func (e *DateField) RawValue() interface{} {
|
||||
return (*orm.DateField)(e).RawValue()
|
||||
}
|
||||
|
||||
// verify DateField implement fielder interface
|
||||
var _ Fielder = new(DateField)
|
||||
|
||||
// DateTimeField A date, represented in go by a time.Time instance.
|
||||
// datetime values like 2006-01-02 15:04:05
|
||||
// Takes the same extra arguments as DateField.
|
||||
type DateTimeField orm.DateTimeField
|
||||
|
||||
// Value return the datetime value
|
||||
func (e DateTimeField) Value() time.Time {
|
||||
return orm.DateTimeField(e).Value()
|
||||
}
|
||||
|
||||
// Set set the time.Time to datetime
|
||||
func (e *DateTimeField) Set(d time.Time) {
|
||||
(*orm.DateTimeField)(e).Set(d)
|
||||
}
|
||||
|
||||
// String return the time's String
|
||||
func (e *DateTimeField) String() string {
|
||||
return (*orm.DateTimeField)(e).String()
|
||||
}
|
||||
|
||||
// FieldType return the enum TypeDateTimeField
|
||||
func (e *DateTimeField) FieldType() int {
|
||||
return (*orm.DateTimeField)(e).FieldType()
|
||||
}
|
||||
|
||||
// SetRaw convert the string or time.Time to DateTimeField
|
||||
func (e *DateTimeField) SetRaw(value interface{}) error {
|
||||
return (*orm.DateTimeField)(e).SetRaw(value)
|
||||
}
|
||||
|
||||
// RawValue return the datetime value
|
||||
func (e *DateTimeField) RawValue() interface{} {
|
||||
return (*orm.DateTimeField)(e).RawValue()
|
||||
}
|
||||
|
||||
// verify datetime implement fielder
|
||||
var _ Fielder = new(DateTimeField)
|
||||
|
||||
// FloatField A floating-point number represented in go by a float32 value.
|
||||
type FloatField orm.FloatField
|
||||
|
||||
// Value return the FloatField value
|
||||
func (e FloatField) Value() float64 {
|
||||
return orm.FloatField(e).Value()
|
||||
}
|
||||
|
||||
// Set the Float64
|
||||
func (e *FloatField) Set(d float64) {
|
||||
(*orm.FloatField)(e).Set(d)
|
||||
}
|
||||
|
||||
// String return the string
|
||||
func (e *FloatField) String() string {
|
||||
return (*orm.FloatField)(e).String()
|
||||
}
|
||||
|
||||
// FieldType return the enum type
|
||||
func (e *FloatField) FieldType() int {
|
||||
return (*orm.FloatField)(e).FieldType()
|
||||
}
|
||||
|
||||
// SetRaw converter interface Float64 float32 or string to FloatField
|
||||
func (e *FloatField) SetRaw(value interface{}) error {
|
||||
return (*orm.FloatField)(e).SetRaw(value)
|
||||
}
|
||||
|
||||
// RawValue return the FloatField value
|
||||
func (e *FloatField) RawValue() interface{} {
|
||||
return (*orm.FloatField)(e).RawValue()
|
||||
}
|
||||
|
||||
// verify FloatField implement Fielder
|
||||
var _ Fielder = new(FloatField)
|
||||
|
||||
// SmallIntegerField -32768 to 32767
|
||||
type SmallIntegerField orm.SmallIntegerField
|
||||
|
||||
// Value return int16 value
|
||||
func (e SmallIntegerField) Value() int16 {
|
||||
return orm.SmallIntegerField(e).Value()
|
||||
}
|
||||
|
||||
// Set the SmallIntegerField value
|
||||
func (e *SmallIntegerField) Set(d int16) {
|
||||
(*orm.SmallIntegerField)(e).Set(d)
|
||||
}
|
||||
|
||||
// String convert smallint to string
|
||||
func (e *SmallIntegerField) String() string {
|
||||
return (*orm.SmallIntegerField)(e).String()
|
||||
}
|
||||
|
||||
// FieldType return enum type SmallIntegerField
|
||||
func (e *SmallIntegerField) FieldType() int {
|
||||
return (*orm.SmallIntegerField)(e).FieldType()
|
||||
}
|
||||
|
||||
// SetRaw convert interface int16/string to int16
|
||||
func (e *SmallIntegerField) SetRaw(value interface{}) error {
|
||||
return (*orm.SmallIntegerField)(e).SetRaw(value)
|
||||
}
|
||||
|
||||
// RawValue return smallint value
|
||||
func (e *SmallIntegerField) RawValue() interface{} {
|
||||
return (*orm.SmallIntegerField)(e).RawValue()
|
||||
}
|
||||
|
||||
// verify SmallIntegerField implement Fielder
|
||||
var _ Fielder = new(SmallIntegerField)
|
||||
|
||||
// IntegerField -2147483648 to 2147483647
|
||||
type IntegerField orm.IntegerField
|
||||
|
||||
// Value return the int32
|
||||
func (e IntegerField) Value() int32 {
|
||||
return orm.IntegerField(e).Value()
|
||||
}
|
||||
|
||||
// Set IntegerField value
|
||||
func (e *IntegerField) Set(d int32) {
|
||||
(*orm.IntegerField)(e).Set(d)
|
||||
}
|
||||
|
||||
// String convert Int32 to string
|
||||
func (e *IntegerField) String() string {
|
||||
return (*orm.IntegerField)(e).String()
|
||||
}
|
||||
|
||||
// FieldType return the enum type
|
||||
func (e *IntegerField) FieldType() int {
|
||||
return (*orm.IntegerField)(e).FieldType()
|
||||
}
|
||||
|
||||
// SetRaw convert interface int32/string to int32
|
||||
func (e *IntegerField) SetRaw(value interface{}) error {
|
||||
return (*orm.IntegerField)(e).SetRaw(value)
|
||||
}
|
||||
|
||||
// RawValue return IntegerField value
|
||||
func (e *IntegerField) RawValue() interface{} {
|
||||
return (*orm.IntegerField)(e).RawValue()
|
||||
}
|
||||
|
||||
// verify IntegerField implement Fielder
|
||||
var _ Fielder = new(IntegerField)
|
||||
|
||||
// BigIntegerField -9223372036854775808 to 9223372036854775807.
|
||||
type BigIntegerField orm.BigIntegerField
|
||||
|
||||
// Value return int64
|
||||
func (e BigIntegerField) Value() int64 {
|
||||
return orm.BigIntegerField(e).Value()
|
||||
}
|
||||
|
||||
// Set the BigIntegerField value
|
||||
func (e *BigIntegerField) Set(d int64) {
|
||||
(*orm.BigIntegerField)(e).Set(d)
|
||||
}
|
||||
|
||||
// String convert BigIntegerField to string
|
||||
func (e *BigIntegerField) String() string {
|
||||
return (*orm.BigIntegerField)(e).String()
|
||||
}
|
||||
|
||||
// FieldType return enum type
|
||||
func (e *BigIntegerField) FieldType() int {
|
||||
return (*orm.BigIntegerField)(e).FieldType()
|
||||
}
|
||||
|
||||
// SetRaw convert interface int64/string to int64
|
||||
func (e *BigIntegerField) SetRaw(value interface{}) error {
|
||||
return (*orm.BigIntegerField)(e).SetRaw(value)
|
||||
}
|
||||
|
||||
// RawValue return BigIntegerField value
|
||||
func (e *BigIntegerField) RawValue() interface{} {
|
||||
return (*orm.BigIntegerField)(e).RawValue()
|
||||
}
|
||||
|
||||
// verify BigIntegerField implement Fielder
|
||||
var _ Fielder = new(BigIntegerField)
|
||||
|
||||
// PositiveSmallIntegerField 0 to 65535
|
||||
type PositiveSmallIntegerField orm.PositiveSmallIntegerField
|
||||
|
||||
// Value return uint16
|
||||
func (e PositiveSmallIntegerField) Value() uint16 {
|
||||
return orm.PositiveSmallIntegerField(e).Value()
|
||||
}
|
||||
|
||||
// Set PositiveSmallIntegerField value
|
||||
func (e *PositiveSmallIntegerField) Set(d uint16) {
|
||||
(*orm.PositiveSmallIntegerField)(e).Set(d)
|
||||
}
|
||||
|
||||
// String convert uint16 to string
|
||||
func (e *PositiveSmallIntegerField) String() string {
|
||||
return (*orm.PositiveSmallIntegerField)(e).String()
|
||||
}
|
||||
|
||||
// FieldType return enum type
|
||||
func (e *PositiveSmallIntegerField) FieldType() int {
|
||||
return (*orm.PositiveSmallIntegerField)(e).FieldType()
|
||||
}
|
||||
|
||||
// SetRaw convert Interface uint16/string to uint16
|
||||
func (e *PositiveSmallIntegerField) SetRaw(value interface{}) error {
|
||||
return (*orm.PositiveSmallIntegerField)(e).SetRaw(value)
|
||||
}
|
||||
|
||||
// RawValue returns PositiveSmallIntegerField value
|
||||
func (e *PositiveSmallIntegerField) RawValue() interface{} {
|
||||
return (*orm.PositiveSmallIntegerField)(e).RawValue()
|
||||
}
|
||||
|
||||
// verify PositiveSmallIntegerField implement Fielder
|
||||
var _ Fielder = new(PositiveSmallIntegerField)
|
||||
|
||||
// PositiveIntegerField 0 to 4294967295
|
||||
type PositiveIntegerField orm.PositiveIntegerField
|
||||
|
||||
// Value return PositiveIntegerField value. Uint32
|
||||
func (e PositiveIntegerField) Value() uint32 {
|
||||
return orm.PositiveIntegerField(e).Value()
|
||||
}
|
||||
|
||||
// Set the PositiveIntegerField value
|
||||
func (e *PositiveIntegerField) Set(d uint32) {
|
||||
(*orm.PositiveIntegerField)(e).Set(d)
|
||||
}
|
||||
|
||||
// String convert PositiveIntegerField to string
|
||||
func (e *PositiveIntegerField) String() string {
|
||||
return (*orm.PositiveIntegerField)(e).String()
|
||||
}
|
||||
|
||||
// FieldType return enum type
|
||||
func (e *PositiveIntegerField) FieldType() int {
|
||||
return (*orm.PositiveIntegerField)(e).FieldType()
|
||||
}
|
||||
|
||||
// SetRaw convert interface uint32/string to Uint32
|
||||
func (e *PositiveIntegerField) SetRaw(value interface{}) error {
|
||||
return (*orm.PositiveIntegerField)(e).SetRaw(value)
|
||||
}
|
||||
|
||||
// RawValue return the PositiveIntegerField Value
|
||||
func (e *PositiveIntegerField) RawValue() interface{} {
|
||||
return (*orm.PositiveIntegerField)(e).RawValue()
|
||||
}
|
||||
|
||||
// verify PositiveIntegerField implement Fielder
|
||||
var _ Fielder = new(PositiveIntegerField)
|
||||
|
||||
// PositiveBigIntegerField 0 to 18446744073709551615
|
||||
type PositiveBigIntegerField orm.PositiveBigIntegerField
|
||||
|
||||
// Value return uint64
|
||||
func (e PositiveBigIntegerField) Value() uint64 {
|
||||
return orm.PositiveBigIntegerField(e).Value()
|
||||
}
|
||||
|
||||
// Set PositiveBigIntegerField value
|
||||
func (e *PositiveBigIntegerField) Set(d uint64) {
|
||||
(*orm.PositiveBigIntegerField)(e).Set(d)
|
||||
}
|
||||
|
||||
// String convert PositiveBigIntegerField to string
|
||||
func (e *PositiveBigIntegerField) String() string {
|
||||
return (*orm.PositiveBigIntegerField)(e).String()
|
||||
}
|
||||
|
||||
// FieldType return enum type
|
||||
func (e *PositiveBigIntegerField) FieldType() int {
|
||||
return (*orm.PositiveBigIntegerField)(e).FieldType()
|
||||
}
|
||||
|
||||
// SetRaw convert interface uint64/string to Uint64
|
||||
func (e *PositiveBigIntegerField) SetRaw(value interface{}) error {
|
||||
return (*orm.PositiveBigIntegerField)(e).SetRaw(value)
|
||||
}
|
||||
|
||||
// RawValue return PositiveBigIntegerField value
|
||||
func (e *PositiveBigIntegerField) RawValue() interface{} {
|
||||
return (*orm.PositiveBigIntegerField)(e).RawValue()
|
||||
}
|
||||
|
||||
// verify PositiveBigIntegerField implement Fielder
|
||||
var _ Fielder = new(PositiveBigIntegerField)
|
||||
|
||||
// TextField A large text field.
|
||||
type TextField orm.TextField
|
||||
|
||||
// Value return TextField value
|
||||
func (e TextField) Value() string {
|
||||
return orm.TextField(e).Value()
|
||||
}
|
||||
|
||||
// Set the TextField value
|
||||
func (e *TextField) Set(d string) {
|
||||
(*orm.TextField)(e).Set(d)
|
||||
}
|
||||
|
||||
// String convert TextField to string
|
||||
func (e *TextField) String() string {
|
||||
return (*orm.TextField)(e).String()
|
||||
}
|
||||
|
||||
// FieldType return enum type
|
||||
func (e *TextField) FieldType() int {
|
||||
return (*orm.TextField)(e).FieldType()
|
||||
}
|
||||
|
||||
// SetRaw convert interface string to string
|
||||
func (e *TextField) SetRaw(value interface{}) error {
|
||||
return (*orm.TextField)(e).SetRaw(value)
|
||||
}
|
||||
|
||||
// RawValue return TextField value
|
||||
func (e *TextField) RawValue() interface{} {
|
||||
return (*orm.TextField)(e).RawValue()
|
||||
}
|
||||
|
||||
// verify TextField implement Fielder
|
||||
var _ Fielder = new(TextField)
|
||||
|
||||
// JSONField postgres json field.
|
||||
type JSONField orm.JSONField
|
||||
|
||||
// Value return JSONField value
|
||||
func (j JSONField) Value() string {
|
||||
return orm.JSONField(j).Value()
|
||||
}
|
||||
|
||||
// Set the JSONField value
|
||||
func (j *JSONField) Set(d string) {
|
||||
(*orm.JSONField)(j).Set(d)
|
||||
}
|
||||
|
||||
// String convert JSONField to string
|
||||
func (j *JSONField) String() string {
|
||||
return (*orm.JSONField)(j).String()
|
||||
}
|
||||
|
||||
// FieldType return enum type
|
||||
func (j *JSONField) FieldType() int {
|
||||
return (*orm.JSONField)(j).FieldType()
|
||||
}
|
||||
|
||||
// SetRaw convert interface string to string
|
||||
func (j *JSONField) SetRaw(value interface{}) error {
|
||||
return (*orm.JSONField)(j).SetRaw(value)
|
||||
}
|
||||
|
||||
// RawValue return JSONField value
|
||||
func (j *JSONField) RawValue() interface{} {
|
||||
return (*orm.JSONField)(j).RawValue()
|
||||
}
|
||||
|
||||
// verify JSONField implement Fielder
|
||||
var _ Fielder = new(JSONField)
|
||||
|
||||
// JsonbField postgres json field.
|
||||
type JsonbField orm.JsonbField
|
||||
|
||||
// Value return JsonbField value
|
||||
func (j JsonbField) Value() string {
|
||||
return orm.JsonbField(j).Value()
|
||||
}
|
||||
|
||||
// Set the JsonbField value
|
||||
func (j *JsonbField) Set(d string) {
|
||||
(*orm.JsonbField)(j).Set(d)
|
||||
}
|
||||
|
||||
// String convert JsonbField to string
|
||||
func (j *JsonbField) String() string {
|
||||
return (*orm.JsonbField)(j).String()
|
||||
}
|
||||
|
||||
// FieldType return enum type
|
||||
func (j *JsonbField) FieldType() int {
|
||||
return (*orm.JsonbField)(j).FieldType()
|
||||
}
|
||||
|
||||
// SetRaw convert interface string to string
|
||||
func (j *JsonbField) SetRaw(value interface{}) error {
|
||||
return (*orm.JsonbField)(j).SetRaw(value)
|
||||
}
|
||||
|
||||
// RawValue return JsonbField value
|
||||
func (j *JsonbField) RawValue() interface{} {
|
||||
return (*orm.JsonbField)(j).RawValue()
|
||||
}
|
||||
|
||||
// verify JsonbField implement Fielder
|
||||
var _ Fielder = new(JsonbField)
|
314
adapter/orm/orm.go
Normal file
314
adapter/orm/orm.go
Normal file
@ -0,0 +1,314 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build go1.8
|
||||
|
||||
// Package orm provide ORM for MySQL/PostgreSQL/sqlite
|
||||
// Simple Usage
|
||||
//
|
||||
// package main
|
||||
//
|
||||
// import (
|
||||
// "fmt"
|
||||
// "github.com/astaxie/beego/orm"
|
||||
// _ "github.com/go-sql-driver/mysql" // import your used driver
|
||||
// )
|
||||
//
|
||||
// // Model Struct
|
||||
// type User struct {
|
||||
// Id int `orm:"auto"`
|
||||
// Name string `orm:"size(100)"`
|
||||
// }
|
||||
//
|
||||
// func init() {
|
||||
// orm.RegisterDataBase("default", "mysql", "root:root@/my_db?charset=utf8", 30)
|
||||
// }
|
||||
//
|
||||
// func main() {
|
||||
// o := orm.NewOrm()
|
||||
// user := User{Name: "slene"}
|
||||
// // insert
|
||||
// id, err := o.Insert(&user)
|
||||
// // update
|
||||
// user.Name = "astaxie"
|
||||
// num, err := o.Update(&user)
|
||||
// // read one
|
||||
// u := User{Id: user.Id}
|
||||
// err = o.Read(&u)
|
||||
// // delete
|
||||
// num, err = o.Delete(&u)
|
||||
// }
|
||||
//
|
||||
// more docs: http://beego.me/docs/mvc/model/overview.md
|
||||
package orm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
|
||||
"github.com/astaxie/beego/client/orm"
|
||||
"github.com/astaxie/beego/client/orm/hints"
|
||||
"github.com/astaxie/beego/core/utils"
|
||||
)
|
||||
|
||||
// DebugQueries define the debug
|
||||
const (
|
||||
DebugQueries = iota
|
||||
)
|
||||
|
||||
// Define common vars
|
||||
var (
|
||||
Debug = orm.Debug
|
||||
DebugLog = orm.DebugLog
|
||||
DefaultRowsLimit = orm.DefaultRowsLimit
|
||||
DefaultRelsDepth = orm.DefaultRelsDepth
|
||||
DefaultTimeLoc = orm.DefaultTimeLoc
|
||||
ErrTxHasBegan = errors.New("<Ormer.Begin> transaction already begin")
|
||||
ErrTxDone = errors.New("<Ormer.Commit/Rollback> transaction not begin")
|
||||
ErrMultiRows = errors.New("<QuerySeter> return multi rows")
|
||||
ErrNoRows = errors.New("<QuerySeter> no row found")
|
||||
ErrStmtClosed = errors.New("<QuerySeter> stmt already closed")
|
||||
ErrArgs = errors.New("<Ormer> args error may be empty")
|
||||
ErrNotImplement = errors.New("have not implement")
|
||||
)
|
||||
|
||||
type ormer struct {
|
||||
delegate orm.Ormer
|
||||
txDelegate orm.TxOrmer
|
||||
isTx bool
|
||||
}
|
||||
|
||||
var _ Ormer = new(ormer)
|
||||
|
||||
// read data to model
|
||||
func (o *ormer) Read(md interface{}, cols ...string) error {
|
||||
if o.isTx {
|
||||
return o.txDelegate.Read(md, cols...)
|
||||
}
|
||||
return o.delegate.Read(md, cols...)
|
||||
}
|
||||
|
||||
// read data to model, like Read(), but use "SELECT FOR UPDATE" form
|
||||
func (o *ormer) ReadForUpdate(md interface{}, cols ...string) error {
|
||||
if o.isTx {
|
||||
return o.txDelegate.ReadForUpdate(md, cols...)
|
||||
}
|
||||
return o.delegate.ReadForUpdate(md, cols...)
|
||||
}
|
||||
|
||||
// Try to read a row from the database, or insert one if it doesn't exist
|
||||
func (o *ormer) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error) {
|
||||
if o.isTx {
|
||||
return o.txDelegate.ReadOrCreate(md, col1, cols...)
|
||||
}
|
||||
return o.delegate.ReadOrCreate(md, col1, cols...)
|
||||
}
|
||||
|
||||
// insert model data to database
|
||||
func (o *ormer) Insert(md interface{}) (int64, error) {
|
||||
if o.isTx {
|
||||
return o.txDelegate.Insert(md)
|
||||
}
|
||||
return o.delegate.Insert(md)
|
||||
}
|
||||
|
||||
// insert some models to database
|
||||
func (o *ormer) InsertMulti(bulk int, mds interface{}) (int64, error) {
|
||||
if o.isTx {
|
||||
return o.txDelegate.InsertMulti(bulk, mds)
|
||||
}
|
||||
return o.delegate.InsertMulti(bulk, mds)
|
||||
}
|
||||
|
||||
// InsertOrUpdate data to database
|
||||
func (o *ormer) InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error) {
|
||||
if o.isTx {
|
||||
return o.txDelegate.InsertOrUpdate(md, colConflitAndArgs...)
|
||||
}
|
||||
return o.delegate.InsertOrUpdate(md, colConflitAndArgs...)
|
||||
}
|
||||
|
||||
// update model to database.
|
||||
// cols set the columns those want to update.
|
||||
func (o *ormer) Update(md interface{}, cols ...string) (int64, error) {
|
||||
if o.isTx {
|
||||
return o.txDelegate.Update(md, cols...)
|
||||
}
|
||||
return o.delegate.Update(md, cols...)
|
||||
}
|
||||
|
||||
// delete model in database
|
||||
// cols shows the delete conditions values read from. default is pk
|
||||
func (o *ormer) Delete(md interface{}, cols ...string) (int64, error) {
|
||||
if o.isTx {
|
||||
return o.txDelegate.Delete(md, cols...)
|
||||
}
|
||||
return o.delegate.Delete(md, cols...)
|
||||
}
|
||||
|
||||
// create a models to models queryer
|
||||
func (o *ormer) QueryM2M(md interface{}, name string) QueryM2Mer {
|
||||
if o.isTx {
|
||||
return o.txDelegate.QueryM2M(md, name)
|
||||
}
|
||||
return o.delegate.QueryM2M(md, name)
|
||||
}
|
||||
|
||||
// load related models to md model.
|
||||
// args are limit, offset int and order string.
|
||||
//
|
||||
// example:
|
||||
// orm.LoadRelated(post,"Tags")
|
||||
// for _,tag := range post.Tags{...}
|
||||
//
|
||||
// make sure the relation is defined in model struct tags.
|
||||
func (o *ormer) LoadRelated(md interface{}, name string, args ...interface{}) (int64, error) {
|
||||
kvs := make([]utils.KV, 0, 4)
|
||||
for i, arg := range args {
|
||||
switch i {
|
||||
case 0:
|
||||
if v, ok := arg.(bool); ok {
|
||||
if v {
|
||||
kvs = append(kvs, hints.DefaultRelDepth())
|
||||
}
|
||||
} else if v, ok := arg.(int); ok {
|
||||
kvs = append(kvs, hints.RelDepth(v))
|
||||
}
|
||||
case 1:
|
||||
kvs = append(kvs, hints.Limit(orm.ToInt64(arg)))
|
||||
case 2:
|
||||
kvs = append(kvs, hints.Offset(orm.ToInt64(arg)))
|
||||
case 3:
|
||||
kvs = append(kvs, hints.Offset(orm.ToInt64(arg)))
|
||||
}
|
||||
}
|
||||
if o.isTx {
|
||||
return o.txDelegate.LoadRelated(md, name, kvs...)
|
||||
}
|
||||
return o.delegate.LoadRelated(md, name, kvs...)
|
||||
}
|
||||
|
||||
// return a QuerySeter for table operations.
|
||||
// table name can be string or struct.
|
||||
// e.g. QueryTable("user"), QueryTable(&user{}) or QueryTable((*User)(nil)),
|
||||
func (o *ormer) QueryTable(ptrStructOrTableName interface{}) (qs QuerySeter) {
|
||||
if o.isTx {
|
||||
return o.txDelegate.QueryTable(ptrStructOrTableName)
|
||||
}
|
||||
return o.delegate.QueryTable(ptrStructOrTableName)
|
||||
}
|
||||
|
||||
// switch to another registered database driver by given name.
|
||||
func (o *ormer) Using(name string) error {
|
||||
if o.isTx {
|
||||
return ErrTxHasBegan
|
||||
}
|
||||
o.delegate = orm.NewOrmUsingDB(name)
|
||||
return nil
|
||||
}
|
||||
|
||||
// begin transaction
|
||||
func (o *ormer) Begin() error {
|
||||
if o.isTx {
|
||||
return ErrTxHasBegan
|
||||
}
|
||||
return o.BeginTx(context.Background(), nil)
|
||||
}
|
||||
|
||||
func (o *ormer) BeginTx(ctx context.Context, opts *sql.TxOptions) error {
|
||||
if o.isTx {
|
||||
return ErrTxHasBegan
|
||||
}
|
||||
txOrmer, err := o.delegate.BeginWithCtxAndOpts(ctx, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
o.txDelegate = txOrmer
|
||||
o.isTx = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// commit transaction
|
||||
func (o *ormer) Commit() error {
|
||||
if !o.isTx {
|
||||
return ErrTxDone
|
||||
}
|
||||
err := o.txDelegate.Commit()
|
||||
if err == nil {
|
||||
o.isTx = false
|
||||
o.txDelegate = nil
|
||||
} else if err == sql.ErrTxDone {
|
||||
return ErrTxDone
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// rollback transaction
|
||||
func (o *ormer) Rollback() error {
|
||||
if !o.isTx {
|
||||
return ErrTxDone
|
||||
}
|
||||
err := o.txDelegate.Rollback()
|
||||
if err == nil {
|
||||
o.isTx = false
|
||||
o.txDelegate = nil
|
||||
} else if err == sql.ErrTxDone {
|
||||
return ErrTxDone
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// return a raw query seter for raw sql string.
|
||||
func (o *ormer) Raw(query string, args ...interface{}) RawSeter {
|
||||
if o.isTx {
|
||||
return o.txDelegate.Raw(query, args...)
|
||||
}
|
||||
return o.delegate.Raw(query, args...)
|
||||
}
|
||||
|
||||
// return current using database Driver
|
||||
func (o *ormer) Driver() Driver {
|
||||
if o.isTx {
|
||||
return o.txDelegate.Driver()
|
||||
}
|
||||
return o.delegate.Driver()
|
||||
}
|
||||
|
||||
// return sql.DBStats for current database
|
||||
func (o *ormer) DBStats() *sql.DBStats {
|
||||
if o.isTx {
|
||||
return o.txDelegate.DBStats()
|
||||
}
|
||||
return o.delegate.DBStats()
|
||||
}
|
||||
|
||||
// NewOrm create new orm
|
||||
func NewOrm() Ormer {
|
||||
o := orm.NewOrm()
|
||||
return &ormer{
|
||||
delegate: o,
|
||||
}
|
||||
}
|
||||
|
||||
// NewOrmWithDB create a new ormer object with specify *sql.DB for query
|
||||
func NewOrmWithDB(driverName, aliasName string, db *sql.DB) (Ormer, error) {
|
||||
o, err := orm.NewOrmWithDB(driverName, aliasName, db)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ormer{
|
||||
delegate: o,
|
||||
}, nil
|
||||
}
|
83
adapter/orm/orm_conds.go
Normal file
83
adapter/orm/orm_conds.go
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package orm
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/client/orm"
|
||||
)
|
||||
|
||||
// ExprSep define the expression separation
|
||||
const (
|
||||
ExprSep = "__"
|
||||
)
|
||||
|
||||
// Condition struct.
|
||||
// work for WHERE conditions.
|
||||
type Condition orm.Condition
|
||||
|
||||
// NewCondition return new condition struct
|
||||
func NewCondition() *Condition {
|
||||
return (*Condition)(orm.NewCondition())
|
||||
}
|
||||
|
||||
// Raw add raw sql to condition
|
||||
func (c Condition) Raw(expr string, sql string) *Condition {
|
||||
return (*Condition)((orm.Condition)(c).Raw(expr, sql))
|
||||
}
|
||||
|
||||
// And add expression to condition
|
||||
func (c Condition) And(expr string, args ...interface{}) *Condition {
|
||||
return (*Condition)((orm.Condition)(c).And(expr, args...))
|
||||
}
|
||||
|
||||
// AndNot add NOT expression to condition
|
||||
func (c Condition) AndNot(expr string, args ...interface{}) *Condition {
|
||||
return (*Condition)((orm.Condition)(c).AndNot(expr, args...))
|
||||
}
|
||||
|
||||
// AndCond combine a condition to current condition
|
||||
func (c *Condition) AndCond(cond *Condition) *Condition {
|
||||
return (*Condition)((*orm.Condition)(c).AndCond((*orm.Condition)(cond)))
|
||||
}
|
||||
|
||||
// AndNotCond combine a AND NOT condition to current condition
|
||||
func (c *Condition) AndNotCond(cond *Condition) *Condition {
|
||||
return (*Condition)((*orm.Condition)(c).AndNotCond((*orm.Condition)(cond)))
|
||||
}
|
||||
|
||||
// Or add OR expression to condition
|
||||
func (c Condition) Or(expr string, args ...interface{}) *Condition {
|
||||
return (*Condition)((orm.Condition)(c).Or(expr, args...))
|
||||
}
|
||||
|
||||
// OrNot add OR NOT expression to condition
|
||||
func (c Condition) OrNot(expr string, args ...interface{}) *Condition {
|
||||
return (*Condition)((orm.Condition)(c).OrNot(expr, args...))
|
||||
}
|
||||
|
||||
// OrCond combine a OR condition to current condition
|
||||
func (c *Condition) OrCond(cond *Condition) *Condition {
|
||||
return (*Condition)((*orm.Condition)(c).OrCond((*orm.Condition)(cond)))
|
||||
}
|
||||
|
||||
// OrNotCond combine a OR NOT condition to current condition
|
||||
func (c *Condition) OrNotCond(cond *Condition) *Condition {
|
||||
return (*Condition)((*orm.Condition)(c).OrNotCond((*orm.Condition)(cond)))
|
||||
}
|
||||
|
||||
// IsEmpty check the condition arguments are empty or not.
|
||||
func (c *Condition) IsEmpty() bool {
|
||||
return (*orm.Condition)(c).IsEmpty()
|
||||
}
|
32
adapter/orm/orm_log.go
Normal file
32
adapter/orm/orm_log.go
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package orm
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/astaxie/beego/client/orm"
|
||||
)
|
||||
|
||||
// Log implement the log.Logger
|
||||
type Log orm.Log
|
||||
|
||||
// costomer log func
|
||||
var LogFunc = orm.LogFunc
|
||||
|
||||
// NewLog set io.Writer to create a Logger.
|
||||
func NewLog(out io.Writer) *Log {
|
||||
return (*Log)(orm.NewLog(out))
|
||||
}
|
32
adapter/orm/orm_queryset.go
Normal file
32
adapter/orm/orm_queryset.go
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package orm
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/client/orm"
|
||||
)
|
||||
|
||||
// define Col operations
|
||||
const (
|
||||
ColAdd = orm.ColAdd
|
||||
ColMinus = orm.ColMinus
|
||||
ColMultiply = orm.ColMultiply
|
||||
ColExcept = orm.ColExcept
|
||||
ColBitAnd = orm.ColBitAnd
|
||||
ColBitRShift = orm.ColBitRShift
|
||||
ColBitLShift = orm.ColBitLShift
|
||||
ColBitXOR = orm.ColBitXOR
|
||||
ColBitOr = orm.ColBitOr
|
||||
)
|
27
adapter/orm/qb.go
Normal file
27
adapter/orm/qb.go
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package orm
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/client/orm"
|
||||
)
|
||||
|
||||
// QueryBuilder is the Query builder interface
|
||||
type QueryBuilder orm.QueryBuilder
|
||||
|
||||
// NewQueryBuilder return the QueryBuilder
|
||||
func NewQueryBuilder(driver string) (qb QueryBuilder, err error) {
|
||||
return orm.NewQueryBuilder(driver)
|
||||
}
|
150
adapter/orm/qb_mysql.go
Normal file
150
adapter/orm/qb_mysql.go
Normal file
@ -0,0 +1,150 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package orm
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/client/orm"
|
||||
)
|
||||
|
||||
// CommaSpace is the separation
|
||||
const CommaSpace = orm.CommaSpace
|
||||
|
||||
// MySQLQueryBuilder is the SQL build
|
||||
type MySQLQueryBuilder orm.MySQLQueryBuilder
|
||||
|
||||
// Select will join the fields
|
||||
func (qb *MySQLQueryBuilder) Select(fields ...string) QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).Select(fields...)
|
||||
}
|
||||
|
||||
// ForUpdate add the FOR UPDATE clause
|
||||
func (qb *MySQLQueryBuilder) ForUpdate() QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).ForUpdate()
|
||||
}
|
||||
|
||||
// From join the tables
|
||||
func (qb *MySQLQueryBuilder) From(tables ...string) QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).From(tables...)
|
||||
}
|
||||
|
||||
// InnerJoin INNER JOIN the table
|
||||
func (qb *MySQLQueryBuilder) InnerJoin(table string) QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).InnerJoin(table)
|
||||
}
|
||||
|
||||
// LeftJoin LEFT JOIN the table
|
||||
func (qb *MySQLQueryBuilder) LeftJoin(table string) QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).LeftJoin(table)
|
||||
}
|
||||
|
||||
// RightJoin RIGHT JOIN the table
|
||||
func (qb *MySQLQueryBuilder) RightJoin(table string) QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).RightJoin(table)
|
||||
}
|
||||
|
||||
// On join with on cond
|
||||
func (qb *MySQLQueryBuilder) On(cond string) QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).On(cond)
|
||||
}
|
||||
|
||||
// Where join the Where cond
|
||||
func (qb *MySQLQueryBuilder) Where(cond string) QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).Where(cond)
|
||||
}
|
||||
|
||||
// And join the and cond
|
||||
func (qb *MySQLQueryBuilder) And(cond string) QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).And(cond)
|
||||
}
|
||||
|
||||
// Or join the or cond
|
||||
func (qb *MySQLQueryBuilder) Or(cond string) QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).Or(cond)
|
||||
}
|
||||
|
||||
// In join the IN (vals)
|
||||
func (qb *MySQLQueryBuilder) In(vals ...string) QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).In(vals...)
|
||||
}
|
||||
|
||||
// OrderBy join the Order by fields
|
||||
func (qb *MySQLQueryBuilder) OrderBy(fields ...string) QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).OrderBy(fields...)
|
||||
}
|
||||
|
||||
// Asc join the asc
|
||||
func (qb *MySQLQueryBuilder) Asc() QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).Asc()
|
||||
}
|
||||
|
||||
// Desc join the desc
|
||||
func (qb *MySQLQueryBuilder) Desc() QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).Desc()
|
||||
}
|
||||
|
||||
// Limit join the limit num
|
||||
func (qb *MySQLQueryBuilder) Limit(limit int) QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).Limit(limit)
|
||||
}
|
||||
|
||||
// Offset join the offset num
|
||||
func (qb *MySQLQueryBuilder) Offset(offset int) QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).Offset(offset)
|
||||
}
|
||||
|
||||
// GroupBy join the Group by fields
|
||||
func (qb *MySQLQueryBuilder) GroupBy(fields ...string) QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).GroupBy(fields...)
|
||||
}
|
||||
|
||||
// Having join the Having cond
|
||||
func (qb *MySQLQueryBuilder) Having(cond string) QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).Having(cond)
|
||||
}
|
||||
|
||||
// Update join the update table
|
||||
func (qb *MySQLQueryBuilder) Update(tables ...string) QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).Update(tables...)
|
||||
}
|
||||
|
||||
// Set join the set kv
|
||||
func (qb *MySQLQueryBuilder) Set(kv ...string) QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).Set(kv...)
|
||||
}
|
||||
|
||||
// Delete join the Delete tables
|
||||
func (qb *MySQLQueryBuilder) Delete(tables ...string) QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).Delete(tables...)
|
||||
}
|
||||
|
||||
// InsertInto join the insert SQL
|
||||
func (qb *MySQLQueryBuilder) InsertInto(table string, fields ...string) QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).InsertInto(table, fields...)
|
||||
}
|
||||
|
||||
// Values join the Values(vals)
|
||||
func (qb *MySQLQueryBuilder) Values(vals ...string) QueryBuilder {
|
||||
return (*orm.MySQLQueryBuilder)(qb).Values(vals...)
|
||||
}
|
||||
|
||||
// Subquery join the sub as alias
|
||||
func (qb *MySQLQueryBuilder) Subquery(sub string, alias string) string {
|
||||
return (*orm.MySQLQueryBuilder)(qb).Subquery(sub, alias)
|
||||
}
|
||||
|
||||
// String join all Tokens
|
||||
func (qb *MySQLQueryBuilder) String() string {
|
||||
return (*orm.MySQLQueryBuilder)(qb).String()
|
||||
}
|
@ -15,168 +15,133 @@
|
||||
package orm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"github.com/astaxie/beego/client/orm"
|
||||
)
|
||||
|
||||
// TiDBQueryBuilder is the SQL build
|
||||
type TiDBQueryBuilder struct {
|
||||
Tokens []string
|
||||
}
|
||||
type TiDBQueryBuilder orm.TiDBQueryBuilder
|
||||
|
||||
// Select will join the fields
|
||||
func (qb *TiDBQueryBuilder) Select(fields ...string) QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "SELECT", strings.Join(fields, CommaSpace))
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).Select(fields...)
|
||||
}
|
||||
|
||||
// ForUpdate add the FOR UPDATE clause
|
||||
func (qb *TiDBQueryBuilder) ForUpdate() QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "FOR UPDATE")
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).ForUpdate()
|
||||
}
|
||||
|
||||
// From join the tables
|
||||
func (qb *TiDBQueryBuilder) From(tables ...string) QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "FROM", strings.Join(tables, CommaSpace))
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).From(tables...)
|
||||
}
|
||||
|
||||
// InnerJoin INNER JOIN the table
|
||||
func (qb *TiDBQueryBuilder) InnerJoin(table string) QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "INNER JOIN", table)
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).InnerJoin(table)
|
||||
}
|
||||
|
||||
// LeftJoin LEFT JOIN the table
|
||||
func (qb *TiDBQueryBuilder) LeftJoin(table string) QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "LEFT JOIN", table)
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).LeftJoin(table)
|
||||
}
|
||||
|
||||
// RightJoin RIGHT JOIN the table
|
||||
func (qb *TiDBQueryBuilder) RightJoin(table string) QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "RIGHT JOIN", table)
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).RightJoin(table)
|
||||
}
|
||||
|
||||
// On join with on cond
|
||||
func (qb *TiDBQueryBuilder) On(cond string) QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "ON", cond)
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).On(cond)
|
||||
}
|
||||
|
||||
// Where join the Where cond
|
||||
func (qb *TiDBQueryBuilder) Where(cond string) QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "WHERE", cond)
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).Where(cond)
|
||||
}
|
||||
|
||||
// And join the and cond
|
||||
func (qb *TiDBQueryBuilder) And(cond string) QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "AND", cond)
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).And(cond)
|
||||
}
|
||||
|
||||
// Or join the or cond
|
||||
func (qb *TiDBQueryBuilder) Or(cond string) QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "OR", cond)
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).Or(cond)
|
||||
}
|
||||
|
||||
// In join the IN (vals)
|
||||
func (qb *TiDBQueryBuilder) In(vals ...string) QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "IN", "(", strings.Join(vals, CommaSpace), ")")
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).In(vals...)
|
||||
}
|
||||
|
||||
// OrderBy join the Order by fields
|
||||
func (qb *TiDBQueryBuilder) OrderBy(fields ...string) QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "ORDER BY", strings.Join(fields, CommaSpace))
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).OrderBy(fields...)
|
||||
}
|
||||
|
||||
// Asc join the asc
|
||||
func (qb *TiDBQueryBuilder) Asc() QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "ASC")
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).Asc()
|
||||
}
|
||||
|
||||
// Desc join the desc
|
||||
func (qb *TiDBQueryBuilder) Desc() QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "DESC")
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).Desc()
|
||||
}
|
||||
|
||||
// Limit join the limit num
|
||||
func (qb *TiDBQueryBuilder) Limit(limit int) QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "LIMIT", strconv.Itoa(limit))
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).Limit(limit)
|
||||
}
|
||||
|
||||
// Offset join the offset num
|
||||
func (qb *TiDBQueryBuilder) Offset(offset int) QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "OFFSET", strconv.Itoa(offset))
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).Offset(offset)
|
||||
}
|
||||
|
||||
// GroupBy join the Group by fields
|
||||
func (qb *TiDBQueryBuilder) GroupBy(fields ...string) QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "GROUP BY", strings.Join(fields, CommaSpace))
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).GroupBy(fields...)
|
||||
}
|
||||
|
||||
// Having join the Having cond
|
||||
func (qb *TiDBQueryBuilder) Having(cond string) QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "HAVING", cond)
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).Having(cond)
|
||||
}
|
||||
|
||||
// Update join the update table
|
||||
func (qb *TiDBQueryBuilder) Update(tables ...string) QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "UPDATE", strings.Join(tables, CommaSpace))
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).Update(tables...)
|
||||
}
|
||||
|
||||
// Set join the set kv
|
||||
func (qb *TiDBQueryBuilder) Set(kv ...string) QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "SET", strings.Join(kv, CommaSpace))
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).Set(kv...)
|
||||
}
|
||||
|
||||
// Delete join the Delete tables
|
||||
func (qb *TiDBQueryBuilder) Delete(tables ...string) QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "DELETE")
|
||||
if len(tables) != 0 {
|
||||
qb.Tokens = append(qb.Tokens, strings.Join(tables, CommaSpace))
|
||||
}
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).Delete(tables...)
|
||||
}
|
||||
|
||||
// InsertInto join the insert SQL
|
||||
func (qb *TiDBQueryBuilder) InsertInto(table string, fields ...string) QueryBuilder {
|
||||
qb.Tokens = append(qb.Tokens, "INSERT INTO", table)
|
||||
if len(fields) != 0 {
|
||||
fieldsStr := strings.Join(fields, CommaSpace)
|
||||
qb.Tokens = append(qb.Tokens, "(", fieldsStr, ")")
|
||||
}
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).InsertInto(table, fields...)
|
||||
}
|
||||
|
||||
// Values join the Values(vals)
|
||||
func (qb *TiDBQueryBuilder) Values(vals ...string) QueryBuilder {
|
||||
valsStr := strings.Join(vals, CommaSpace)
|
||||
qb.Tokens = append(qb.Tokens, "VALUES", "(", valsStr, ")")
|
||||
return qb
|
||||
return (*orm.TiDBQueryBuilder)(qb).Values(vals...)
|
||||
}
|
||||
|
||||
// Subquery join the sub as alias
|
||||
func (qb *TiDBQueryBuilder) Subquery(sub string, alias string) string {
|
||||
return fmt.Sprintf("(%s) AS %s", sub, alias)
|
||||
return (*orm.TiDBQueryBuilder)(qb).Subquery(sub, alias)
|
||||
}
|
||||
|
||||
// String join all Tokens
|
||||
func (qb *TiDBQueryBuilder) String() string {
|
||||
return strings.Join(qb.Tokens, " ")
|
||||
return (*orm.TiDBQueryBuilder)(qb).String()
|
||||
}
|
34
adapter/orm/query_setter_adapter.go
Normal file
34
adapter/orm/query_setter_adapter.go
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright 2020
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package orm
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/client/orm"
|
||||
)
|
||||
|
||||
type baseQuerySetter struct {
|
||||
}
|
||||
|
||||
func (b *baseQuerySetter) ForceIndex(indexes ...string) orm.QuerySeter {
|
||||
panic("you should not invoke this method.")
|
||||
}
|
||||
|
||||
func (b *baseQuerySetter) UseIndex(indexes ...string) orm.QuerySeter {
|
||||
panic("you should not invoke this method.")
|
||||
}
|
||||
|
||||
func (b *baseQuerySetter) IgnoreIndex(indexes ...string) orm.QuerySeter {
|
||||
panic("you should not invoke this method.")
|
||||
}
|
150
adapter/orm/types.go
Normal file
150
adapter/orm/types.go
Normal file
@ -0,0 +1,150 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package orm
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"github.com/astaxie/beego/client/orm"
|
||||
)
|
||||
|
||||
// Params stores the Params
|
||||
type Params orm.Params
|
||||
|
||||
// ParamsList stores paramslist
|
||||
type ParamsList orm.ParamsList
|
||||
|
||||
// Driver define database driver
|
||||
type Driver orm.Driver
|
||||
|
||||
// Fielder define field info
|
||||
type Fielder orm.Fielder
|
||||
|
||||
// Ormer define the orm interface
|
||||
type Ormer interface {
|
||||
// read data to model
|
||||
// for example:
|
||||
// this will find User by Id field
|
||||
// u = &User{Id: user.Id}
|
||||
// err = Ormer.Read(u)
|
||||
// this will find User by UserName field
|
||||
// u = &User{UserName: "astaxie", Password: "pass"}
|
||||
// err = Ormer.Read(u, "UserName")
|
||||
Read(md interface{}, cols ...string) error
|
||||
// Like Read(), but with "FOR UPDATE" clause, useful in transaction.
|
||||
// Some databases are not support this feature.
|
||||
ReadForUpdate(md interface{}, cols ...string) error
|
||||
// Try to read a row from the database, or insert one if it doesn't exist
|
||||
ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error)
|
||||
// insert model data to database
|
||||
// for example:
|
||||
// user := new(User)
|
||||
// id, err = Ormer.Insert(user)
|
||||
// user must be a pointer and Insert will set user's pk field
|
||||
Insert(interface{}) (int64, error)
|
||||
// mysql:InsertOrUpdate(model) or InsertOrUpdate(model,"colu=colu+value")
|
||||
// if colu type is integer : can use(+-*/), string : convert(colu,"value")
|
||||
// postgres: InsertOrUpdate(model,"conflictColumnName") or InsertOrUpdate(model,"conflictColumnName","colu=colu+value")
|
||||
// if colu type is integer : can use(+-*/), string : colu || "value"
|
||||
InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error)
|
||||
// insert some models to database
|
||||
InsertMulti(bulk int, mds interface{}) (int64, error)
|
||||
// update model to database.
|
||||
// cols set the columns those want to update.
|
||||
// find model by Id(pk) field and update columns specified by fields, if cols is null then update all columns
|
||||
// for example:
|
||||
// user := User{Id: 2}
|
||||
// user.Langs = append(user.Langs, "zh-CN", "en-US")
|
||||
// user.Extra.Name = "beego"
|
||||
// user.Extra.Data = "orm"
|
||||
// num, err = Ormer.Update(&user, "Langs", "Extra")
|
||||
Update(md interface{}, cols ...string) (int64, error)
|
||||
// delete model in database
|
||||
Delete(md interface{}, cols ...string) (int64, error)
|
||||
// load related models to md model.
|
||||
// args are limit, offset int and order string.
|
||||
//
|
||||
// example:
|
||||
// Ormer.LoadRelated(post,"Tags")
|
||||
// for _,tag := range post.Tags{...}
|
||||
// args[0] bool true useDefaultRelsDepth ; false depth 0
|
||||
// args[0] int loadRelationDepth
|
||||
// args[1] int limit default limit 1000
|
||||
// args[2] int offset default offset 0
|
||||
// args[3] string order for example : "-Id"
|
||||
// make sure the relation is defined in model struct tags.
|
||||
LoadRelated(md interface{}, name string, args ...interface{}) (int64, error)
|
||||
// create a models to models queryer
|
||||
// for example:
|
||||
// post := Post{Id: 4}
|
||||
// m2m := Ormer.QueryM2M(&post, "Tags")
|
||||
QueryM2M(md interface{}, name string) QueryM2Mer
|
||||
// return a QuerySeter for table operations.
|
||||
// table name can be string or struct.
|
||||
// e.g. QueryTable("user"), QueryTable(&user{}) or QueryTable((*User)(nil)),
|
||||
QueryTable(ptrStructOrTableName interface{}) QuerySeter
|
||||
// switch to another registered database driver by given name.
|
||||
Using(name string) error
|
||||
// begin transaction
|
||||
// for example:
|
||||
// o := NewOrm()
|
||||
// err := o.Begin()
|
||||
// ...
|
||||
// err = o.Rollback()
|
||||
Begin() error
|
||||
// begin transaction with provided context and option
|
||||
// the provided context is used until the transaction is committed or rolled back.
|
||||
// if the context is canceled, the transaction will be rolled back.
|
||||
// the provided TxOptions is optional and may be nil if defaults should be used.
|
||||
// if a non-default isolation level is used that the driver doesn't support, an error will be returned.
|
||||
// for example:
|
||||
// o := NewOrm()
|
||||
// err := o.BeginTx(context.Background(), &sql.TxOptions{Isolation: sql.LevelRepeatableRead})
|
||||
// ...
|
||||
// err = o.Rollback()
|
||||
BeginTx(ctx context.Context, opts *sql.TxOptions) error
|
||||
// commit transaction
|
||||
Commit() error
|
||||
// rollback transaction
|
||||
Rollback() error
|
||||
// return a raw query seter for raw sql string.
|
||||
// for example:
|
||||
// ormer.Raw("UPDATE `user` SET `user_name` = ? WHERE `user_name` = ?", "slene", "testing").Exec()
|
||||
// // update user testing's name to slene
|
||||
Raw(query string, args ...interface{}) RawSeter
|
||||
Driver() Driver
|
||||
DBStats() *sql.DBStats
|
||||
}
|
||||
|
||||
// Inserter insert prepared statement
|
||||
type Inserter orm.Inserter
|
||||
|
||||
// QuerySeter query seter
|
||||
type QuerySeter orm.QuerySeter
|
||||
|
||||
// QueryM2Mer model to model query struct
|
||||
// all operations are on the m2m table only, will not affect the origin model table
|
||||
type QueryM2Mer orm.QueryM2Mer
|
||||
|
||||
// RawPreparer raw query statement
|
||||
type RawPreparer orm.RawPreparer
|
||||
|
||||
// RawSeter raw query seter
|
||||
// create From Ormer.Raw
|
||||
// for example:
|
||||
// sql := fmt.Sprintf("SELECT %sid%s,%sname%s FROM %suser%s WHERE id = ?",Q,Q,Q,Q,Q,Q)
|
||||
// rs := Ormer.Raw(sql, 1)
|
||||
type RawSeter orm.RawSeter
|
286
adapter/orm/utils.go
Normal file
286
adapter/orm/utils.go
Normal file
@ -0,0 +1,286 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package orm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/astaxie/beego/client/orm"
|
||||
)
|
||||
|
||||
type fn func(string) string
|
||||
|
||||
var (
|
||||
nameStrategyMap = map[string]fn{
|
||||
defaultNameStrategy: snakeString,
|
||||
SnakeAcronymNameStrategy: snakeStringWithAcronym,
|
||||
}
|
||||
defaultNameStrategy = "snakeString"
|
||||
SnakeAcronymNameStrategy = "snakeStringWithAcronym"
|
||||
nameStrategy = defaultNameStrategy
|
||||
)
|
||||
|
||||
// StrTo is the target string
|
||||
type StrTo orm.StrTo
|
||||
|
||||
// Set string
|
||||
func (f *StrTo) Set(v string) {
|
||||
(*orm.StrTo)(f).Set(v)
|
||||
}
|
||||
|
||||
// Clear string
|
||||
func (f *StrTo) Clear() {
|
||||
(*orm.StrTo)(f).Clear()
|
||||
}
|
||||
|
||||
// Exist check string exist
|
||||
func (f StrTo) Exist() bool {
|
||||
return orm.StrTo(f).Exist()
|
||||
}
|
||||
|
||||
// Bool string to bool
|
||||
func (f StrTo) Bool() (bool, error) {
|
||||
return orm.StrTo(f).Bool()
|
||||
}
|
||||
|
||||
// Float32 string to float32
|
||||
func (f StrTo) Float32() (float32, error) {
|
||||
return orm.StrTo(f).Float32()
|
||||
}
|
||||
|
||||
// Float64 string to float64
|
||||
func (f StrTo) Float64() (float64, error) {
|
||||
return orm.StrTo(f).Float64()
|
||||
}
|
||||
|
||||
// Int string to int
|
||||
func (f StrTo) Int() (int, error) {
|
||||
return orm.StrTo(f).Int()
|
||||
}
|
||||
|
||||
// Int8 string to int8
|
||||
func (f StrTo) Int8() (int8, error) {
|
||||
return orm.StrTo(f).Int8()
|
||||
}
|
||||
|
||||
// Int16 string to int16
|
||||
func (f StrTo) Int16() (int16, error) {
|
||||
return orm.StrTo(f).Int16()
|
||||
}
|
||||
|
||||
// Int32 string to int32
|
||||
func (f StrTo) Int32() (int32, error) {
|
||||
return orm.StrTo(f).Int32()
|
||||
}
|
||||
|
||||
// Int64 string to int64
|
||||
func (f StrTo) Int64() (int64, error) {
|
||||
return orm.StrTo(f).Int64()
|
||||
}
|
||||
|
||||
// Uint string to uint
|
||||
func (f StrTo) Uint() (uint, error) {
|
||||
return orm.StrTo(f).Uint()
|
||||
}
|
||||
|
||||
// Uint8 string to uint8
|
||||
func (f StrTo) Uint8() (uint8, error) {
|
||||
return orm.StrTo(f).Uint8()
|
||||
}
|
||||
|
||||
// Uint16 string to uint16
|
||||
func (f StrTo) Uint16() (uint16, error) {
|
||||
return orm.StrTo(f).Uint16()
|
||||
}
|
||||
|
||||
// Uint32 string to uint32
|
||||
func (f StrTo) Uint32() (uint32, error) {
|
||||
return orm.StrTo(f).Uint32()
|
||||
}
|
||||
|
||||
// Uint64 string to uint64
|
||||
func (f StrTo) Uint64() (uint64, error) {
|
||||
return orm.StrTo(f).Uint64()
|
||||
}
|
||||
|
||||
// String string to string
|
||||
func (f StrTo) String() string {
|
||||
return orm.StrTo(f).String()
|
||||
}
|
||||
|
||||
// ToStr interface to string
|
||||
func ToStr(value interface{}, args ...int) (s string) {
|
||||
switch v := value.(type) {
|
||||
case bool:
|
||||
s = strconv.FormatBool(v)
|
||||
case float32:
|
||||
s = strconv.FormatFloat(float64(v), 'f', argInt(args).Get(0, -1), argInt(args).Get(1, 32))
|
||||
case float64:
|
||||
s = strconv.FormatFloat(v, 'f', argInt(args).Get(0, -1), argInt(args).Get(1, 64))
|
||||
case int:
|
||||
s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
|
||||
case int8:
|
||||
s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
|
||||
case int16:
|
||||
s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
|
||||
case int32:
|
||||
s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
|
||||
case int64:
|
||||
s = strconv.FormatInt(v, argInt(args).Get(0, 10))
|
||||
case uint:
|
||||
s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
|
||||
case uint8:
|
||||
s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
|
||||
case uint16:
|
||||
s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
|
||||
case uint32:
|
||||
s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
|
||||
case uint64:
|
||||
s = strconv.FormatUint(v, argInt(args).Get(0, 10))
|
||||
case string:
|
||||
s = v
|
||||
case []byte:
|
||||
s = string(v)
|
||||
default:
|
||||
s = fmt.Sprintf("%v", v)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// ToInt64 interface to int64
|
||||
func ToInt64(value interface{}) (d int64) {
|
||||
val := reflect.ValueOf(value)
|
||||
switch value.(type) {
|
||||
case int, int8, int16, int32, int64:
|
||||
d = val.Int()
|
||||
case uint, uint8, uint16, uint32, uint64:
|
||||
d = int64(val.Uint())
|
||||
default:
|
||||
panic(fmt.Errorf("ToInt64 need numeric not `%T`", value))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func snakeStringWithAcronym(s string) string {
|
||||
data := make([]byte, 0, len(s)*2)
|
||||
num := len(s)
|
||||
for i := 0; i < num; i++ {
|
||||
d := s[i]
|
||||
before := false
|
||||
after := false
|
||||
if i > 0 {
|
||||
before = s[i-1] >= 'a' && s[i-1] <= 'z'
|
||||
}
|
||||
if i+1 < num {
|
||||
after = s[i+1] >= 'a' && s[i+1] <= 'z'
|
||||
}
|
||||
if i > 0 && d >= 'A' && d <= 'Z' && (before || after) {
|
||||
data = append(data, '_')
|
||||
}
|
||||
data = append(data, d)
|
||||
}
|
||||
return strings.ToLower(string(data[:]))
|
||||
}
|
||||
|
||||
// snake string, XxYy to xx_yy , XxYY to xx_y_y
|
||||
func snakeString(s string) string {
|
||||
data := make([]byte, 0, len(s)*2)
|
||||
j := false
|
||||
num := len(s)
|
||||
for i := 0; i < num; i++ {
|
||||
d := s[i]
|
||||
if i > 0 && d >= 'A' && d <= 'Z' && j {
|
||||
data = append(data, '_')
|
||||
}
|
||||
if d != '_' {
|
||||
j = true
|
||||
}
|
||||
data = append(data, d)
|
||||
}
|
||||
return strings.ToLower(string(data[:]))
|
||||
}
|
||||
|
||||
// SetNameStrategy set different name strategy
|
||||
func SetNameStrategy(s string) {
|
||||
if SnakeAcronymNameStrategy != s {
|
||||
nameStrategy = defaultNameStrategy
|
||||
}
|
||||
nameStrategy = s
|
||||
}
|
||||
|
||||
// camel string, xx_yy to XxYy
|
||||
func camelString(s string) string {
|
||||
data := make([]byte, 0, len(s))
|
||||
flag, num := true, len(s)-1
|
||||
for i := 0; i <= num; i++ {
|
||||
d := s[i]
|
||||
if d == '_' {
|
||||
flag = true
|
||||
continue
|
||||
} else if flag {
|
||||
if d >= 'a' && d <= 'z' {
|
||||
d = d - 32
|
||||
}
|
||||
flag = false
|
||||
}
|
||||
data = append(data, d)
|
||||
}
|
||||
return string(data[:])
|
||||
}
|
||||
|
||||
type argString []string
|
||||
|
||||
// get string by index from string slice
|
||||
func (a argString) Get(i int, args ...string) (r string) {
|
||||
if i >= 0 && i < len(a) {
|
||||
r = a[i]
|
||||
} else if len(args) > 0 {
|
||||
r = args[0]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type argInt []int
|
||||
|
||||
// get int by index from int slice
|
||||
func (a argInt) Get(i int, args ...int) (r int) {
|
||||
if i >= 0 && i < len(a) {
|
||||
r = a[i]
|
||||
}
|
||||
if len(args) > 0 {
|
||||
r = args[0]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// parse time to string with location
|
||||
func timeParse(dateString, format string) (time.Time, error) {
|
||||
tp, err := time.ParseInLocation(format, dateString, DefaultTimeLoc)
|
||||
return tp, err
|
||||
}
|
||||
|
||||
// get pointer indirect type
|
||||
func indirectType(v reflect.Type) reflect.Type {
|
||||
switch v.Kind() {
|
||||
case reflect.Ptr:
|
||||
return indirectType(v.Elem())
|
||||
default:
|
||||
return v
|
||||
}
|
||||
}
|
70
adapter/orm/utils_test.go
Normal file
70
adapter/orm/utils_test.go
Normal file
@ -0,0 +1,70 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package orm
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestCamelString(t *testing.T) {
|
||||
snake := []string{"pic_url", "hello_world_", "hello__World", "_HelLO_Word", "pic_url_1", "pic_url__1"}
|
||||
camel := []string{"PicUrl", "HelloWorld", "HelloWorld", "HelLOWord", "PicUrl1", "PicUrl1"}
|
||||
|
||||
answer := make(map[string]string)
|
||||
for i, v := range snake {
|
||||
answer[v] = camel[i]
|
||||
}
|
||||
|
||||
for _, v := range snake {
|
||||
res := camelString(v)
|
||||
if res != answer[v] {
|
||||
t.Error("Unit Test Fail:", v, res, answer[v])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSnakeString(t *testing.T) {
|
||||
camel := []string{"PicUrl", "HelloWorld", "HelloWorld", "HelLOWord", "PicUrl1", "XyXX"}
|
||||
snake := []string{"pic_url", "hello_world", "hello_world", "hel_l_o_word", "pic_url1", "xy_x_x"}
|
||||
|
||||
answer := make(map[string]string)
|
||||
for i, v := range camel {
|
||||
answer[v] = snake[i]
|
||||
}
|
||||
|
||||
for _, v := range camel {
|
||||
res := snakeString(v)
|
||||
if res != answer[v] {
|
||||
t.Error("Unit Test Fail:", v, res, answer[v])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSnakeStringWithAcronym(t *testing.T) {
|
||||
camel := []string{"ID", "PicURL", "HelloWorld", "HelloWorld", "HelLOWord", "PicUrl1", "XyXX"}
|
||||
snake := []string{"id", "pic_url", "hello_world", "hello_world", "hel_lo_word", "pic_url1", "xy_xx"}
|
||||
|
||||
answer := make(map[string]string)
|
||||
for i, v := range camel {
|
||||
answer[v] = snake[i]
|
||||
}
|
||||
|
||||
for _, v := range camel {
|
||||
res := snakeStringWithAcronym(v)
|
||||
if res != answer[v] {
|
||||
t.Error("Unit Test Fail:", v, res, answer[v])
|
||||
}
|
||||
}
|
||||
}
|
94
adapter/plugins/apiauth/apiauth.go
Normal file
94
adapter/plugins/apiauth/apiauth.go
Normal file
@ -0,0 +1,94 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package apiauth provides handlers to enable apiauth support.
|
||||
//
|
||||
// Simple Usage:
|
||||
// import(
|
||||
// "github.com/astaxie/beego"
|
||||
// "github.com/astaxie/beego/plugins/apiauth"
|
||||
// )
|
||||
//
|
||||
// func main(){
|
||||
// // apiauth every request
|
||||
// beego.InsertFilter("*", beego.BeforeRouter,apiauth.APIBaiscAuth("appid","appkey"))
|
||||
// beego.Run()
|
||||
// }
|
||||
//
|
||||
// Advanced Usage:
|
||||
//
|
||||
// func getAppSecret(appid string) string {
|
||||
// // get appsecret by appid
|
||||
// // maybe store in configure, maybe in database
|
||||
// }
|
||||
//
|
||||
// beego.InsertFilter("*", beego.BeforeRouter,apiauth.APISecretAuth(getAppSecret, 360))
|
||||
//
|
||||
// Information:
|
||||
//
|
||||
// In the request user should include these params in the query
|
||||
//
|
||||
// 1. appid
|
||||
//
|
||||
// appid is assigned to the application
|
||||
//
|
||||
// 2. signature
|
||||
//
|
||||
// get the signature use apiauth.Signature()
|
||||
//
|
||||
// when you send to server remember use url.QueryEscape()
|
||||
//
|
||||
// 3. timestamp:
|
||||
//
|
||||
// send the request time, the format is yyyy-mm-dd HH:ii:ss
|
||||
//
|
||||
package apiauth
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
|
||||
beego "github.com/astaxie/beego/adapter"
|
||||
"github.com/astaxie/beego/adapter/context"
|
||||
beecontext "github.com/astaxie/beego/server/web/context"
|
||||
"github.com/astaxie/beego/server/web/filter/apiauth"
|
||||
)
|
||||
|
||||
// AppIDToAppSecret is used to get appsecret throw appid
|
||||
type AppIDToAppSecret apiauth.AppIDToAppSecret
|
||||
|
||||
// APIBasicAuth use the basic appid/appkey as the AppIdToAppSecret
|
||||
func APIBasicAuth(appid, appkey string) beego.FilterFunc {
|
||||
f := apiauth.APIBasicAuth(appid, appkey)
|
||||
return func(c *context.Context) {
|
||||
f((*beecontext.Context)(c))
|
||||
}
|
||||
}
|
||||
|
||||
// APIBaiscAuth calls APIBasicAuth for previous callers
|
||||
func APIBaiscAuth(appid, appkey string) beego.FilterFunc {
|
||||
return APIBasicAuth(appid, appkey)
|
||||
}
|
||||
|
||||
// APISecretAuth use AppIdToAppSecret verify and
|
||||
func APISecretAuth(f AppIDToAppSecret, timeout int) beego.FilterFunc {
|
||||
ft := apiauth.APISecretAuth(apiauth.AppIDToAppSecret(f), timeout)
|
||||
return func(ctx *context.Context) {
|
||||
ft((*beecontext.Context)(ctx))
|
||||
}
|
||||
}
|
||||
|
||||
// Signature used to generate signature with the appsecret/method/params/RequestURI
|
||||
func Signature(appsecret, method string, params url.Values, requestURL string) string {
|
||||
return apiauth.Signature(appsecret, method, params, requestURL)
|
||||
}
|
81
adapter/plugins/auth/basic.go
Normal file
81
adapter/plugins/auth/basic.go
Normal file
@ -0,0 +1,81 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package auth provides handlers to enable basic auth support.
|
||||
// Simple Usage:
|
||||
// import(
|
||||
// "github.com/astaxie/beego"
|
||||
// "github.com/astaxie/beego/plugins/auth"
|
||||
// )
|
||||
//
|
||||
// func main(){
|
||||
// // authenticate every request
|
||||
// beego.InsertFilter("*", beego.BeforeRouter,auth.Basic("username","secretpassword"))
|
||||
// beego.Run()
|
||||
// }
|
||||
//
|
||||
//
|
||||
// Advanced Usage:
|
||||
//
|
||||
// func SecretAuth(username, password string) bool {
|
||||
// return username == "astaxie" && password == "helloBeego"
|
||||
// }
|
||||
// authPlugin := auth.NewBasicAuthenticator(SecretAuth, "Authorization Required")
|
||||
// beego.InsertFilter("*", beego.BeforeRouter,authPlugin)
|
||||
package auth
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
beego "github.com/astaxie/beego/adapter"
|
||||
"github.com/astaxie/beego/adapter/context"
|
||||
beecontext "github.com/astaxie/beego/server/web/context"
|
||||
"github.com/astaxie/beego/server/web/filter/auth"
|
||||
)
|
||||
|
||||
// Basic is the http basic auth
|
||||
func Basic(username string, password string) beego.FilterFunc {
|
||||
return func(c *context.Context) {
|
||||
f := auth.Basic(username, password)
|
||||
f((*beecontext.Context)(c))
|
||||
}
|
||||
}
|
||||
|
||||
// NewBasicAuthenticator return the BasicAuth
|
||||
func NewBasicAuthenticator(secrets SecretProvider, realm string) beego.FilterFunc {
|
||||
f := auth.NewBasicAuthenticator(auth.SecretProvider(secrets), realm)
|
||||
return func(c *context.Context) {
|
||||
f((*beecontext.Context)(c))
|
||||
}
|
||||
}
|
||||
|
||||
// SecretProvider is the SecretProvider function
|
||||
type SecretProvider auth.SecretProvider
|
||||
|
||||
// BasicAuth store the SecretProvider and Realm
|
||||
type BasicAuth auth.BasicAuth
|
||||
|
||||
// CheckAuth Checks the username/password combination from the request. Returns
|
||||
// either an empty string (authentication failed) or the name of the
|
||||
// authenticated user.
|
||||
// Supports MD5 and SHA1 password entries
|
||||
func (a *BasicAuth) CheckAuth(r *http.Request) string {
|
||||
return (*auth.BasicAuth)(a).CheckAuth(r)
|
||||
}
|
||||
|
||||
// RequireAuth http.Handler for BasicAuth which initiates the authentication process
|
||||
// (or requires reauthentication).
|
||||
func (a *BasicAuth) RequireAuth(w http.ResponseWriter, r *http.Request) {
|
||||
(*auth.BasicAuth)(a).RequireAuth(w, r)
|
||||
}
|
80
adapter/plugins/authz/authz.go
Normal file
80
adapter/plugins/authz/authz.go
Normal file
@ -0,0 +1,80 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package authz provides handlers to enable ACL, RBAC, ABAC authorization support.
|
||||
// Simple Usage:
|
||||
// import(
|
||||
// "github.com/astaxie/beego"
|
||||
// "github.com/astaxie/beego/plugins/authz"
|
||||
// "github.com/casbin/casbin"
|
||||
// )
|
||||
//
|
||||
// func main(){
|
||||
// // mediate the access for every request
|
||||
// beego.InsertFilter("*", beego.BeforeRouter, authz.NewAuthorizer(casbin.NewEnforcer("authz_model.conf", "authz_policy.csv")))
|
||||
// beego.Run()
|
||||
// }
|
||||
//
|
||||
//
|
||||
// Advanced Usage:
|
||||
//
|
||||
// func main(){
|
||||
// e := casbin.NewEnforcer("authz_model.conf", "")
|
||||
// e.AddRoleForUser("alice", "admin")
|
||||
// e.AddPolicy(...)
|
||||
//
|
||||
// beego.InsertFilter("*", beego.BeforeRouter, authz.NewAuthorizer(e))
|
||||
// beego.Run()
|
||||
// }
|
||||
package authz
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/casbin/casbin"
|
||||
|
||||
beego "github.com/astaxie/beego/adapter"
|
||||
"github.com/astaxie/beego/adapter/context"
|
||||
beecontext "github.com/astaxie/beego/server/web/context"
|
||||
"github.com/astaxie/beego/server/web/filter/authz"
|
||||
)
|
||||
|
||||
// NewAuthorizer returns the authorizer.
|
||||
// Use a casbin enforcer as input
|
||||
func NewAuthorizer(e *casbin.Enforcer) beego.FilterFunc {
|
||||
f := authz.NewAuthorizer(e)
|
||||
return func(context *context.Context) {
|
||||
f((*beecontext.Context)(context))
|
||||
}
|
||||
}
|
||||
|
||||
// BasicAuthorizer stores the casbin handler
|
||||
type BasicAuthorizer authz.BasicAuthorizer
|
||||
|
||||
// GetUserName gets the user name from the request.
|
||||
// Currently, only HTTP basic authentication is supported
|
||||
func (a *BasicAuthorizer) GetUserName(r *http.Request) string {
|
||||
return (*authz.BasicAuthorizer)(a).GetUserName(r)
|
||||
}
|
||||
|
||||
// CheckPermission checks the user/method/path combination from the request.
|
||||
// Returns true (permission granted) or false (permission forbidden)
|
||||
func (a *BasicAuthorizer) CheckPermission(r *http.Request) bool {
|
||||
return (*authz.BasicAuthorizer)(a).CheckPermission(r)
|
||||
}
|
||||
|
||||
// RequirePermission returns the 403 Forbidden to the client
|
||||
func (a *BasicAuthorizer) RequirePermission(w http.ResponseWriter) {
|
||||
(*authz.BasicAuthorizer)(a).RequirePermission(w)
|
||||
}
|
@ -15,13 +15,14 @@
|
||||
package authz
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego"
|
||||
"github.com/astaxie/beego/context"
|
||||
"github.com/astaxie/beego/plugins/auth"
|
||||
"github.com/hsluoyz/casbin"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
beego "github.com/astaxie/beego/adapter"
|
||||
"github.com/astaxie/beego/adapter/context"
|
||||
"github.com/astaxie/beego/adapter/plugins/auth"
|
||||
"github.com/casbin/casbin"
|
||||
)
|
||||
|
||||
func testRequest(t *testing.T, handler *beego.ControllerRegister, user string, path string, method string, code int) {
|
71
adapter/plugins/cors/cors.go
Normal file
71
adapter/plugins/cors/cors.go
Normal file
@ -0,0 +1,71 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package cors provides handlers to enable CORS support.
|
||||
// Usage
|
||||
// import (
|
||||
// "github.com/astaxie/beego"
|
||||
// "github.com/astaxie/beego/plugins/cors"
|
||||
// )
|
||||
//
|
||||
// func main() {
|
||||
// // CORS for https://foo.* origins, allowing:
|
||||
// // - PUT and PATCH methods
|
||||
// // - Origin header
|
||||
// // - Credentials share
|
||||
// beego.InsertFilter("*", beego.BeforeRouter, cors.Allow(&cors.Options{
|
||||
// AllowOrigins: []string{"https://*.foo.com"},
|
||||
// AllowMethods: []string{"PUT", "PATCH"},
|
||||
// AllowHeaders: []string{"Origin"},
|
||||
// ExposeHeaders: []string{"Content-Length"},
|
||||
// AllowCredentials: true,
|
||||
// }))
|
||||
// beego.Run()
|
||||
// }
|
||||
package cors
|
||||
|
||||
import (
|
||||
beego "github.com/astaxie/beego/adapter"
|
||||
beecontext "github.com/astaxie/beego/server/web/context"
|
||||
"github.com/astaxie/beego/server/web/filter/cors"
|
||||
|
||||
"github.com/astaxie/beego/adapter/context"
|
||||
)
|
||||
|
||||
// Options represents Access Control options.
|
||||
type Options cors.Options
|
||||
|
||||
// Header converts options into CORS headers.
|
||||
func (o *Options) Header(origin string) (headers map[string]string) {
|
||||
return (*cors.Options)(o).Header(origin)
|
||||
}
|
||||
|
||||
// PreflightHeader converts options into CORS headers for a preflight response.
|
||||
func (o *Options) PreflightHeader(origin, rMethod, rHeaders string) (headers map[string]string) {
|
||||
return (*cors.Options)(o).PreflightHeader(origin, rMethod, rHeaders)
|
||||
}
|
||||
|
||||
// IsOriginAllowed looks up if the origin matches one of the patterns
|
||||
// generated from Options.AllowOrigins patterns.
|
||||
func (o *Options) IsOriginAllowed(origin string) bool {
|
||||
return (*cors.Options)(o).IsOriginAllowed(origin)
|
||||
}
|
||||
|
||||
// Allow enables CORS for requests those match the provided options.
|
||||
func Allow(opts *Options) beego.FilterFunc {
|
||||
f := cors.Allow((*cors.Options)(opts))
|
||||
return func(c *context.Context) {
|
||||
f((*beecontext.Context)(c))
|
||||
}
|
||||
}
|
57
adapter/policy.go
Normal file
57
adapter/policy.go
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright 2016 beego authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package adapter
|
||||
|
||||
import (
|
||||
"github.com/astaxie/beego/adapter/context"
|
||||
"github.com/astaxie/beego/server/web"
|
||||
beecontext "github.com/astaxie/beego/server/web/context"
|
||||
)
|
||||
|
||||
// PolicyFunc defines a policy function which is invoked before the controller handler is executed.
|
||||
type PolicyFunc func(*context.Context)
|
||||
|
||||
// FindPolicy Find Router info for URL
|
||||
func (p *ControllerRegister) FindPolicy(cont *context.Context) []PolicyFunc {
|
||||
pf := (*web.ControllerRegister)(p).FindPolicy((*beecontext.Context)(cont))
|
||||
npf := newToOldPolicyFunc(pf)
|
||||
return npf
|
||||
}
|
||||
|
||||
func newToOldPolicyFunc(pf []web.PolicyFunc) []PolicyFunc {
|
||||
npf := make([]PolicyFunc, 0, len(pf))
|
||||
for _, f := range pf {
|
||||
npf = append(npf, func(c *context.Context) {
|
||||
f((*beecontext.Context)(c))
|
||||
})
|
||||
}
|
||||
return npf
|
||||
}
|
||||
|
||||
func oldToNewPolicyFunc(pf []PolicyFunc) []web.PolicyFunc {
|
||||
npf := make([]web.PolicyFunc, 0, len(pf))
|
||||
for _, f := range pf {
|
||||
npf = append(npf, func(c *beecontext.Context) {
|
||||
f((*context.Context)(c))
|
||||
})
|
||||
}
|
||||
return npf
|
||||
}
|
||||
|
||||
// Policy Register new policy in beego
|
||||
func Policy(pattern, method string, policy ...PolicyFunc) {
|
||||
pf := oldToNewPolicyFunc(policy)
|
||||
web.Policy(pattern, method, pf...)
|
||||
}
|
282
adapter/router.go
Normal file
282
adapter/router.go
Normal file
@ -0,0 +1,282 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package adapter
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
beecontext "github.com/astaxie/beego/adapter/context"
|
||||
"github.com/astaxie/beego/server/web/context"
|
||||
|
||||
"github.com/astaxie/beego/server/web"
|
||||
)
|
||||
|
||||
// default filter execution points
|
||||
const (
|
||||
BeforeStatic = web.BeforeStatic
|
||||
BeforeRouter = web.BeforeRouter
|
||||
BeforeExec = web.BeforeExec
|
||||
AfterExec = web.AfterExec
|
||||
FinishRouter = web.FinishRouter
|
||||
)
|
||||
|
||||
var (
|
||||
// HTTPMETHOD list the supported http methods.
|
||||
HTTPMETHOD = web.HTTPMETHOD
|
||||
|
||||
// DefaultAccessLogFilter will skip the accesslog if return true
|
||||
DefaultAccessLogFilter FilterHandler = &newToOldFtHdlAdapter{
|
||||
delegate: web.DefaultAccessLogFilter,
|
||||
}
|
||||
)
|
||||
|
||||
// FilterHandler is an interface for
|
||||
type FilterHandler interface {
|
||||
Filter(*beecontext.Context) bool
|
||||
}
|
||||
|
||||
type newToOldFtHdlAdapter struct {
|
||||
delegate web.FilterHandler
|
||||
}
|
||||
|
||||
func (n *newToOldFtHdlAdapter) Filter(ctx *beecontext.Context) bool {
|
||||
return n.delegate.Filter((*context.Context)(ctx))
|
||||
}
|
||||
|
||||
// ExceptMethodAppend to append a slice's value into "exceptMethod", for controller's methods shouldn't reflect to AutoRouter
|
||||
func ExceptMethodAppend(action string) {
|
||||
web.ExceptMethodAppend(action)
|
||||
}
|
||||
|
||||
// ControllerInfo holds information about the controller.
|
||||
type ControllerInfo web.ControllerInfo
|
||||
|
||||
func (c *ControllerInfo) GetPattern() string {
|
||||
return (*web.ControllerInfo)(c).GetPattern()
|
||||
}
|
||||
|
||||
// ControllerRegister containers registered router rules, controller handlers and filters.
|
||||
type ControllerRegister web.ControllerRegister
|
||||
|
||||
// NewControllerRegister returns a new ControllerRegister.
|
||||
func NewControllerRegister() *ControllerRegister {
|
||||
return (*ControllerRegister)(web.NewControllerRegister())
|
||||
}
|
||||
|
||||
// Add controller handler and pattern rules to ControllerRegister.
|
||||
// usage:
|
||||
// default methods is the same name as method
|
||||
// Add("/user",&UserController{})
|
||||
// Add("/api/list",&RestController{},"*:ListFood")
|
||||
// Add("/api/create",&RestController{},"post:CreateFood")
|
||||
// Add("/api/update",&RestController{},"put:UpdateFood")
|
||||
// Add("/api/delete",&RestController{},"delete:DeleteFood")
|
||||
// Add("/api",&RestController{},"get,post:ApiFunc"
|
||||
// Add("/simple",&SimpleController{},"get:GetFunc;post:PostFunc")
|
||||
func (p *ControllerRegister) Add(pattern string, c ControllerInterface, mappingMethods ...string) {
|
||||
(*web.ControllerRegister)(p).Add(pattern, c, mappingMethods...)
|
||||
}
|
||||
|
||||
// Include only when the Runmode is dev will generate router file in the router/auto.go from the controller
|
||||
// Include(&BankAccount{}, &OrderController{},&RefundController{},&ReceiptController{})
|
||||
func (p *ControllerRegister) Include(cList ...ControllerInterface) {
|
||||
nls := oldToNewCtrlIntfs(cList)
|
||||
(*web.ControllerRegister)(p).Include(nls...)
|
||||
}
|
||||
|
||||
// GetContext returns a context from pool, so usually you should remember to call Reset function to clean the context
|
||||
// And don't forget to give back context to pool
|
||||
// example:
|
||||
// ctx := p.GetContext()
|
||||
// ctx.Reset(w, q)
|
||||
// defer p.GiveBackContext(ctx)
|
||||
func (p *ControllerRegister) GetContext() *beecontext.Context {
|
||||
return (*beecontext.Context)((*web.ControllerRegister)(p).GetContext())
|
||||
}
|
||||
|
||||
// GiveBackContext put the ctx into pool so that it could be reuse
|
||||
func (p *ControllerRegister) GiveBackContext(ctx *beecontext.Context) {
|
||||
(*web.ControllerRegister)(p).GiveBackContext((*context.Context)(ctx))
|
||||
}
|
||||
|
||||
// Get add get method
|
||||
// usage:
|
||||
// Get("/", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
func (p *ControllerRegister) Get(pattern string, f FilterFunc) {
|
||||
(*web.ControllerRegister)(p).Get(pattern, func(ctx *context.Context) {
|
||||
f((*beecontext.Context)(ctx))
|
||||
})
|
||||
}
|
||||
|
||||
// Post add post method
|
||||
// usage:
|
||||
// Post("/api", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
func (p *ControllerRegister) Post(pattern string, f FilterFunc) {
|
||||
(*web.ControllerRegister)(p).Post(pattern, func(ctx *context.Context) {
|
||||
f((*beecontext.Context)(ctx))
|
||||
})
|
||||
}
|
||||
|
||||
// Put add put method
|
||||
// usage:
|
||||
// Put("/api/:id", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
func (p *ControllerRegister) Put(pattern string, f FilterFunc) {
|
||||
(*web.ControllerRegister)(p).Put(pattern, func(ctx *context.Context) {
|
||||
f((*beecontext.Context)(ctx))
|
||||
})
|
||||
}
|
||||
|
||||
// Delete add delete method
|
||||
// usage:
|
||||
// Delete("/api/:id", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
func (p *ControllerRegister) Delete(pattern string, f FilterFunc) {
|
||||
(*web.ControllerRegister)(p).Delete(pattern, func(ctx *context.Context) {
|
||||
f((*beecontext.Context)(ctx))
|
||||
})
|
||||
}
|
||||
|
||||
// Head add head method
|
||||
// usage:
|
||||
// Head("/api/:id", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
func (p *ControllerRegister) Head(pattern string, f FilterFunc) {
|
||||
(*web.ControllerRegister)(p).Head(pattern, func(ctx *context.Context) {
|
||||
f((*beecontext.Context)(ctx))
|
||||
})
|
||||
}
|
||||
|
||||
// Patch add patch method
|
||||
// usage:
|
||||
// Patch("/api/:id", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
func (p *ControllerRegister) Patch(pattern string, f FilterFunc) {
|
||||
(*web.ControllerRegister)(p).Patch(pattern, func(ctx *context.Context) {
|
||||
f((*beecontext.Context)(ctx))
|
||||
})
|
||||
}
|
||||
|
||||
// Options add options method
|
||||
// usage:
|
||||
// Options("/api/:id", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
func (p *ControllerRegister) Options(pattern string, f FilterFunc) {
|
||||
(*web.ControllerRegister)(p).Options(pattern, func(ctx *context.Context) {
|
||||
f((*beecontext.Context)(ctx))
|
||||
})
|
||||
}
|
||||
|
||||
// Any add all method
|
||||
// usage:
|
||||
// Any("/api/:id", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
func (p *ControllerRegister) Any(pattern string, f FilterFunc) {
|
||||
(*web.ControllerRegister)(p).Any(pattern, func(ctx *context.Context) {
|
||||
f((*beecontext.Context)(ctx))
|
||||
})
|
||||
}
|
||||
|
||||
// AddMethod add http method router
|
||||
// usage:
|
||||
// AddMethod("get","/api/:id", func(ctx *context.Context){
|
||||
// ctx.Output.Body("hello world")
|
||||
// })
|
||||
func (p *ControllerRegister) AddMethod(method, pattern string, f FilterFunc) {
|
||||
(*web.ControllerRegister)(p).AddMethod(method, pattern, func(ctx *context.Context) {
|
||||
f((*beecontext.Context)(ctx))
|
||||
})
|
||||
}
|
||||
|
||||
// Handler add user defined Handler
|
||||
func (p *ControllerRegister) Handler(pattern string, h http.Handler, options ...interface{}) {
|
||||
(*web.ControllerRegister)(p).Handler(pattern, h, options)
|
||||
}
|
||||
|
||||
// AddAuto router to ControllerRegister.
|
||||
// example beego.AddAuto(&MainContorlller{}),
|
||||
// MainController has method List and Page.
|
||||
// visit the url /main/list to execute List function
|
||||
// /main/page to execute Page function.
|
||||
func (p *ControllerRegister) AddAuto(c ControllerInterface) {
|
||||
(*web.ControllerRegister)(p).AddAuto(c)
|
||||
}
|
||||
|
||||
// AddAutoPrefix Add auto router to ControllerRegister with prefix.
|
||||
// example beego.AddAutoPrefix("/admin",&MainContorlller{}),
|
||||
// MainController has method List and Page.
|
||||
// visit the url /admin/main/list to execute List function
|
||||
// /admin/main/page to execute Page function.
|
||||
func (p *ControllerRegister) AddAutoPrefix(prefix string, c ControllerInterface) {
|
||||
(*web.ControllerRegister)(p).AddAutoPrefix(prefix, c)
|
||||
}
|
||||
|
||||
// InsertFilter Add a FilterFunc with pattern rule and action constant.
|
||||
// params is for:
|
||||
// 1. setting the returnOnOutput value (false allows multiple filters to execute)
|
||||
// 2. determining whether or not params need to be reset.
|
||||
func (p *ControllerRegister) InsertFilter(pattern string, pos int, filter FilterFunc, params ...bool) error {
|
||||
opts := oldToNewFilterOpts(params)
|
||||
return (*web.ControllerRegister)(p).InsertFilter(pattern, pos, func(ctx *context.Context) {
|
||||
filter((*beecontext.Context)(ctx))
|
||||
}, opts...)
|
||||
}
|
||||
|
||||
func oldToNewFilterOpts(params []bool) []web.FilterOpt {
|
||||
opts := make([]web.FilterOpt, 0, 4)
|
||||
if len(params) > 0 {
|
||||
opts = append(opts, web.WithReturnOnOutput(params[0]))
|
||||
} else {
|
||||
// the default value should be true
|
||||
opts = append(opts, web.WithReturnOnOutput(true))
|
||||
}
|
||||
if len(params) > 1 {
|
||||
opts = append(opts, web.WithResetParams(params[1]))
|
||||
}
|
||||
return opts
|
||||
}
|
||||
|
||||
// URLFor does another controller handler in this request function.
|
||||
// it can access any controller method.
|
||||
func (p *ControllerRegister) URLFor(endpoint string, values ...interface{}) string {
|
||||
return (*web.ControllerRegister)(p).URLFor(endpoint, values...)
|
||||
}
|
||||
|
||||
// Implement http.Handler interface.
|
||||
func (p *ControllerRegister) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
(*web.ControllerRegister)(p).ServeHTTP(rw, r)
|
||||
}
|
||||
|
||||
// FindRouter Find Router info for URL
|
||||
func (p *ControllerRegister) FindRouter(ctx *beecontext.Context) (routerInfo *ControllerInfo, isFind bool) {
|
||||
r, ok := (*web.ControllerRegister)(p).FindRouter((*context.Context)(ctx))
|
||||
return (*ControllerInfo)(r), ok
|
||||
}
|
||||
|
||||
// LogAccess logging info HTTP Access
|
||||
func LogAccess(ctx *beecontext.Context, startTime *time.Time, statusCode int) {
|
||||
web.LogAccess((*context.Context)(ctx), startTime, statusCode)
|
||||
}
|
118
adapter/session/couchbase/sess_couchbase.go
Normal file
118
adapter/session/couchbase/sess_couchbase.go
Normal file
@ -0,0 +1,118 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package couchbase for session provider
|
||||
//
|
||||
// depend on github.com/couchbaselabs/go-couchbasee
|
||||
//
|
||||
// go install github.com/couchbaselabs/go-couchbase
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/astaxie/beego/session/couchbase"
|
||||
// "github.com/astaxie/beego/session"
|
||||
// )
|
||||
//
|
||||
// func init() {
|
||||
// globalSessions, _ = session.NewManager("couchbase", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"http://host:port/, Pool, Bucket"}``)
|
||||
// go globalSessions.GC()
|
||||
// }
|
||||
//
|
||||
// more docs: http://beego.me/docs/module/session.md
|
||||
package couchbase
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/astaxie/beego/adapter/session"
|
||||
beecb "github.com/astaxie/beego/server/web/session/couchbase"
|
||||
)
|
||||
|
||||
// SessionStore store each session
|
||||
type SessionStore beecb.SessionStore
|
||||
|
||||
// Provider couchabse provided
|
||||
type Provider beecb.Provider
|
||||
|
||||
// Set value to couchabse session
|
||||
func (cs *SessionStore) Set(key, value interface{}) error {
|
||||
return (*beecb.SessionStore)(cs).Set(context.Background(), key, value)
|
||||
}
|
||||
|
||||
// Get value from couchabse session
|
||||
func (cs *SessionStore) Get(key interface{}) interface{} {
|
||||
return (*beecb.SessionStore)(cs).Get(context.Background(), key)
|
||||
}
|
||||
|
||||
// Delete value in couchbase session by given key
|
||||
func (cs *SessionStore) Delete(key interface{}) error {
|
||||
return (*beecb.SessionStore)(cs).Delete(context.Background(), key)
|
||||
}
|
||||
|
||||
// Flush Clean all values in couchbase session
|
||||
func (cs *SessionStore) Flush() error {
|
||||
return (*beecb.SessionStore)(cs).Flush(context.Background())
|
||||
}
|
||||
|
||||
// SessionID Get couchbase session store id
|
||||
func (cs *SessionStore) SessionID() string {
|
||||
return (*beecb.SessionStore)(cs).SessionID(context.Background())
|
||||
}
|
||||
|
||||
// SessionRelease Write couchbase session with Gob string
|
||||
func (cs *SessionStore) SessionRelease(w http.ResponseWriter) {
|
||||
(*beecb.SessionStore)(cs).SessionRelease(context.Background(), w)
|
||||
}
|
||||
|
||||
// SessionInit init couchbase session
|
||||
// savepath like couchbase server REST/JSON URL
|
||||
// e.g. http://host:port/, Pool, Bucket
|
||||
func (cp *Provider) SessionInit(maxlifetime int64, savePath string) error {
|
||||
return (*beecb.Provider)(cp).SessionInit(context.Background(), maxlifetime, savePath)
|
||||
}
|
||||
|
||||
// SessionRead read couchbase session by sid
|
||||
func (cp *Provider) SessionRead(sid string) (session.Store, error) {
|
||||
s, err := (*beecb.Provider)(cp).SessionRead(context.Background(), sid)
|
||||
return session.CreateNewToOldStoreAdapter(s), err
|
||||
}
|
||||
|
||||
// SessionExist Check couchbase session exist.
|
||||
// it checkes sid exist or not.
|
||||
func (cp *Provider) SessionExist(sid string) bool {
|
||||
res, _ := (*beecb.Provider)(cp).SessionExist(context.Background(), sid)
|
||||
return res
|
||||
}
|
||||
|
||||
// SessionRegenerate remove oldsid and use sid to generate new session
|
||||
func (cp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
|
||||
s, err := (*beecb.Provider)(cp).SessionRegenerate(context.Background(), oldsid, sid)
|
||||
return session.CreateNewToOldStoreAdapter(s), err
|
||||
}
|
||||
|
||||
// SessionDestroy Remove bucket in this couchbase
|
||||
func (cp *Provider) SessionDestroy(sid string) error {
|
||||
return (*beecb.Provider)(cp).SessionDestroy(context.Background(), sid)
|
||||
}
|
||||
|
||||
// SessionGC Recycle
|
||||
func (cp *Provider) SessionGC() {
|
||||
(*beecb.Provider)(cp).SessionGC(context.Background())
|
||||
}
|
||||
|
||||
// SessionAll return all active session
|
||||
func (cp *Provider) SessionAll() int {
|
||||
return (*beecb.Provider)(cp).SessionAll(context.Background())
|
||||
}
|
86
adapter/session/ledis/ledis_session.go
Normal file
86
adapter/session/ledis/ledis_session.go
Normal file
@ -0,0 +1,86 @@
|
||||
// Package ledis provide session Provider
|
||||
package ledis
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/astaxie/beego/adapter/session"
|
||||
beeLedis "github.com/astaxie/beego/server/web/session/ledis"
|
||||
)
|
||||
|
||||
// SessionStore ledis session store
|
||||
type SessionStore beeLedis.SessionStore
|
||||
|
||||
// Set value in ledis session
|
||||
func (ls *SessionStore) Set(key, value interface{}) error {
|
||||
return (*beeLedis.SessionStore)(ls).Set(context.Background(), key, value)
|
||||
}
|
||||
|
||||
// Get value in ledis session
|
||||
func (ls *SessionStore) Get(key interface{}) interface{} {
|
||||
return (*beeLedis.SessionStore)(ls).Get(context.Background(), key)
|
||||
}
|
||||
|
||||
// Delete value in ledis session
|
||||
func (ls *SessionStore) Delete(key interface{}) error {
|
||||
return (*beeLedis.SessionStore)(ls).Delete(context.Background(), key)
|
||||
}
|
||||
|
||||
// Flush clear all values in ledis session
|
||||
func (ls *SessionStore) Flush() error {
|
||||
return (*beeLedis.SessionStore)(ls).Flush(context.Background())
|
||||
}
|
||||
|
||||
// SessionID get ledis session id
|
||||
func (ls *SessionStore) SessionID() string {
|
||||
return (*beeLedis.SessionStore)(ls).SessionID(context.Background())
|
||||
}
|
||||
|
||||
// SessionRelease save session values to ledis
|
||||
func (ls *SessionStore) SessionRelease(w http.ResponseWriter) {
|
||||
(*beeLedis.SessionStore)(ls).SessionRelease(context.Background(), w)
|
||||
}
|
||||
|
||||
// Provider ledis session provider
|
||||
type Provider beeLedis.Provider
|
||||
|
||||
// SessionInit init ledis session
|
||||
// savepath like ledis server saveDataPath,pool size
|
||||
// e.g. 127.0.0.1:6379,100,astaxie
|
||||
func (lp *Provider) SessionInit(maxlifetime int64, savePath string) error {
|
||||
return (*beeLedis.Provider)(lp).SessionInit(context.Background(), maxlifetime, savePath)
|
||||
}
|
||||
|
||||
// SessionRead read ledis session by sid
|
||||
func (lp *Provider) SessionRead(sid string) (session.Store, error) {
|
||||
s, err := (*beeLedis.Provider)(lp).SessionRead(context.Background(), sid)
|
||||
return session.CreateNewToOldStoreAdapter(s), err
|
||||
}
|
||||
|
||||
// SessionExist check ledis session exist by sid
|
||||
func (lp *Provider) SessionExist(sid string) bool {
|
||||
res, _ := (*beeLedis.Provider)(lp).SessionExist(context.Background(), sid)
|
||||
return res
|
||||
}
|
||||
|
||||
// SessionRegenerate generate new sid for ledis session
|
||||
func (lp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
|
||||
s, err := (*beeLedis.Provider)(lp).SessionRegenerate(context.Background(), oldsid, sid)
|
||||
return session.CreateNewToOldStoreAdapter(s), err
|
||||
}
|
||||
|
||||
// SessionDestroy delete ledis session by id
|
||||
func (lp *Provider) SessionDestroy(sid string) error {
|
||||
return (*beeLedis.Provider)(lp).SessionDestroy(context.Background(), sid)
|
||||
}
|
||||
|
||||
// SessionGC Impelment method, no used.
|
||||
func (lp *Provider) SessionGC() {
|
||||
(*beeLedis.Provider)(lp).SessionGC(context.Background())
|
||||
}
|
||||
|
||||
// SessionAll return all active session
|
||||
func (lp *Provider) SessionAll() int {
|
||||
return (*beeLedis.Provider)(lp).SessionAll(context.Background())
|
||||
}
|
118
adapter/session/memcache/sess_memcache.go
Normal file
118
adapter/session/memcache/sess_memcache.go
Normal file
@ -0,0 +1,118 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package memcache for session provider
|
||||
//
|
||||
// depend on github.com/bradfitz/gomemcache/memcache
|
||||
//
|
||||
// go install github.com/bradfitz/gomemcache/memcache
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/astaxie/beego/session/memcache"
|
||||
// "github.com/astaxie/beego/session"
|
||||
// )
|
||||
//
|
||||
// func init() {
|
||||
// globalSessions, _ = session.NewManager("memcache", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"127.0.0.1:11211"}``)
|
||||
// go globalSessions.GC()
|
||||
// }
|
||||
//
|
||||
// more docs: http://beego.me/docs/module/session.md
|
||||
package memcache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/astaxie/beego/adapter/session"
|
||||
|
||||
beemem "github.com/astaxie/beego/server/web/session/memcache"
|
||||
)
|
||||
|
||||
// SessionStore memcache session store
|
||||
type SessionStore beemem.SessionStore
|
||||
|
||||
// Set value in memcache session
|
||||
func (rs *SessionStore) Set(key, value interface{}) error {
|
||||
return (*beemem.SessionStore)(rs).Set(context.Background(), key, value)
|
||||
}
|
||||
|
||||
// Get value in memcache session
|
||||
func (rs *SessionStore) Get(key interface{}) interface{} {
|
||||
return (*beemem.SessionStore)(rs).Get(context.Background(), key)
|
||||
}
|
||||
|
||||
// Delete value in memcache session
|
||||
func (rs *SessionStore) Delete(key interface{}) error {
|
||||
return (*beemem.SessionStore)(rs).Delete(context.Background(), key)
|
||||
}
|
||||
|
||||
// Flush clear all values in memcache session
|
||||
func (rs *SessionStore) Flush() error {
|
||||
return (*beemem.SessionStore)(rs).Flush(context.Background())
|
||||
}
|
||||
|
||||
// SessionID get memcache session id
|
||||
func (rs *SessionStore) SessionID() string {
|
||||
return (*beemem.SessionStore)(rs).SessionID(context.Background())
|
||||
}
|
||||
|
||||
// SessionRelease save session values to memcache
|
||||
func (rs *SessionStore) SessionRelease(w http.ResponseWriter) {
|
||||
(*beemem.SessionStore)(rs).SessionRelease(context.Background(), w)
|
||||
}
|
||||
|
||||
// MemProvider memcache session provider
|
||||
type MemProvider beemem.MemProvider
|
||||
|
||||
// SessionInit init memcache session
|
||||
// savepath like
|
||||
// e.g. 127.0.0.1:9090
|
||||
func (rp *MemProvider) SessionInit(maxlifetime int64, savePath string) error {
|
||||
return (*beemem.MemProvider)(rp).SessionInit(context.Background(), maxlifetime, savePath)
|
||||
}
|
||||
|
||||
// SessionRead read memcache session by sid
|
||||
func (rp *MemProvider) SessionRead(sid string) (session.Store, error) {
|
||||
s, err := (*beemem.MemProvider)(rp).SessionRead(context.Background(), sid)
|
||||
return session.CreateNewToOldStoreAdapter(s), err
|
||||
}
|
||||
|
||||
// SessionExist check memcache session exist by sid
|
||||
func (rp *MemProvider) SessionExist(sid string) bool {
|
||||
res, _ := (*beemem.MemProvider)(rp).SessionExist(context.Background(), sid)
|
||||
return res
|
||||
}
|
||||
|
||||
// SessionRegenerate generate new sid for memcache session
|
||||
func (rp *MemProvider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
|
||||
s, err := (*beemem.MemProvider)(rp).SessionRegenerate(context.Background(), oldsid, sid)
|
||||
return session.CreateNewToOldStoreAdapter(s), err
|
||||
}
|
||||
|
||||
// SessionDestroy delete memcache session by id
|
||||
func (rp *MemProvider) SessionDestroy(sid string) error {
|
||||
return (*beemem.MemProvider)(rp).SessionDestroy(context.Background(), sid)
|
||||
}
|
||||
|
||||
// SessionGC Impelment method, no used.
|
||||
func (rp *MemProvider) SessionGC() {
|
||||
(*beemem.MemProvider)(rp).SessionGC(context.Background())
|
||||
}
|
||||
|
||||
// SessionAll return all activeSession
|
||||
func (rp *MemProvider) SessionAll() int {
|
||||
return (*beemem.MemProvider)(rp).SessionAll(context.Background())
|
||||
}
|
135
adapter/session/mysql/sess_mysql.go
Normal file
135
adapter/session/mysql/sess_mysql.go
Normal file
@ -0,0 +1,135 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package mysql for session provider
|
||||
//
|
||||
// depends on github.com/go-sql-driver/mysql:
|
||||
//
|
||||
// go install github.com/go-sql-driver/mysql
|
||||
//
|
||||
// mysql session support need create table as sql:
|
||||
// CREATE TABLE `session` (
|
||||
// `session_key` char(64) NOT NULL,
|
||||
// `session_data` blob,
|
||||
// `session_expiry` int(11) unsigned NOT NULL,
|
||||
// PRIMARY KEY (`session_key`)
|
||||
// ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/astaxie/beego/session/mysql"
|
||||
// "github.com/astaxie/beego/session"
|
||||
// )
|
||||
//
|
||||
// func init() {
|
||||
// globalSessions, _ = session.NewManager("mysql", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...¶mN=valueN]"}``)
|
||||
// go globalSessions.GC()
|
||||
// }
|
||||
//
|
||||
// more docs: http://beego.me/docs/module/session.md
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/astaxie/beego/adapter/session"
|
||||
"github.com/astaxie/beego/server/web/session/mysql"
|
||||
|
||||
// import mysql driver
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
)
|
||||
|
||||
var (
|
||||
// TableName store the session in MySQL
|
||||
TableName = mysql.TableName
|
||||
mysqlpder = &Provider{}
|
||||
)
|
||||
|
||||
// SessionStore mysql session store
|
||||
type SessionStore mysql.SessionStore
|
||||
|
||||
// Set value in mysql session.
|
||||
// it is temp value in map.
|
||||
func (st *SessionStore) Set(key, value interface{}) error {
|
||||
return (*mysql.SessionStore)(st).Set(context.Background(), key, value)
|
||||
}
|
||||
|
||||
// Get value from mysql session
|
||||
func (st *SessionStore) Get(key interface{}) interface{} {
|
||||
return (*mysql.SessionStore)(st).Get(context.Background(), key)
|
||||
}
|
||||
|
||||
// Delete value in mysql session
|
||||
func (st *SessionStore) Delete(key interface{}) error {
|
||||
return (*mysql.SessionStore)(st).Delete(context.Background(), key)
|
||||
}
|
||||
|
||||
// Flush clear all values in mysql session
|
||||
func (st *SessionStore) Flush() error {
|
||||
return (*mysql.SessionStore)(st).Flush(context.Background())
|
||||
}
|
||||
|
||||
// SessionID get session id of this mysql session store
|
||||
func (st *SessionStore) SessionID() string {
|
||||
return (*mysql.SessionStore)(st).SessionID(context.Background())
|
||||
}
|
||||
|
||||
// SessionRelease save mysql session values to database.
|
||||
// must call this method to save values to database.
|
||||
func (st *SessionStore) SessionRelease(w http.ResponseWriter) {
|
||||
(*mysql.SessionStore)(st).SessionRelease(context.Background(), w)
|
||||
}
|
||||
|
||||
// Provider mysql session provider
|
||||
type Provider mysql.Provider
|
||||
|
||||
// SessionInit init mysql session.
|
||||
// savepath is the connection string of mysql.
|
||||
func (mp *Provider) SessionInit(maxlifetime int64, savePath string) error {
|
||||
return (*mysql.Provider)(mp).SessionInit(context.Background(), maxlifetime, savePath)
|
||||
}
|
||||
|
||||
// SessionRead get mysql session by sid
|
||||
func (mp *Provider) SessionRead(sid string) (session.Store, error) {
|
||||
s, err := (*mysql.Provider)(mp).SessionRead(context.Background(), sid)
|
||||
return session.CreateNewToOldStoreAdapter(s), err
|
||||
}
|
||||
|
||||
// SessionExist check mysql session exist
|
||||
func (mp *Provider) SessionExist(sid string) bool {
|
||||
res, _ := (*mysql.Provider)(mp).SessionExist(context.Background(), sid)
|
||||
return res
|
||||
}
|
||||
|
||||
// SessionRegenerate generate new sid for mysql session
|
||||
func (mp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
|
||||
s, err := (*mysql.Provider)(mp).SessionRegenerate(context.Background(), oldsid, sid)
|
||||
return session.CreateNewToOldStoreAdapter(s), err
|
||||
}
|
||||
|
||||
// SessionDestroy delete mysql session by sid
|
||||
func (mp *Provider) SessionDestroy(sid string) error {
|
||||
return (*mysql.Provider)(mp).SessionDestroy(context.Background(), sid)
|
||||
}
|
||||
|
||||
// SessionGC delete expired values in mysql session
|
||||
func (mp *Provider) SessionGC() {
|
||||
(*mysql.Provider)(mp).SessionGC(context.Background())
|
||||
}
|
||||
|
||||
// SessionAll count values in mysql session
|
||||
func (mp *Provider) SessionAll() int {
|
||||
return (*mysql.Provider)(mp).SessionAll(context.Background())
|
||||
}
|
139
adapter/session/postgres/sess_postgresql.go
Normal file
139
adapter/session/postgres/sess_postgresql.go
Normal file
@ -0,0 +1,139 @@
|
||||
// Copyright 2014 beego Author. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package postgres for session provider
|
||||
//
|
||||
// depends on github.com/lib/pq:
|
||||
//
|
||||
// go install github.com/lib/pq
|
||||
//
|
||||
//
|
||||
// needs this table in your database:
|
||||
//
|
||||
// CREATE TABLE session (
|
||||
// session_key char(64) NOT NULL,
|
||||
// session_data bytea,
|
||||
// session_expiry timestamp NOT NULL,
|
||||
// CONSTRAINT session_key PRIMARY KEY(session_key)
|
||||
// );
|
||||
//
|
||||
// will be activated with these settings in app.conf:
|
||||
//
|
||||
// SessionOn = true
|
||||
// SessionProvider = postgresql
|
||||
// SessionSavePath = "user=a password=b dbname=c sslmode=disable"
|
||||
// SessionName = session
|
||||
//
|
||||
//
|
||||
// Usage:
|
||||
// import(
|
||||
// _ "github.com/astaxie/beego/session/postgresql"
|
||||
// "github.com/astaxie/beego/session"
|
||||
// )
|
||||
//
|
||||
// func init() {
|
||||
// globalSessions, _ = session.NewManager("postgresql", ``{"cookieName":"gosessionid","gclifetime":3600,"ProviderConfig":"user=pqgotest dbname=pqgotest sslmode=verify-full"}``)
|
||||
// go globalSessions.GC()
|
||||
// }
|
||||
//
|
||||
// more docs: http://beego.me/docs/module/session.md
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/astaxie/beego/adapter/session"
|
||||
// import postgresql Driver
|
||||
_ "github.com/lib/pq"
|
||||
|
||||
"github.com/astaxie/beego/server/web/session/postgres"
|
||||
)
|
||||
|
||||
// SessionStore postgresql session store
|
||||
type SessionStore postgres.SessionStore
|
||||
|
||||
// Set value in postgresql session.
|
||||
// it is temp value in map.
|
||||
func (st *SessionStore) Set(key, value interface{}) error {
|
||||
return (*postgres.SessionStore)(st).Set(context.Background(), key, value)
|
||||
}
|
||||
|
||||
// Get value from postgresql session
|
||||
func (st *SessionStore) Get(key interface{}) interface{} {
|
||||
return (*postgres.SessionStore)(st).Get(context.Background(), key)
|
||||
}
|
||||
|
||||
// Delete value in postgresql session
|
||||
func (st *SessionStore) Delete(key interface{}) error {
|
||||
return (*postgres.SessionStore)(st).Delete(context.Background(), key)
|
||||
}
|
||||
|
||||
// Flush clear all values in postgresql session
|
||||
func (st *SessionStore) Flush() error {
|
||||
return (*postgres.SessionStore)(st).Flush(context.Background())
|
||||
}
|
||||
|
||||
// SessionID get session id of this postgresql session store
|
||||
func (st *SessionStore) SessionID() string {
|
||||
return (*postgres.SessionStore)(st).SessionID(context.Background())
|
||||
}
|
||||
|
||||
// SessionRelease save postgresql session values to database.
|
||||
// must call this method to save values to database.
|
||||
func (st *SessionStore) SessionRelease(w http.ResponseWriter) {
|
||||
(*postgres.SessionStore)(st).SessionRelease(context.Background(), w)
|
||||
}
|
||||
|
||||
// Provider postgresql session provider
|
||||
type Provider postgres.Provider
|
||||
|
||||
// SessionInit init postgresql session.
|
||||
// savepath is the connection string of postgresql.
|
||||
func (mp *Provider) SessionInit(maxlifetime int64, savePath string) error {
|
||||
return (*postgres.Provider)(mp).SessionInit(context.Background(), maxlifetime, savePath)
|
||||
}
|
||||
|
||||
// SessionRead get postgresql session by sid
|
||||
func (mp *Provider) SessionRead(sid string) (session.Store, error) {
|
||||
s, err := (*postgres.Provider)(mp).SessionRead(context.Background(), sid)
|
||||
return session.CreateNewToOldStoreAdapter(s), err
|
||||
}
|
||||
|
||||
// SessionExist check postgresql session exist
|
||||
func (mp *Provider) SessionExist(sid string) bool {
|
||||
res, _ := (*postgres.Provider)(mp).SessionExist(context.Background(), sid)
|
||||
return res
|
||||
}
|
||||
|
||||
// SessionRegenerate generate new sid for postgresql session
|
||||
func (mp *Provider) SessionRegenerate(oldsid, sid string) (session.Store, error) {
|
||||
s, err := (*postgres.Provider)(mp).SessionRegenerate(context.Background(), oldsid, sid)
|
||||
return session.CreateNewToOldStoreAdapter(s), err
|
||||
}
|
||||
|
||||
// SessionDestroy delete postgresql session by sid
|
||||
func (mp *Provider) SessionDestroy(sid string) error {
|
||||
return (*postgres.Provider)(mp).SessionDestroy(context.Background(), sid)
|
||||
}
|
||||
|
||||
// SessionGC delete expired values in postgresql session
|
||||
func (mp *Provider) SessionGC() {
|
||||
(*postgres.Provider)(mp).SessionGC(context.Background())
|
||||
}
|
||||
|
||||
// SessionAll count values in postgresql session
|
||||
func (mp *Provider) SessionAll() int {
|
||||
return (*postgres.Provider)(mp).SessionAll(context.Background())
|
||||
}
|
104
adapter/session/provider_adapter.go
Normal file
104
adapter/session/provider_adapter.go
Normal file
@ -0,0 +1,104 @@
|
||||
// Copyright 2020
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package session
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/astaxie/beego/server/web/session"
|
||||
)
|
||||
|
||||
type oldToNewProviderAdapter struct {
|
||||
delegate Provider
|
||||
}
|
||||
|
||||
func (o *oldToNewProviderAdapter) SessionInit(ctx context.Context, gclifetime int64, config string) error {
|
||||
return o.delegate.SessionInit(gclifetime, config)
|
||||
}
|
||||
|
||||
func (o *oldToNewProviderAdapter) SessionRead(ctx context.Context, sid string) (session.Store, error) {
|
||||
store, err := o.delegate.SessionRead(sid)
|
||||
return &oldToNewStoreAdapter{
|
||||
delegate: store,
|
||||
}, err
|
||||
}
|
||||
|
||||
func (o *oldToNewProviderAdapter) SessionExist(ctx context.Context, sid string) (bool, error) {
|
||||
return o.delegate.SessionExist(sid), nil
|
||||
}
|
||||
|
||||
func (o *oldToNewProviderAdapter) SessionRegenerate(ctx context.Context, oldsid, sid string) (session.Store, error) {
|
||||
s, err := o.delegate.SessionRegenerate(oldsid, sid)
|
||||
return &oldToNewStoreAdapter{
|
||||
delegate: s,
|
||||
}, err
|
||||
}
|
||||
|
||||
func (o *oldToNewProviderAdapter) SessionDestroy(ctx context.Context, sid string) error {
|
||||
return o.delegate.SessionDestroy(sid)
|
||||
}
|
||||
|
||||
func (o *oldToNewProviderAdapter) SessionAll(ctx context.Context) int {
|
||||
return o.delegate.SessionAll()
|
||||
}
|
||||
|
||||
func (o *oldToNewProviderAdapter) SessionGC(ctx context.Context) {
|
||||
o.delegate.SessionGC()
|
||||
}
|
||||
|
||||
type newToOldProviderAdapter struct {
|
||||
delegate session.Provider
|
||||
}
|
||||
|
||||
func (n *newToOldProviderAdapter) SessionInit(gclifetime int64, config string) error {
|
||||
return n.delegate.SessionInit(context.Background(), gclifetime, config)
|
||||
}
|
||||
|
||||
func (n *newToOldProviderAdapter) SessionRead(sid string) (Store, error) {
|
||||
s, err := n.delegate.SessionRead(context.Background(), sid)
|
||||
if adt, ok := s.(*oldToNewStoreAdapter); err == nil && ok {
|
||||
return adt.delegate, err
|
||||
}
|
||||
return &NewToOldStoreAdapter{
|
||||
delegate: s,
|
||||
}, err
|
||||
}
|
||||
|
||||
func (n *newToOldProviderAdapter) SessionExist(sid string) bool {
|
||||
res, _ := n.delegate.SessionExist(context.Background(), sid)
|
||||
return res
|
||||
}
|
||||
|
||||
func (n *newToOldProviderAdapter) SessionRegenerate(oldsid, sid string) (Store, error) {
|
||||
s, err := n.delegate.SessionRegenerate(context.Background(), oldsid, sid)
|
||||
if adt, ok := s.(*oldToNewStoreAdapter); err == nil && ok {
|
||||
return adt.delegate, err
|
||||
}
|
||||
return &NewToOldStoreAdapter{
|
||||
delegate: s,
|
||||
}, err
|
||||
}
|
||||
|
||||
func (n *newToOldProviderAdapter) SessionDestroy(sid string) error {
|
||||
return n.delegate.SessionDestroy(context.Background(), sid)
|
||||
}
|
||||
|
||||
func (n *newToOldProviderAdapter) SessionAll() int {
|
||||
return n.delegate.SessionAll(context.Background())
|
||||
}
|
||||
|
||||
func (n *newToOldProviderAdapter) SessionGC() {
|
||||
n.delegate.SessionGC(context.Background())
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user