mirror of
https://github.com/documize/community.git
synced 2025-08-08 06:55:28 +02:00
Compare commits
794 commits
Author | SHA1 | Date | |
---|---|---|---|
|
efb092ef8f | ||
|
3fc0a15f87 | ||
|
c841c85478 | ||
|
2dae03332b | ||
|
44b1f263cd | ||
|
982e16737e | ||
|
f641e42434 | ||
|
8895db56af | ||
|
acb59e1b43 | ||
|
f2ba294be8 | ||
|
69940cb7f1 | ||
|
6bfdda7178 | ||
|
027fdf108c | ||
|
1f12df76aa | ||
|
d811b88896 | ||
|
20fb853907 | ||
|
599c53a971 | ||
|
1f462ed4f7 | ||
|
9f122fa79b | ||
|
4210caca48 | ||
|
c62fa4612b | ||
|
510e1bd0bd | ||
|
a32510b8e6 | ||
|
589f3f581f | ||
|
20bba4cd7e | ||
|
cbf5f4be7d | ||
|
dc63639c99 | ||
|
26f435bdc9 | ||
|
a8a82963fa | ||
|
ab8582e807 | ||
|
4fa0566274 | ||
|
f4b45d2aa7 | ||
|
1abc5d3e52 | ||
|
6e463ff2f4 | ||
|
f80b3f3d10 | ||
|
6c218cf087 | ||
|
3d1c8a6c54 | ||
|
576fd5e604 | ||
|
62407a28b4 | ||
|
0adf6d5dc8 | ||
|
15f8a64c86 | ||
|
95c67acaa0 | ||
|
d8f66b5ffb | ||
|
c051e81a99 | ||
|
1d86b98949 | ||
|
0a1cc86907 | ||
|
a49869d35d | ||
|
848afd3263 | ||
|
b9cb99e3bb | ||
|
64261ffcf5 | ||
|
0030418707 | ||
|
0f91ee518e | ||
|
5de1b7a92e | ||
|
a2524f785e | ||
|
f16b9f3810 | ||
|
1c09771c33 | ||
|
13fc5b5015 | ||
|
76c777acc1 | ||
|
ea9ff78411 | ||
|
4a9dd47894 | ||
|
7565779ef1 | ||
|
c07e7b6afc | ||
|
88bdafcb1b | ||
|
5a3cb1b226 | ||
|
6ee8e6c7b4 | ||
|
599c464d2d | ||
|
ae77fa2275 | ||
|
610367aac5 | ||
|
be2c2a7a2c | ||
|
0d28b7ee79 | ||
|
aa8b473018 | ||
|
6993dc678f | ||
|
e0e3f0c141 | ||
|
4c031fe7e4 | ||
|
e4025bee42 | ||
|
876775b395 | ||
|
828c01d189 | ||
|
a69bcc0af6 | ||
|
5ec911dce2 | ||
|
ce07d4d147 | ||
|
f3ef83162e | ||
|
f1a01ec195 | ||
|
01e53c3d27 | ||
|
2cf21a7bea | ||
|
d4c606760c | ||
|
9343d77b26 | ||
|
30aa8aadb6 | ||
|
29bc2677a8 | ||
|
d9827df440 | ||
|
cfd7ebd2bf | ||
|
b510615691 | ||
|
e8641405cf | ||
|
209f1b667e | ||
|
e70019d73b | ||
|
dc26f063c8 | ||
|
68d067ef7b | ||
|
0d52f434d5 | ||
|
ce22c78dac | ||
|
f976ea36f6 | ||
|
1734963693 | ||
|
247a2b2c03 | ||
|
38a790dd04 | ||
|
b77b4abdc2 | ||
|
6b498a74c6 | ||
|
f6dd872782 | ||
|
9473ecba9a | ||
|
1a909dd046 | ||
|
607a2d5797 | ||
|
037dfc40cd | ||
|
65348eee28 | ||
|
78932fb8c7 | ||
|
6c8b10753d | ||
|
e56263564c | ||
|
22b6a4fb78 | ||
|
7e26c003d6 | ||
|
e81cbad385 | ||
|
4494ace0a2 | ||
|
23abcf1585 | ||
|
67070c3bfc | ||
|
77c767a351 | ||
|
17162ce336 | ||
|
7255eb4f56 | ||
|
df534f72fa | ||
|
f4a1350a41 | ||
|
cd15c393fe | ||
|
7f66977ac1 | ||
|
33a9cbb5b0 | ||
|
716343680a | ||
|
5db5f4d63b | ||
|
3d3d50762e | ||
|
20c9168140 | ||
|
ce9c635fb4 | ||
|
f735ae1278 | ||
|
bca7794c00 | ||
|
371706fb49 | ||
|
a236cbb01c | ||
|
93b6f26365 | ||
|
5e687f5ef4 | ||
|
97c4c927ac | ||
|
4885a1b380 | ||
|
e0805d7131 | ||
|
6d735e8579 | ||
|
073ef81e80 | ||
|
38c9a94a9c | ||
|
59dc6ea991 | ||
|
4ab48cc67d | ||
|
53297f7627 | ||
|
4ed2b3902c | ||
|
6968581e5b | ||
|
c09a116e56 | ||
|
7cf672646a | ||
|
29447a2784 | ||
|
479d03ba70 | ||
|
a7dac6911c | ||
|
08f21346c1 | ||
|
ce4f62d346 | ||
|
8a25509019 | ||
|
59c929d251 | ||
|
245c538990 | ||
|
32a9528e6d | ||
|
a15f0c8eb6 | ||
|
eb9fbd25b9 | ||
|
dbef758035 | ||
|
dea25a2b85 | ||
|
fcf38d8af9 | ||
|
ce93a5e623 | ||
|
8df1cc73b0 | ||
|
53ec7c9274 | ||
|
cfe85248ce | ||
|
30c31a1ba7 | ||
|
a97b6b22d9 | ||
|
e985c5f808 | ||
|
4b89f3b1c2 | ||
|
707dc1e052 | ||
|
88211739f0 | ||
|
6b3cdb5033 | ||
|
45f216b8a1 | ||
|
c31c130ffd | ||
|
5d5e212a6b | ||
|
8fa5569ae5 | ||
|
8976bf817b | ||
|
0c3fed2b18 | ||
|
60dfb54d54 | ||
|
c6863201b3 | ||
|
45567e274a | ||
|
dff4c6929b | ||
|
eea8db9288 | ||
|
e19c4ad18a | ||
|
989b7cd62c | ||
|
df8f650319 | ||
|
565a063231 | ||
|
cb46f34503 | ||
|
470e2d3ecf | ||
|
cddba799f8 | ||
|
05df22ed4a | ||
|
a5dfa6ee39 | ||
|
780ce2df61 | ||
|
9f28e1bff2 | ||
|
8ae94295a2 | ||
|
adb7b4d7bf | ||
|
66fcb77d8b | ||
|
972413110f | ||
|
a0a166136e | ||
|
30d12ba756 | ||
|
06bf9efcfc | ||
|
9ed8f79315 | ||
|
73e8c7a278 | ||
|
806efd7eac | ||
|
724f3c88b3 | ||
|
4a7d915ebb | ||
|
c7413da943 | ||
|
4e0218f5ea | ||
|
4fe022aa0c | ||
|
aaa8c3282d | ||
|
5e022dd0b8 | ||
|
bbca180298 | ||
|
cdc7489659 | ||
|
ab95fcc64d | ||
|
9bee58057e | ||
|
bda9719ecb | ||
|
fbd4b17c15 | ||
|
c689379f92 | ||
|
d1774b42bd | ||
|
8ac35a6b74 | ||
|
813f270a9d | ||
|
e014f5b5c1 | ||
|
2b66d0096a | ||
|
50f47f61a5 | ||
|
d26ecdc12f | ||
|
1a89201bd9 | ||
|
accf0a2c63 | ||
|
cafa3ceed0 | ||
|
2b3e9dfbc9 | ||
|
1c1ebee15a | ||
|
6ba4ca9c16 | ||
|
5aaa9f874d | ||
|
51a25adbdb | ||
|
9d025c3f71 | ||
|
a4384210d4 | ||
|
6882491201 | ||
|
d4edcb8b2c | ||
|
f117e91bcb | ||
|
5c1ad25dc9 | ||
|
8970a21b58 | ||
|
0e6f2f1f5e | ||
|
7fc74be7cd | ||
|
faeadb2bbb | ||
|
be50bf9f14 | ||
|
60ef205948 | ||
|
7ae801554d | ||
|
441efd42e9 | ||
|
a19ba46f7a | ||
|
ad361c22ba | ||
|
7954f4b976 | ||
|
2d105f2154 | ||
|
811e239baf | ||
|
c7e71173ea | ||
|
8fa8a3657c | ||
|
a64a219ce8 | ||
|
d7a484a936 | ||
|
017b19141c | ||
|
39f457e90e | ||
|
30d3e6f82e | ||
|
8c2bed283f | ||
|
a3867c617a | ||
|
28424e7e4b | ||
|
7c70274f5e | ||
|
ef5b5cdb32 | ||
|
ccd756aca0 | ||
|
444b89e425 | ||
|
3d0f17386b | ||
|
513fd9f994 | ||
|
5cef58eeba | ||
|
fad1de2e41 | ||
|
6b723568d3 | ||
|
00889f0e0e | ||
|
6629d76453 | ||
|
74300b009b | ||
|
5004e5a85e | ||
|
0524a0c74c | ||
|
b826852137 | ||
|
2c164a135a | ||
|
44febcc25c | ||
|
66e11cefbc | ||
|
5e9eeb5bf9 | ||
|
5b7610d726 | ||
|
0419f3b7b3 | ||
|
5b72da037c | ||
|
d14e8a3ff6 | ||
|
9a3d2c3c28 | ||
|
3b76e10ee0 | ||
|
29d7307537 | ||
|
96e5812fc0 | ||
|
c35eb16fc5 | ||
|
9dd78ca9be | ||
|
891ba07db8 | ||
|
2ee9a9ff46 | ||
|
399c36611f | ||
|
fbb73560c0 | ||
|
15e687841f | ||
|
0a10087160 | ||
|
9d0d4a7861 | ||
|
fc60a5917e | ||
|
285a01508b | ||
|
4f248bf018 | ||
|
32dbab826d | ||
|
b6e1543b7f | ||
|
f8bb879a70 | ||
|
20366e6776 | ||
|
ffacf17c5f | ||
|
bfe4c5d768 | ||
|
0f3a618140 | ||
|
826f6d96a6 | ||
|
6a9fa0140a | ||
|
24619c6a58 | ||
|
ebc8214049 | ||
|
71c1def5c7 | ||
|
fded0014a3 | ||
|
041091504f | ||
|
8c2df6178d | ||
|
02d478c6dd | ||
|
8c99977fc9 | ||
|
9d6b6fec23 | ||
|
4e0e3b5101 | ||
|
e219c97a6b | ||
|
7485f2cef7 | ||
|
627195aae7 | ||
|
f39be2a594 | ||
|
444b4fd1f7 | ||
|
b31f330c41 | ||
|
69077ce419 | ||
|
201d2a339c | ||
|
326019d655 | ||
|
264c25cfe0 | ||
|
595301db64 | ||
|
d6432afdad | ||
|
9c36241b58 | ||
|
c538fc9eb1 | ||
|
f3df43efe0 | ||
|
d04becc1a3 | ||
|
3621e2fb79 | ||
|
411f64c359 | ||
|
ae923e7df1 | ||
|
bfe5262cb5 | ||
|
80f0876b51 | ||
|
b2cd375936 | ||
|
243a170071 | ||
|
fb3f2cc24b | ||
|
946c433018 | ||
|
4d2f30711c | ||
|
887c999a1e | ||
|
b256bf2e9d | ||
|
8f4cd755de | ||
|
64612b825a | ||
|
216866a953 | ||
|
14820df165 | ||
|
f7a738ad84 | ||
|
df2775f8a4 | ||
|
a710839f69 | ||
|
2a45c82b46 | ||
|
7eec01811a | ||
|
ef5e4db298 | ||
|
b1cb0ed155 | ||
|
78fd14b3d3 | ||
|
82ddcc057d | ||
|
a90c5834fa | ||
|
ec8d5c78e2 | ||
|
b75969ae90 | ||
|
9b82f42cc1 | ||
|
b8fee6b962 | ||
|
8baad7e2f0 | ||
|
99a5418dba | ||
|
acd3dd63b5 | ||
|
96872990f9 | ||
|
c59a467cdb | ||
|
715c31a1da | ||
|
40237344e2 | ||
|
91a3c59cd2 | ||
|
fe7548cd97 | ||
|
ca4a9a74ee | ||
|
1e1cbdd843 | ||
|
c8b82c85fe | ||
|
bae7909801 | ||
|
c870547fa1 | ||
|
c0876e7be8 | ||
|
cd9f681adf | ||
|
0240f98eb0 | ||
|
c49707d160 | ||
|
c65eb97948 | ||
|
bc9dab72f2 | ||
|
6ae9414361 | ||
|
e37782e5b7 | ||
|
2bbeaf91a0 | ||
|
de273a38ed | ||
|
08794f8d5f | ||
|
14f313a836 | ||
|
62c3cd03ad | ||
|
bce1c1b166 | ||
|
758bf07272 | ||
|
479508e436 | ||
|
49bf4eeaa0 | ||
|
1c45aef461 | ||
|
a988bc0c3c | ||
|
91ec2f89d8 | ||
|
2477c36f11 | ||
|
e2a3962092 | ||
|
8ecbb9cdee | ||
|
f738077f5a | ||
|
f17de58fff | ||
|
40a0d77f93 | ||
|
072ca0dfed | ||
|
b054addb9c | ||
|
e59e1f060a | ||
|
faf9a555d2 | ||
|
8ab3cbe7e8 | ||
|
86d25b2191 | ||
|
9a53958c8f | ||
|
b971c52469 | ||
|
34d1639899 | ||
|
1fefdaec9f | ||
|
8f1bc8ce1f | ||
|
d151555597 | ||
|
4255291223 | ||
|
86a4e82c12 | ||
|
daa9e08ab4 | ||
|
c666e68c2b | ||
|
e6e3ed71ac | ||
|
89a28ad22f | ||
|
8e4ad6422b | ||
|
4de83beba4 | ||
|
10c57a0ae1 | ||
|
728789195c | ||
|
b5cd378302 | ||
|
7fde947a52 | ||
|
61d0086337 | ||
|
166aeba09b | ||
|
c0ed3c3d04 | ||
|
ab5314d5e1 | ||
|
51a0e1127e | ||
|
e10d04d22e | ||
|
2fffb7869e | ||
|
82ed36478b | ||
|
1da49974cb | ||
|
9e3eac19aa | ||
|
92696c5181 | ||
|
eecf316d50 | ||
|
fa383a58ff | ||
|
b5a5cfd697 | ||
|
2ddd7ada9b | ||
|
8515a77403 | ||
|
f8d97d2a56 | ||
|
e98f7b9218 | ||
|
a41f43c380 | ||
|
64403c402b | ||
|
9ec858286f | ||
|
80aab3ce99 | ||
|
deb579d8ad | ||
|
e6335dd58c | ||
|
e1a8f8b724 | ||
|
e1001bb11e | ||
|
dbee77df56 | ||
|
9c2bff0374 | ||
|
651cbb1dfe | ||
|
a98c3a0fe2 | ||
|
a08b583b22 | ||
|
6738d2c9e1 | ||
|
441001fffe | ||
|
a4e07fbf7f | ||
|
9a41e82aa3 | ||
|
b89a297c70 | ||
|
ca1e281775 | ||
|
c5fc0f93e0 | ||
|
217e8a3a29 | ||
|
1854998c80 | ||
|
f4a371357e | ||
|
1d00f8ac6e | ||
|
0985dbf5b6 | ||
|
b2fcad649e | ||
|
f062005946 | ||
|
36d7136210 | ||
|
0bfde82040 | ||
|
e6e5f75ee7 | ||
|
eb9501014d | ||
|
e35639502d | ||
|
3db4981181 | ||
|
3206eb4176 | ||
|
576e1beade | ||
|
54eefc5132 | ||
|
fbb1e334f8 | ||
|
bb73655327 | ||
|
8c2febd636 | ||
|
395008d06d | ||
|
d009e4ed2a | ||
|
54bf258c61 | ||
|
8332e8a03d | ||
|
a6f8be2928 | ||
|
cbd9fddcfe | ||
|
4013b5ca03 | ||
|
24b1326c31 | ||
|
566807bc14 | ||
|
df8e843bf5 | ||
|
4d0de69489 | ||
|
25c247e99b | ||
|
ed99b0c9f3 | ||
|
8b0bb456d9 | ||
|
e438542cab | ||
|
553c17181e | ||
|
9b06ddecb5 | ||
|
3fd1d793a3 | ||
|
fc17ea5225 | ||
|
f47f09661f | ||
|
4b7d4cf872 | ||
|
c108d0eb30 | ||
|
1f5221ffa0 | ||
|
a888b12ad1 | ||
|
2510972a83 | ||
|
560f786b8b | ||
|
af641b93f1 | ||
|
f4fa63359f | ||
|
f828583b49 | ||
|
af9bc25660 | ||
|
66003dac21 | ||
|
d4f6694933 | ||
|
27030a0dc2 | ||
|
43f515a1f9 | ||
|
9aaea9492a | ||
|
ac84eaf85d | ||
|
9504a8cf6c | ||
|
fbe353475c | ||
|
bbed3e5a08 | ||
|
9f4715a494 | ||
|
d8cb69b6c0 | ||
|
7f2d2c01a6 | ||
|
f3e66b73c1 | ||
|
02ffaa5f99 | ||
|
9219dd9296 | ||
|
5faf6bda9b | ||
|
89a7496c7f | ||
|
c0c3ca18e2 | ||
|
2e443de84e | ||
|
9b51d9990f | ||
|
278572c49b | ||
|
1e217274c6 | ||
|
9fd002b5da | ||
|
f5bdbb49d0 | ||
|
c69020f1e6 | ||
|
0707bdd3d6 | ||
|
36634be6f5 | ||
|
6c71a1f18d | ||
|
6126d4dd5d | ||
|
013d09dda4 | ||
|
c6632fec1d | ||
|
e8735ffc12 | ||
|
c5155da74b | ||
|
e737339090 | ||
|
4f63a32ab1 | ||
|
7cc0b9c9b8 | ||
|
560d00322f | ||
|
b6d9c54667 | ||
|
6c07d2e569 | ||
|
924b707db0 | ||
|
3da4144c1b | ||
|
1ef209b74f | ||
|
d281621d90 | ||
|
d05052a5b4 | ||
|
317e9cbcaa | ||
|
2efd239d14 | ||
|
984aa854e5 | ||
|
ca213ba5d1 | ||
|
c1d796e6bc | ||
|
60fbdfda11 | ||
|
659eb99c0f | ||
|
bc28b36627 | ||
|
f73c2f13d4 | ||
|
0ce10ae5a2 | ||
|
a1d5dcaed9 | ||
|
3beb47fd49 | ||
|
aa0f76d3e2 | ||
|
479a61a3ef | ||
|
c706edec47 | ||
|
5467771542 | ||
|
1d4a20cdfe | ||
|
1b268d42de | ||
|
4ddbe59556 | ||
|
a424bbfcae | ||
|
fb391d49a5 | ||
|
9206e9aaa1 | ||
|
e6ddb1ec24 | ||
|
0b94d55fb9 | ||
|
4d83f5efd7 | ||
|
dd355958a2 | ||
|
90aa9710a6 | ||
|
036f36ba1d | ||
|
a211ba051a | ||
|
fe8068965c | ||
|
5757b2d36e | ||
|
3d0a3cecf9 | ||
|
eb56169fe5 | ||
|
6f495dd1c6 | ||
|
b495041222 | ||
|
92cb03a1db | ||
|
60f8cb7b5b | ||
|
60d2ef57bb | ||
|
61c648a7ac | ||
|
d0f0a12f2d | ||
|
89957c8278 | ||
|
e140caff55 | ||
|
3c81297fc6 | ||
|
2042454e77 | ||
|
329c43eba0 | ||
|
93253be0f2 | ||
|
3d2060ca60 | ||
|
7cdf97aa86 | ||
|
b4b3dbcb4c | ||
|
60e92b63a9 | ||
|
d5b5e015d1 | ||
|
0cc83c13c8 | ||
|
42db78ce14 | ||
|
05a1db9d8a | ||
|
9f35cbb64a | ||
|
d1bc4a5b4c | ||
|
8a654fcf3d | ||
|
0ec0c65002 | ||
|
edb256e754 | ||
|
ff1d737c68 | ||
|
8d525ce733 | ||
|
f442081a41 | ||
|
02102f9bf3 | ||
|
6eb68f84e0 | ||
|
f140e7ef77 | ||
|
adbd00bdd7 | ||
|
c7808d0b5a | ||
|
cf263a4f6a | ||
|
70a3b5915c | ||
|
5cfbf07e55 | ||
|
4b68529090 | ||
|
44d3e40663 | ||
|
0de7efdf20 | ||
|
3b179d5bc0 | ||
|
75a19a80f9 | ||
|
f05a6fc999 | ||
|
f44cda66e6 | ||
|
d7a46ceee6 | ||
|
da0861b3fd | ||
|
34d54745f3 | ||
|
679049d2b1 | ||
|
11e164496b | ||
|
a7e52809dc | ||
|
7428199fdd | ||
|
d499888cfd | ||
|
c152d029f2 | ||
|
5d632712e0 | ||
|
09635b67ab | ||
|
73d91a2dae | ||
|
5153d49ad7 | ||
|
b1865b2318 | ||
|
7e959b448c | ||
|
b37f9d601f | ||
|
0a313be1de | ||
|
1d8bb2d3ad | ||
|
3913995dd0 | ||
|
5e58b56182 | ||
|
cb9fd0940d | ||
|
4df1574663 | ||
|
77ab56dbf8 | ||
|
c0e1bd5045 | ||
|
0a64afd6b5 | ||
|
6a9ad7f540 | ||
|
d1b803b246 | ||
|
745e610bcb | ||
|
db78d75489 | ||
|
e116d3b000 | ||
|
6e4c5194e2 | ||
|
eb57cfbfd6 | ||
|
cccf160d37 | ||
|
4b543733e7 | ||
|
8cc6bf3d40 | ||
|
9c6075c6a4 | ||
|
150f86025b | ||
|
313ed7f90a | ||
|
f950075593 | ||
|
9667e8c2a0 | ||
|
88b84dc5ed | ||
|
cee71cb313 | ||
|
db04057d9e | ||
|
ec1939c01d | ||
|
b3383f46ca | ||
|
516140dd7e | ||
|
71a2860716 | ||
|
e0457b40da | ||
|
66d5e73ed1 | ||
|
4094677792 | ||
|
8bbb0d3e82 | ||
|
4aa3bba7bc | ||
|
49f05746bd | ||
|
8eb930d281 | ||
|
85b3f6e8ee | ||
|
5b4c3ec8cd | ||
|
df0e3c108e | ||
|
ab2cbd4ff7 | ||
|
391c143483 | ||
|
7860bc1808 | ||
|
486395c1ce | ||
|
1c3eef345f | ||
|
c5476d99e9 | ||
|
6dfb1ad2e5 | ||
|
075060d11c | ||
|
97d36fa2c8 | ||
|
58aad87770 | ||
|
8a65567169 | ||
|
97beb3f4d3 | ||
|
b455e5eaf5 | ||
|
d0e005f638 | ||
|
a9e12f3b4c | ||
|
153e38a5d4 | ||
|
fe7389e7ca | ||
|
8ee63de6c7 | ||
|
944fd98421 | ||
|
5376bd88d8 | ||
|
3ea6ae3c37 | ||
|
d67767fcfc | ||
|
4f0cc2f616 | ||
|
28342fcf5e | ||
|
9c2594b1b4 | ||
|
4f525bd634 | ||
|
09de686fcf | ||
|
97d90662dd | ||
|
4c733ce581 | ||
|
2336dab69f | ||
|
cf1e1ff943 | ||
|
3bccd6a537 | ||
|
d7fea2125f | ||
|
2792c8c1da | ||
|
0f19826556 | ||
|
64e6a41353 | ||
|
0847a82fc9 | ||
|
9ee9526a47 | ||
|
53e4861ded | ||
|
8ab23c657b | ||
|
e03497032b | ||
|
ae084ae0bb | ||
|
6e0958b3c3 | ||
|
074eea3aeb | ||
|
63b17f9b88 | ||
|
1ce7e53398 | ||
|
fd167234ae | ||
|
e6b557f43b | ||
|
a7865d0f71 | ||
|
7df0fbcb2b | ||
|
e490407260 | ||
|
e7bff0359a | ||
|
2a2831e576 | ||
|
8d3dfcc3c7 | ||
|
f28b7497fa | ||
|
b1a35b7f75 | ||
|
8a30f3681c | ||
|
6073b24036 | ||
|
1b16be2505 | ||
|
bd2e8ac165 | ||
|
351b8dcc12 | ||
|
2c8b757ff6 | ||
|
abc0b206a4 | ||
|
47bb9d7d74 | ||
|
58fc03f4c1 | ||
|
9987d29b7b | ||
|
7206f721f4 | ||
|
4d1eb952b2 | ||
|
64b1394ec1 | ||
|
7b178a76b2 | ||
|
0f9602e3a0 | ||
|
7878a244d3 | ||
|
0c5ec43c80 | ||
|
39891a0758 | ||
|
63ce324eae | ||
|
b74dfe6385 | ||
|
aaca1c73b1 | ||
|
67bb3bae4f | ||
|
39677791b3 | ||
|
82a5bfe198 | ||
|
9d80c5fc8c | ||
|
4949043df9 | ||
|
b7fa4e1a1a | ||
|
def01b6265 | ||
|
cf0b06923d | ||
|
ef425a6ce2 | ||
|
689e5078b8 | ||
|
f916801008 | ||
|
d0970c153b | ||
|
743eae5aad | ||
|
f884926df7 | ||
|
50c7fabeb6 | ||
|
6617a5de45 | ||
|
4cfbd57871 | ||
|
19736aab04 |
2429 changed files with 453693 additions and 152157 deletions
|
@ -1,3 +1,6 @@
|
|||
.DS_Store
|
||||
.git
|
||||
bin
|
||||
.idea
|
||||
selfcert
|
||||
gui/dist-prod
|
|
@ -1,9 +0,0 @@
|
|||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
indent_size = 4
|
||||
insert_final_newline = true
|
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -18,6 +18,7 @@ _convert
|
|||
bin/*
|
||||
dist/*
|
||||
embed/bindata/*
|
||||
edition/static/*
|
||||
gui/dist/*
|
||||
gui/dist-prod/*
|
||||
|
||||
|
@ -52,14 +53,12 @@ _testmain.go
|
|||
node_modules
|
||||
|
||||
# Misc.
|
||||
build
|
||||
plugin-msword/plugin-msword
|
||||
plugin-msword/plugin-msword-osx
|
||||
npm-debug.log
|
||||
debug
|
||||
*.pem
|
||||
*.crt
|
||||
Dockerfile
|
||||
container.sh
|
||||
make.sh
|
||||
jsconfig.json
|
||||
|
@ -70,3 +69,5 @@ testem.log
|
|||
bower.json.ember-try
|
||||
package.json.ember-try
|
||||
embed/bindata_assetfs.go
|
||||
dmz-backup*.zip
|
||||
*.conf
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
{
|
||||
"css": {
|
||||
"indent_size": 4,
|
||||
"indent_level": 0,
|
||||
"indent_with_tabs": true,
|
||||
"preserve_newlines": true,
|
||||
"max_preserve_newlines": 2,
|
||||
"newline_between_rules": true,
|
||||
"selector_separator_newlines": true
|
||||
},
|
||||
"scss": {
|
||||
"indent_size": 4,
|
||||
"indent_level": 0,
|
||||
"indent_with_tabs": true,
|
||||
"preserve_newlines": true,
|
||||
"max_preserve_newlines": 2,
|
||||
"newline_between_rules": true,
|
||||
"selector_separator_newlines": true
|
||||
},
|
||||
"html": {
|
||||
"indent_size": 4,
|
||||
"indent_level": 0,
|
||||
"indent_with_tabs": true,
|
||||
"preserve_newlines": true,
|
||||
"max_preserve_newlines": 2,
|
||||
"wrap_line_length": 0,
|
||||
"indent_handlebars": true,
|
||||
"indent_inner_html": false,
|
||||
"indent_scripts": "keep"
|
||||
},
|
||||
"hbs": {
|
||||
"indent_size": 4,
|
||||
"indent_level": 0,
|
||||
"indent_with_tabs": true,
|
||||
"max_preserve_newlines": 2,
|
||||
"preserve_newlines": true,
|
||||
"wrap_line_length": 0
|
||||
},
|
||||
"js": {
|
||||
"indent_size": 4,
|
||||
"indent_level": 0,
|
||||
"indent_with_tabs": true,
|
||||
"preserve_newlines": true,
|
||||
"wrap_line_length": 0,
|
||||
"break_chained_methods": false,
|
||||
"max_preserve_newlines": 2,
|
||||
"jslint_happy": true,
|
||||
"brace_style": "collapse-preserve-inline",
|
||||
"keep_function_indentation": false,
|
||||
"space_after_anon_function": false,
|
||||
"space_before_anon_function": false,
|
||||
"space_before_conditional": true,
|
||||
"space_in_empty_paren": false,
|
||||
"space_before_func_paren": false,
|
||||
"space_in_paren": false
|
||||
},
|
||||
"sql": {
|
||||
"indent_size": 4,
|
||||
"indent_level": 0,
|
||||
"indent_with_tabs": true
|
||||
}
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
gui/public/tinymce/**
|
||||
gui/public/tinymce/
|
||||
gui/public/tinymce
|
|
@ -1,3 +0,0 @@
|
|||
{
|
||||
"esversion":6
|
||||
}
|
32
Dockerfile
Normal file
32
Dockerfile
Normal file
|
@ -0,0 +1,32 @@
|
|||
FROM node:16-alpine as frontbuilder
|
||||
WORKDIR /go/src/github.com/documize/community/gui
|
||||
COPY ./gui /go/src/github.com/documize/community/gui
|
||||
RUN npm --network-timeout=100000 install
|
||||
RUN npm run build -- --environment=production --output-path dist-prod --suppress-sizes true
|
||||
|
||||
FROM golang:1.21-alpine as builder
|
||||
WORKDIR /go/src/github.com/documize/community
|
||||
COPY . /go/src/github.com/documize/community
|
||||
COPY --from=frontbuilder /go/src/github.com/documize/community/gui/dist-prod/assets /go/src/github.com/documize/community/edition/static/public/assets
|
||||
COPY --from=frontbuilder /go/src/github.com/documize/community/gui/dist-prod/codemirror /go/src/github.com/documize/community/edition/static/public/codemirror
|
||||
COPY --from=frontbuilder /go/src/github.com/documize/community/gui/dist-prod/prism /go/src/github.com/documize/community/edition/static/public/prism
|
||||
COPY --from=frontbuilder /go/src/github.com/documize/community/gui/dist-prod/sections /go/src/github.com/documize/community/edition/static/public/sections
|
||||
COPY --from=frontbuilder /go/src/github.com/documize/community/gui/dist-prod/tinymce /go/src/github.com/documize/community/edition/static/public/tinymce
|
||||
COPY --from=frontbuilder /go/src/github.com/documize/community/gui/dist-prod/pdfjs /go/src/github.com/documize/community/edition/static/public/pdfjs
|
||||
COPY --from=frontbuilder /go/src/github.com/documize/community/gui/dist-prod/i18n /go/src/github.com/documize/community/edition/static/public/i18n
|
||||
COPY --from=frontbuilder /go/src/github.com/documize/community/gui/dist-prod/*.* /go/src/github.com/documize/community/edition/static/
|
||||
COPY --from=frontbuilder /go/src/github.com/documize/community/gui/dist-prod/i18n/*.json /go/src/github.com/documize/community/edition/static/i18n/
|
||||
COPY domain/mail/*.html /go/src/github.com/documize/community/edition/static/mail/
|
||||
COPY core/database/templates/*.html /go/src/github.com/documize/community/edition/static/
|
||||
COPY core/database/scripts/mysql/*.sql /go/src/github.com/documize/community/edition/static/scripts/mysql/
|
||||
COPY core/database/scripts/postgresql/*.sql /go/src/github.com/documize/community/edition/static/scripts/postgresql/
|
||||
COPY core/database/scripts/sqlserver/*.sql /go/src/github.com/documize/community/edition/static/scripts/sqlserver/
|
||||
COPY domain/onboard/*.json /go/src/github.com/documize/community/edition/static/onboard/
|
||||
RUN env GODEBUG=tls13=1 go build -mod=vendor -o bin/documize-community ./edition/community.go
|
||||
|
||||
# build release image
|
||||
FROM alpine:3.16
|
||||
RUN apk add --no-cache ca-certificates
|
||||
COPY --from=builder /go/src/github.com/documize/community/bin/documize-community /documize
|
||||
EXPOSE 5001
|
||||
ENTRYPOINT [ "/documize" ]
|
175
Gopkg.lock
generated
175
Gopkg.lock
generated
|
@ -1,175 +0,0 @@
|
|||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/codegangsta/negroni"
|
||||
packages = ["."]
|
||||
revision = "5dbbc83f748fc3ad38585842b0aedab546d0ea1e"
|
||||
version = "v0.3.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/dgrijalva/jwt-go"
|
||||
packages = ["."]
|
||||
revision = "dbeaa9332f19a944acb5736b4456cfcc02140e29"
|
||||
version = "v3.1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/documize/blackfriday"
|
||||
packages = ["."]
|
||||
revision = "cadec560ec52d93835bf2f15bd794700d3a2473b"
|
||||
version = "v2.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/documize/glick"
|
||||
packages = ["."]
|
||||
revision = "a8ccbef88237fcafe9cef3c9aee7ad83d0e132f9"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/documize/html-diff"
|
||||
packages = ["."]
|
||||
revision = "f61c192c7796644259832ef705c49259797e7fff"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/documize/slug"
|
||||
packages = ["."]
|
||||
revision = "e9f42fa127660e552d0ad2b589868d403a9be7c6"
|
||||
version = "v1.1.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/elazarl/go-bindata-assetfs"
|
||||
packages = ["."]
|
||||
revision = "30f82fa23fd844bd5bb1e5f216db87fd77b5eb43"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/go-sql-driver/mysql"
|
||||
packages = ["."]
|
||||
revision = "a0583e0143b1624142adab07e0e97fe106d99561"
|
||||
version = "v1.3"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = ["proto"]
|
||||
revision = "925541529c1fa6821df4e44ce2723319eb2be768"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/google/go-github"
|
||||
packages = ["github"]
|
||||
revision = "e48060a28fac52d0f1cb758bc8b87c07bac4a87d"
|
||||
version = "v15.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/google/go-querystring"
|
||||
packages = ["query"]
|
||||
revision = "53e6ce116135b80d037921a7fdd5138cf32d7a8a"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gorilla/context"
|
||||
packages = ["."]
|
||||
revision = "1ea25387ff6f684839d82767c1733ff4d4d15d0a"
|
||||
version = "v1.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gorilla/mux"
|
||||
packages = ["."]
|
||||
revision = "53c1911da2b537f792e7cafcb446b05ffe33b996"
|
||||
version = "v1.6.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/jmoiron/sqlx"
|
||||
packages = [
|
||||
".",
|
||||
"reflectx"
|
||||
]
|
||||
revision = "05cef0741ade10ca668982355b3f3f0bcf0ff0a8"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/mb0/diff"
|
||||
packages = ["."]
|
||||
revision = "d8d9a906c24d7b0ee77287e0463e5ca7f026032e"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/nu7hatch/gouuid"
|
||||
packages = ["."]
|
||||
revision = "179d4d0c4d8d407a32af483c2354df1d2c91e6c3"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/pkg/errors"
|
||||
packages = ["."]
|
||||
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
|
||||
version = "v0.8.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/rainycape/unidecode"
|
||||
packages = ["."]
|
||||
revision = "cb7f23ec59bec0d61b19c56cd88cee3d0cc1870c"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/shurcooL/sanitized_anchor_name"
|
||||
packages = ["."]
|
||||
revision = "86672fcb3f950f35f2e675df2240550f2a50762f"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = [
|
||||
"bcrypt",
|
||||
"blowfish"
|
||||
]
|
||||
revision = "650f4a345ab4e5b245a3034b110ebc7299e68186"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/net"
|
||||
packages = [
|
||||
"context",
|
||||
"context/ctxhttp",
|
||||
"html",
|
||||
"html/atom"
|
||||
]
|
||||
revision = "f5dfe339be1d06f81b22525fe34671ee7d2c8904"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/oauth2"
|
||||
packages = [
|
||||
".",
|
||||
"internal"
|
||||
]
|
||||
revision = "543e37812f10c46c622c9575afd7ad22f22a12ba"
|
||||
|
||||
[[projects]]
|
||||
name = "google.golang.org/appengine"
|
||||
packages = [
|
||||
"internal",
|
||||
"internal/base",
|
||||
"internal/datastore",
|
||||
"internal/log",
|
||||
"internal/remote_api",
|
||||
"internal/urlfetch",
|
||||
"urlfetch"
|
||||
]
|
||||
revision = "150dc57a1b433e64154302bdc40b6bb8aefa313a"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "v3"
|
||||
name = "gopkg.in/alexcesaro/quotedprintable.v3"
|
||||
packages = ["."]
|
||||
revision = "2caba252f4dc53eaf6b553000885530023f54623"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "a21753e8c217630ea2893ea4a4ee682749e28d4eb6acf70b9b5982ab8c521a20"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
98
Gopkg.toml
98
Gopkg.toml
|
@ -1,98 +0,0 @@
|
|||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
# for detailed Gopkg.toml documentation.
|
||||
#
|
||||
# required = ["github.com/user/thing/cmd/thing"]
|
||||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project"
|
||||
# version = "1.0.0"
|
||||
#
|
||||
# [[constraint]]
|
||||
# name = "github.com/user/project2"
|
||||
# branch = "dev"
|
||||
# source = "github.com/myfork/project2"
|
||||
#
|
||||
# [[override]]
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
#
|
||||
# [prune]
|
||||
# non-go = false
|
||||
# go-tests = true
|
||||
# unused-packages = true
|
||||
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/codegangsta/negroni"
|
||||
version = "0.3.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/dgrijalva/jwt-go"
|
||||
version = "3.1.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/documize/blackfriday"
|
||||
version = "2.0.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/documize/glick"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/documize/html-diff"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/elazarl/go-bindata-assetfs"
|
||||
version = "1.0.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/go-sql-driver/mysql"
|
||||
version = "1.3.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/google/go-github"
|
||||
version = "15.0.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/gorilla/mux"
|
||||
version = "1.6.1"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/jmoiron/sqlx"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/nu7hatch/gouuid"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/pkg/errors"
|
||||
version = "0.8.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/crypto"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/net"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/oauth2"
|
||||
|
||||
[prune]
|
||||
go-tests = true
|
||||
unused-packages = true
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/documize/unidecode"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/documize/slug"
|
||||
version = "1.1.1"
|
2572
NOTICES.md
Normal file
2572
NOTICES.md
Normal file
File diff suppressed because it is too large
Load diff
162
README.md
162
README.md
|
@ -1,128 +1,110 @@
|
|||
> We're committed to providing frequent product releases to ensure self-host customers enjoy the same product as our cloud/SaaS customers.
|
||||
>
|
||||
> Harvey Kandola, CEO & Founder, Documize Inc.
|
||||
Documize Community is an open source, modern, self-hosted, enterprise-grade knowledge management solution.
|
||||
|
||||
## The mission
|
||||
- Built for technical and non-technical users
|
||||
- Designed to unify both customer-facing and internal documentation
|
||||
- Organization through labels, spaces and categories
|
||||
|
||||
To bring software development inspired features to the world of documenting -- refactoring, importing, testing, linting, metrics, PRs, versioning....
|
||||
It's built with Golang + EmberJS and compiled down to a single executable binary that is available for Linux, Windows and Mac.
|
||||
|
||||
## What is it?
|
||||
All you need to provide is your database -- PostgreSQL, Microsoft SQL Server or any MySQL variant.
|
||||
|
||||
Documize is an intelligent document environment (IDE) for authoring, tracking and delivering documentation -- everything you need in one place.
|
||||

|
||||
|
||||
## Why should I care?
|
||||
## Latest Release
|
||||
|
||||
Because maybe like us you're tired of:
|
||||
[Community edition: v5.13.0](https://github.com/documize/community/releases)
|
||||
|
||||
* juggling WYSIWYG editors, wiki software and other document related solutions
|
||||
* playing email tennis with documents, contributions, versions and feedback
|
||||
* sharing not-so-secure folders with external participants
|
||||
[Community+ edition: v5.13.0](https://www.documize.com/community/get-started)
|
||||
|
||||
Sound familiar? Read on.
|
||||
The Community+ edition is the "enterprise" offering with advanced capabilities and customer support:
|
||||
|
||||
## Who is it for?
|
||||
- content approval workflows
|
||||
- content organization by label, space and category
|
||||
- content version management
|
||||
- content lifecycle management
|
||||
- content feedback capture
|
||||
- content PDF export
|
||||
- analytics and reporting
|
||||
- activity streams
|
||||
- audit logs
|
||||
- actions assignments
|
||||
- product support
|
||||
|
||||
Anyone who wants a single place for any kind of document.
|
||||
The Community+ edition is [free](https://www.documize.com/community/get-started) for the first five users -- thereafter pricing starts at just $900 annually for 100 users.
|
||||
|
||||
Anyone who wants to loop in external participants with complete security.
|
||||
|
||||
Anyone who wishes documentation and knowledge capture worked like agile software development.
|
||||
|
||||
Anyone who knows that nested folders fail miserably.
|
||||
|
||||
Anyone who wants to move on from wiki software.
|
||||
|
||||
## What's different about Documize?
|
||||
|
||||
Sane organization through personal, team and public spaces.
|
||||
|
||||
Granular document access control via categories.
|
||||
|
||||
Section based approach to document construction.
|
||||
|
||||
Reusable templates and content blocks.
|
||||
|
||||
Documentation related tasking and delegation.
|
||||
|
||||
Integrations for embedding SaaS data within documents, zero add-on/marketplace fees.
|
||||
|
||||
## What does it look like?
|
||||
|
||||
All spaces.
|
||||
|
||||

|
||||
|
||||
Space view.
|
||||
|
||||

|
||||
|
||||
## Latest version
|
||||
|
||||
[Community edition: v1.66.0](https://github.com/documize/community/releases)
|
||||
|
||||
[Enterprise edition: v1.68.0](https://documize.com/downloads)
|
||||
|
||||
## OS support
|
||||
|
||||
Documize runs on the following:
|
||||
## OS Support
|
||||
|
||||
- Linux
|
||||
- Windows
|
||||
- macOS
|
||||
- Raspberry Pi (ARM build)
|
||||
|
||||
# Browser support
|
||||
Support for AMD and ARM 64 bit architectures.
|
||||
|
||||
Documize supports the following (evergreen) browsers:
|
||||
## Database Support
|
||||
|
||||
- Chrome
|
||||
- Firefox
|
||||
- Safari
|
||||
- Brave
|
||||
- MS Edge (16+)
|
||||
For all database types, Full-Text Search (FTS) support is mandatory.
|
||||
|
||||
## Technology stack
|
||||
|
||||
Documize is built with the following technologies:
|
||||
|
||||
- EmberJS (v3.1.2)
|
||||
- Go (v1.10.3)
|
||||
|
||||
...and supports the following databases:
|
||||
|
||||
- MySQL (v5.7.10+)
|
||||
- PostgreSQL (v9.6+)
|
||||
- Microsoft SQL Server (2016+ with FTS)
|
||||
- Microsoft SQL Azure (v12+)
|
||||
- MySQL (v5.7.10+ and v8.0.12+)
|
||||
- Percona (v5.7.16-10+)
|
||||
- MariaDB (10.3.0+)
|
||||
|
||||
Coming soon, PostgreSQL and Microsoft SQL Server database support.
|
||||
## Browser Support
|
||||
|
||||
## Authentication options
|
||||
- Firefox
|
||||
- Chrome
|
||||
- Safari
|
||||
- Microsoft Edge
|
||||
- Brave
|
||||
- Vivaldi
|
||||
- Opera
|
||||
|
||||
Besides email/password login, you can also leverage the following options.
|
||||
## Technology Stack
|
||||
|
||||
### Keycloak Integration
|
||||
- Go (v1.23.4)
|
||||
- Ember JS (v3.12.0)
|
||||
|
||||
Documize provides out-of-the-box integration with [Redhat Keycloak](http://www.keycloak.org) for open source identity and access management.
|
||||
## Authentication Options
|
||||
|
||||
Connect and authenticate with LDAP, Active Directory and more.
|
||||
Besides email/password login, you can also authenticate via:
|
||||
|
||||
<https://docs.documize.com>
|
||||
* LDAP
|
||||
* Active Directory
|
||||
* Red Hat Keycloak
|
||||
* Central Authentication Service (CAS)
|
||||
|
||||
### Auth0 Compatible
|
||||
When using LDAP/Active Directory, you can enable dual-authentication with email/password.
|
||||
|
||||
Documize is compatible with Auth0 identity as a service.
|
||||
## Localization
|
||||
|
||||
[](https://auth0.com/?utm_source=oss&utm_medium=gp&utm_campaign=oss)
|
||||
Languages supported out-of-the-box:
|
||||
|
||||
Open Source Identity and Access Management
|
||||
- English
|
||||
- German
|
||||
- French
|
||||
- Chinese (中文)
|
||||
- Portuguese (Brazil) (Português - Brasil)
|
||||
- Japanese (日本語)
|
||||
- Italian
|
||||
- Spanish Argentinian
|
||||
|
||||
## Developer's Note
|
||||
PR's welcome for additional languages.
|
||||
|
||||
We try to follow sound advice when writing commit messages:
|
||||
## Product/Technical Support
|
||||
|
||||
https://chris.beams.io/posts/git-commit/
|
||||
For both Community and Community+ editions, please contact our help desk for product help, suggestions and other enquiries.
|
||||
|
||||
## The legal bit
|
||||
<support@documize.com>
|
||||
|
||||
<https://documize.com>
|
||||
We aim to respond within two working days.
|
||||
|
||||
This software (Documize Community Edition) is licensed under GNU AGPL v3 <http://www.gnu.org/licenses/agpl-3.0.en.html>. You can operate outside the AGPL restrictions by purchasing Documize Enterprise Edition and obtaining a commercial license by contacting <sales@documize.com>. Documize® is a registered trade mark of Documize Inc.
|
||||
## The Legal Bit
|
||||
|
||||
<https://www.documize.com>
|
||||
|
||||
This software (Documize Community edition) is licensed under GNU AGPL v3 <http://www.gnu.org/licenses/agpl-3.0.en.html>.
|
||||
|
||||
Documize Community uses other open source components and we acknowledge them in [NOTICES](NOTICES.md)
|
||||
|
|
77
build.bat
77
build.bat
|
@ -7,50 +7,61 @@ echo "Building Ember assets..."
|
|||
cd gui
|
||||
call ember b -o dist-prod/ --environment=production
|
||||
::Call allows the rest of the file to run
|
||||
|
||||
echo "Copying Ember assets..."
|
||||
cd ..
|
||||
rd /s /q embed\bindata\public
|
||||
mkdir embed\bindata\public
|
||||
|
||||
rd /s /q edition\static\public
|
||||
mkdir edition\static\public
|
||||
echo "Copying Ember assets folder"
|
||||
robocopy /e /NFL /NDL /NJH gui\dist-prod\assets embed\bindata\public\assets
|
||||
robocopy /e /NFL /NDL /NJH gui\dist-prod\assets edition\static\public\assets
|
||||
echo "Copying Ember codemirror folder"
|
||||
robocopy /e /NFL /NDL /NJH gui\dist-prod\codemirror embed\bindata\public\codemirror
|
||||
robocopy /e /NFL /NDL /NJH gui\dist-prod\codemirror edition\static\public\codemirror
|
||||
echo "Copying Ember prism folder"
|
||||
robocopy /e /NFL /NDL /NJH gui\dist-prod\prism edition\static\public\prism
|
||||
echo "Copying Ember tinymce folder"
|
||||
robocopy /e /NFL /NDL /NJH gui\dist-prod\tinymce embed\bindata\public\tinymce
|
||||
robocopy /e /NFL /NDL /NJH gui\dist-prod\tinymce edition\static\public\tinymce
|
||||
echo "Copying Ember pdfjs folder"
|
||||
robocopy /e /NFL /NDL /NJH gui\dist-prod\pdfjs edition\static\public\pdfjs
|
||||
echo "Copying Ember sections folder"
|
||||
robocopy /e /NFL /NDL /NJH gui\dist-prod\sections embed\bindata\public\sections
|
||||
robocopy /e /NFL /NDL /NJH gui\dist-prod\sections edition\static\public\sections
|
||||
echo "Copying i18n folder"
|
||||
robocopy /e /NFL /NDL /NJH gui\dist-prod\i18n edition\static\public\i18n
|
||||
|
||||
copy gui\dist-prod\*.* embed\bindata
|
||||
copy gui\dist-prod\favicon.ico embed\bindata\public
|
||||
copy gui\dist-prod\manifest.json embed\bindata\public
|
||||
echo "Copying static files"
|
||||
copy gui\dist-prod\*.* edition\static
|
||||
|
||||
rd /s /q embed\bindata\mail
|
||||
mkdir embed\bindata\mail
|
||||
copy domain\mail\*.html embed\bindata\mail
|
||||
copy core\database\templates\*.html embed\bindata
|
||||
echo "Copying favicon.ico"
|
||||
copy gui\dist-prod\favicon.ico edition\static\public
|
||||
|
||||
rd /s /q embed\bindata\scripts
|
||||
mkdir embed\bindata\scripts
|
||||
echo "Copying manifest.json"
|
||||
copy gui\dist-prod\manifest.json edition\static\public
|
||||
|
||||
echo "Copying mail templates"
|
||||
rd /s /q edition\static\mail
|
||||
mkdir edition\static\mail
|
||||
copy domain\mail\*.html edition\static\mail
|
||||
|
||||
echo "Copying database templates"
|
||||
copy core\database\templates\*.html edition\static
|
||||
|
||||
rd /s /q edition\static\i18n
|
||||
mkdir edition\static\i18n
|
||||
robocopy /e /NFL /NDL /NJH gui\dist-prod\i18n edition\static\i18n *.json
|
||||
|
||||
rd /s /q edition\static\scripts
|
||||
mkdir edition\static\scripts
|
||||
mkdir edition\static\scripts\mysql
|
||||
mkdir edition\static\scripts\postgresql
|
||||
mkdir edition\static\scripts\sqlserver
|
||||
|
||||
echo "Copying database scripts folder"
|
||||
robocopy /e /NFL /NDL /NJH core\database\scripts\autobuild embed\bindata\scripts
|
||||
robocopy /e /NFL /NDL /NJH core\database\scripts\mysql edition\static\scripts\mysql
|
||||
robocopy /e /NFL /NDL /NJH core\database\scripts\postgresql edition\static\scripts\postgresql
|
||||
robocopy /e /NFL /NDL /NJH core\database\scripts\sqlserver edition\static\scripts\sqlserver
|
||||
|
||||
echo "Generating in-memory static assets..."
|
||||
go get -u github.com/jteeuwen/go-bindata/...
|
||||
go get -u github.com/elazarl/go-bindata-assetfs/...
|
||||
cd embed
|
||||
go generate
|
||||
cd ..
|
||||
rd /s /q edition\static\onboard
|
||||
mkdir edition\static\onboard
|
||||
robocopy /e /NFL /NDL /NJH domain\onboard edition\static\onboard *.json
|
||||
|
||||
echo "Compiling Windows"
|
||||
set GOOS=windows
|
||||
go build -gcflags=-trimpath=%GOPATH% -asmflags=-trimpath=%GOPATH% -o bin/documize-community-windows-amd64.exe edition/community.go
|
||||
|
||||
echo "Compiling Linux"
|
||||
set GOOS=linux
|
||||
go build -gcflags=-trimpath=%GOPATH% -asmflags=-trimpath=%GOPATH% -o bin/documize-community-linux-amd64 edition/community.go
|
||||
|
||||
echo "Compiling Darwin"
|
||||
set GOOS=darwin
|
||||
go build -gcflags=-trimpath=%GOPATH% -asmflags=-trimpath=%GOPATH% -o bin/documize-community-darwin-amd64 edition/community.go
|
||||
go build -mod=vendor -trimpath -gcflags="all=-trimpath=$GOPATH" -o bin/documize-community-windows-amd64.exe edition/community.go
|
||||
|
|
89
build.sh
89
build.sh
|
@ -8,50 +8,65 @@ echo "Build process started $NOW"
|
|||
|
||||
echo "Building Ember assets..."
|
||||
cd gui
|
||||
ember b -o dist-prod/ --environment=production
|
||||
# export NODE_OPTIONS=--openssl-legacy-provider
|
||||
ember build ---environment=production --output-path dist-prod --suppress-sizes true
|
||||
cd ..
|
||||
|
||||
echo "Copying Ember assets..."
|
||||
cd ..
|
||||
rm -rf embed/bindata/public
|
||||
mkdir -p embed/bindata/public
|
||||
cp -r gui/dist-prod/assets embed/bindata/public
|
||||
cp -r gui/dist-prod/codemirror embed/bindata/public/codemirror
|
||||
cp -r gui/dist-prod/tinymce embed/bindata/public/tinymce
|
||||
cp -r gui/dist-prod/sections embed/bindata/public/sections
|
||||
cp gui/dist-prod/*.* embed/bindata
|
||||
cp gui/dist-prod/favicon.ico embed/bindata/public
|
||||
cp gui/dist-prod/manifest.json embed/bindata/public
|
||||
rm -rf embed/bindata/mail
|
||||
mkdir -p embed/bindata/mail
|
||||
cp domain/mail/*.html embed/bindata/mail
|
||||
cp core/database/templates/*.html embed/bindata
|
||||
rm -rf embed/bindata/scripts
|
||||
mkdir -p embed/bindata/scripts
|
||||
cp -r core/database/scripts/autobuild/*.sql embed/bindata/scripts
|
||||
rm -rf edition/static/public
|
||||
mkdir -p edition/static/public
|
||||
cp -r gui/dist-prod/assets edition/static/public
|
||||
cp -r gui/dist-prod/codemirror edition/static/public/codemirror
|
||||
cp -r gui/dist-prod/prism edition/static/public/prism
|
||||
cp -r gui/dist-prod/sections edition/static/public/sections
|
||||
cp -r gui/dist-prod/tinymce edition/static/public/tinymce
|
||||
cp -r gui/dist-prod/pdfjs edition/static/public/pdfjs
|
||||
cp -r gui/dist-prod/i18n edition/static/public/i18n
|
||||
cp gui/dist-prod/*.* edition/static
|
||||
cp gui/dist-prod/favicon.ico edition/static/public
|
||||
cp gui/dist-prod/manifest.json edition/static/public
|
||||
|
||||
echo "Generating in-memory static assets..."
|
||||
# go get -u github.com/jteeuwen/go-bindata/...
|
||||
# go get -u github.com/elazarl/go-bindata-assetfs/...
|
||||
cd embed
|
||||
go generate
|
||||
rm -rf edition/static/mail
|
||||
mkdir -p edition/static/mail
|
||||
cp domain/mail/*.html edition/static/mail
|
||||
cp core/database/templates/*.html edition/static
|
||||
|
||||
echo "Compiling app..."
|
||||
cd ..
|
||||
for arch in amd64 ; do
|
||||
for os in darwin linux windows ; do
|
||||
if [ "$os" == "windows" ] ; then
|
||||
echo "Compiling documize-community-$os-$arch.exe"
|
||||
env GOOS=$os GOARCH=$arch go build -gcflags=-trimpath=$GOPATH -asmflags=-trimpath=$GOPATH -o bin/documize-community-$os-$arch.exe ./edition/community.go
|
||||
else
|
||||
echo "Compiling documize-community-$os-$arch"
|
||||
env GOOS=$os GOARCH=$arch go build -gcflags=-trimpath=$GOPATH -asmflags=-trimpath=$GOPATH -o bin/documize-community-$os-$arch ./edition/community.go
|
||||
fi
|
||||
done
|
||||
done
|
||||
rm -rf edition/static/i18n
|
||||
mkdir -p edition/static/i18n
|
||||
cp -r gui/dist-prod/i18n/*.json edition/static/i18n
|
||||
|
||||
rm -rf edition/static/scripts
|
||||
mkdir -p edition/static/scripts
|
||||
mkdir -p edition/static/scripts/mysql
|
||||
mkdir -p edition/static/scripts/postgresql
|
||||
mkdir -p edition/static/scripts/sqlserver
|
||||
cp -r core/database/scripts/mysql/*.sql edition/static/scripts/mysql
|
||||
cp -r core/database/scripts/postgresql/*.sql edition/static/scripts/postgresql
|
||||
cp -r core/database/scripts/sqlserver/*.sql edition/static/scripts/sqlserver
|
||||
|
||||
rm -rf edition/static/onboard
|
||||
mkdir -p edition/static/onboard
|
||||
cp -r domain/onboard/*.json edition/static/onboard
|
||||
|
||||
echo "Compiling for macOS Intel..."
|
||||
env GOOS=darwin GOARCH=amd64 go build -mod=vendor -trimpath -o bin/documize-community-darwin-amd64 ./edition/community.go
|
||||
echo "Compiling for macOS ARM..."
|
||||
env GOOS=darwin GOARCH=arm64 go build -mod=vendor -trimpath -o bin/documize-community-darwin-arm64 ./edition/community.go
|
||||
echo "Compiling for Windows AMD..."
|
||||
env GOOS=windows GOARCH=amd64 go build -mod=vendor -trimpath -o bin/documize-community-windows-amd64.exe ./edition/community.go
|
||||
echo "Compiling for Linux AMD..."
|
||||
env GOOS=linux GOARCH=amd64 go build -mod=vendor -trimpath -o bin/documize-community-linux-amd64 ./edition/community.go
|
||||
echo "Compiling for Linux ARM..."
|
||||
env GOOS=linux GOARCH=arm go build -mod=vendor -trimpath -o bin/documize-community-linux-arm ./edition/community.go
|
||||
echo "Compiling for Linux ARM64..."
|
||||
env GOOS=linux GOARCH=arm64 go build -mod=vendor -trimpath -o bin/documize-community-linux-arm64 ./edition/community.go
|
||||
echo "Compiling for FreeBSD ARM64..."
|
||||
env GOOS=freebsd GOARCH=arm64 go build -mod=vendor -trimpath -o bin/documize-community-freebsd-arm64 ./edition/community.go
|
||||
echo "Compiling for FreeBSD AMD64..."
|
||||
env GOOS=freebsd GOARCH=amd64 go build -mod=vendor -trimpath -o bin/documize-community-freebsd-amd64 ./edition/community.go
|
||||
|
||||
echo "Finished."
|
||||
|
||||
|
||||
# CGO_ENABLED=0 GOOS=linux go build -a -ldflags="-s -w" -installsuffix cgo
|
||||
# go build -ldflags '-d -s -w' -a -tags netgo -installsuffix netgo test.go
|
||||
# ldd test
|
||||
|
|
23
compile.sh
23
compile.sh
|
@ -1,23 +0,0 @@
|
|||
#! /bin/bash
|
||||
|
||||
echo "Generating in-memory static assets..."
|
||||
# go get -u github.com/jteeuwen/go-bindata/...
|
||||
# go get -u github.com/elazarl/go-bindata-assetfs/...
|
||||
cd embed
|
||||
go generate
|
||||
|
||||
echo "Compiling app..."
|
||||
cd ..
|
||||
for arch in amd64 ; do
|
||||
for os in darwin linux windows ; do
|
||||
if [ "$os" == "windows" ] ; then
|
||||
echo "Compiling documize-community-$os-$arch.exe"
|
||||
env GOOS=$os GOARCH=$arch go build -gcflags=-trimpath=$GOPATH -asmflags=-trimpath=$GOPATH -o bin/documize-community-$os-$arch.exe ./edition/community.go
|
||||
else
|
||||
echo "Compiling documize-community-$os-$arch"
|
||||
env GOOS=$os GOARCH=$arch go build -gcflags=-trimpath=$GOPATH -asmflags=-trimpath=$GOPATH -o bin/documize-community-$os-$arch ./edition/community.go
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
echo "Finished."
|
|
@ -19,8 +19,8 @@ import (
|
|||
"net/http"
|
||||
"path/filepath"
|
||||
|
||||
"context"
|
||||
api "github.com/documize/community/core/convapi"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
// Msword type provides a peg to hang the Convert method on.
|
||||
|
|
|
@ -19,7 +19,7 @@ import (
|
|||
"github.com/documize/community/core/api/plugins"
|
||||
api "github.com/documize/community/core/convapi"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
"context"
|
||||
)
|
||||
|
||||
// Convert provides the entry-point into the document conversion process.
|
||||
|
|
|
@ -1,155 +0,0 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
package convert_test
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/documize/community/core/api/convert"
|
||||
"github.com/documize/community/core/api/plugins"
|
||||
api "github.com/documize/community/core/convapi"
|
||||
"github.com/documize/community/core/log"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
func TestConvert(t *testing.T) {
|
||||
|
||||
plugins.PluginFile = "" // no file as html is built-in
|
||||
if lerr := plugins.LibSetup(); lerr == nil {
|
||||
//t.Error("did not error on plugin.Libsetup() with no plugin.json file")
|
||||
//return
|
||||
}
|
||||
defer log.IfErr(plugins.Lib.KillSubProcs())
|
||||
|
||||
ctx := context.Background()
|
||||
xtn := "html"
|
||||
fileRequest := new(api.DocumentConversionRequest)
|
||||
fileRequest.Filedata = []byte(yorkweb)
|
||||
resp, err := convert.Convert(ctx, xtn, fileRequest)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
if len(resp.Pages) != 3 ||
|
||||
!strings.HasPrefix(resp.Pages[1].Title, "STARTING") ||
|
||||
!strings.HasPrefix(resp.Pages[2].Title, "EXERCISE") {
|
||||
for p, pg := range resp.Pages {
|
||||
t.Error(p, pg.Level, len(pg.Body), pg.Title)
|
||||
}
|
||||
}
|
||||
exp := "There are lots of ways to create web pages using already coded programmes. … HTML isn' t computer code, but is a language that uses US English to enable texts( words, images, sounds) to be inserted and formatting such as colo( u) r and centre/ erin…"
|
||||
if resp.Excerpt != exp {
|
||||
t.Errorf("unexpected excerpt wanted: `%s` got: `%s`", exp, resp.Excerpt)
|
||||
}
|
||||
|
||||
// check errors are caught
|
||||
resp, err = convert.Convert(ctx, "unknown", fileRequest)
|
||||
if err == nil {
|
||||
t.Error("does not error on unknown extension")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// www.york.ac.uk/teaching/cws/wws/webpage1.html
|
||||
const yorkweb = `
|
||||
|
||||
<HMTL>
|
||||
<HEAD>
|
||||
<TITLE>webpage1</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR="FFFFFf" LINK="006666" ALINK="8B4513" VLINK="006666">
|
||||
<TABLE WIDTH="75%" ALIGN="center">
|
||||
<TR>
|
||||
<TD>
|
||||
<DIV ALIGN="center"><H1>STARTING . . . </H1></DIV>
|
||||
|
||||
|
||||
<DIV ALIGN="justify"><P>There are lots of ways to create web pages using already coded programmes. These lessons will teach you how to use the underlying HyperText Markup Language - HTML.
|
||||
<BR>
|
||||
<P>HTML isn't computer code, but is a language that uses US English to enable texts (words, images, sounds) to be inserted and formatting such as colo(u)r and centre/ering to be written in. The process is fairly simple; the main difficulties often lie in small mistakes - if you slip up while word processing your reader may pick up your typos, but the page will still be legible. However, if your HTML is inaccurate the page may not appear - writing web pages is, at the least, very good practice for proof reading!</P>
|
||||
|
||||
<P>Learning HTML will enable you to:
|
||||
<UL>
|
||||
<LI>create your own simple pages
|
||||
<LI>read and appreciate pages created by others
|
||||
<LI>develop an understanding of the creative and literary implications of web-texts
|
||||
<LI>have the confidence to branch out into more complex web design
|
||||
</UL></P>
|
||||
|
||||
<P>A HTML web page is made up of tags. Tags are placed in brackets like this <B>< tag > </B>. A tag tells the browser how to display information. Most tags need to be opened < tag > and closed < /tag >.
|
||||
|
||||
<P> To make a simple web page you need to know only four tags:
|
||||
<UL>
|
||||
<LI>< HTML > tells the browser your page is written in HTML format
|
||||
<LI>< HEAD > this is a kind of preface of vital information that doesn't appear on the screen.
|
||||
<LI>< TITLE >Write the title of the web page here - this is the information that viewers see on the upper bar of their screen. (I've given this page the title 'webpage1').
|
||||
<LI>< BODY >This is where you put the content of your page, the words and pictures that people read on the screen.
|
||||
</UL>
|
||||
<P>All these tags need to be closed.
|
||||
|
||||
<H4>EXERCISE</H4>
|
||||
|
||||
<P>Write a simple web page.</P>
|
||||
<P> Copy out exactly the HTML below, using a WP program such as Notepad.<BR>
|
||||
Information in <I>italics</I> indicates where you can insert your own text, other information is HTML and needs to be exact. However, make sure there are no spaces between the tag brackets and the text inside.<BR>
|
||||
(Find Notepad by going to the START menu\ PROGRAMS\ ACCESSORIES\ NOTEPAD).
|
||||
<P>
|
||||
< HTML ><BR>
|
||||
< HEAD ><BR>
|
||||
< TITLE ><I> title of page</I>< /TITLE ><BR>
|
||||
< /HEAD ><BR>
|
||||
< BODY><BR>
|
||||
<I> write what you like here: 'my first web page', or a piece about what you are reading, or a few thoughts on the course, or copy out a few words from a book or cornflake packet. Just type in your words using no extras such as bold, or italics, as these have special HTML tags, although you may use upper and lower case letters and single spaces. </I><BR>
|
||||
|
||||
< /BODY ><BR>
|
||||
< /HTML ><BR>
|
||||
|
||||
<P>Save the file as 'first.html' (ie. call the file anything at all) It's useful if you start a folder - just as you would for word-processing - and call it something like WEBPAGES, and put your first.html file in the folder.
|
||||
|
||||
<P>NOW - open your browser.<BR>
|
||||
On Netscape the process is: <BR>
|
||||
Top menu; FILE\ OPEN PAGE\ CHOOSE FILE<BR>
|
||||
Click on your WEBPAGES folder\ FIRST file<BR>
|
||||
Click 'open' and your page should appear.
|
||||
<P>On Internet Explorer: <BR>
|
||||
Top menu; FILE\ OPEN\ BROWSE <BR>
|
||||
Click on your WEBPAGES folder\ FIRST file<BR>
|
||||
Click 'open' and your page should appear.<BR>
|
||||
|
||||
|
||||
<P>If the page doesn't open, go back over your notepad typing and make sure that all the HTML tags are correct. Check there are no spaces between tags and internal text; check that all tags are closed; check that you haven't written < HTLM > or < BDDY >. Your page will work eventually.
|
||||
<P>
|
||||
Make another page. Call it somethingdifferent.html and place it in the same WEBPAGES folder as detailed above.
|
||||
<P>start formatting in <A HREF="webpage2.html">lesson two</A>
|
||||
<BR><A HREF="col3.html">back to wws index</A> </P>
|
||||
</P>
|
||||
|
||||
|
||||
</DIV>
|
||||
|
||||
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
`
|
|
@ -16,7 +16,7 @@ import (
|
|||
|
||||
api "github.com/documize/community/core/convapi"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
"context"
|
||||
)
|
||||
|
||||
// Convert provides the standard interface for conversion of a ".documizeapi" json document.
|
||||
|
|
|
@ -16,9 +16,9 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
"context"
|
||||
api "github.com/documize/community/core/convapi"
|
||||
"github.com/documize/community/core/stringutil"
|
||||
"golang.org/x/net/context"
|
||||
"golang.org/x/net/html"
|
||||
"golang.org/x/net/html/atom"
|
||||
)
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
|
||||
"github.com/documize/blackfriday"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
"context"
|
||||
)
|
||||
|
||||
// Convert provides the standard interface for conversion of a Markdown document.
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
"github.com/documize/community/core/api/convert/html"
|
||||
"github.com/documize/community/core/api/convert/md"
|
||||
api "github.com/documize/community/core/convapi"
|
||||
"github.com/documize/community/domain"
|
||||
"github.com/documize/community/domain/store"
|
||||
"github.com/documize/glick"
|
||||
)
|
||||
|
||||
|
@ -49,7 +49,7 @@ var Lib *glick.Library
|
|||
|
||||
// Setup configures the global library at Lib,
|
||||
// largely based on the "config.json" file. It should be called only once.
|
||||
func Setup(s *domain.Store) error {
|
||||
func Setup(s *store.Store) error {
|
||||
if insecure == "true" {
|
||||
glick.InsecureSkipVerifyTLS = true
|
||||
}
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSetup(t *testing.T) {
|
||||
err := LibSetup()
|
||||
if err == nil {
|
||||
//t.Error("should error on non-existent config file")
|
||||
//t.Fail()
|
||||
}
|
||||
ssc, err := Lib.Actions("Convert")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// TODO(Elliott) review for empty database
|
||||
//if len(ssc) > 3 {
|
||||
// t.Errorf("extra convert formats:%v", ssc)
|
||||
//}
|
||||
|
||||
/* this code leaves plugins still running */
|
||||
err = os.Chdir("../../..")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = LibSetup()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
ssc, err = Lib.Actions("Convert")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if len(ssc) == 0 {
|
||||
t.Error("no extra convert formats (defined)")
|
||||
}
|
||||
err = os.Chdir("documize/api/plugins")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
err = Lib.KillSubProcs()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
70
core/asset/assets.go
Normal file
70
core/asset/assets.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
package asset
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"errors"
|
||||
"io"
|
||||
"io/fs"
|
||||
"mime"
|
||||
"net/http"
|
||||
"path"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
// GetPublicFileSystem
|
||||
func GetPublicFileSystem(e embed.FS) (hfs http.FileSystem, err error) {
|
||||
fsys, err := fs.Sub(e, "static/public")
|
||||
if err != nil {
|
||||
return nil, errors.New("failed GetPublicFileSystem")
|
||||
}
|
||||
|
||||
return http.FS(fsys), nil
|
||||
}
|
||||
|
||||
// FetchStatic loads static asset from embed file system.
|
||||
func FetchStatic(e embed.FS, filename string) (content, contentType string, err error) {
|
||||
data, err := e.ReadFile("static/" + filename)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
contentType = mime.TypeByExtension(filepath.Ext(filename))
|
||||
content = string(data)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// FetchStaticDir returns filenames within specified directory
|
||||
func FetchStaticDir(fs embed.FS, directory string) (files []string, err error) {
|
||||
entries, err := fs.ReadDir("static/" + directory)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for i := range entries {
|
||||
if !entries[i].Type().IsDir() {
|
||||
files = append(files, entries[i].Name())
|
||||
}
|
||||
}
|
||||
|
||||
return files, nil
|
||||
}
|
||||
|
||||
// WriteStatic loads static asset from embed file system and writes to HTTP.
|
||||
func WriteStatic(fs embed.FS, prefix, requestedPath string, w http.ResponseWriter) error {
|
||||
f, err := fs.Open(path.Join(prefix, requestedPath))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
stat, _ := f.Stat()
|
||||
if stat.IsDir() {
|
||||
return errors.New("cannot write static file")
|
||||
}
|
||||
|
||||
contentType := mime.TypeByExtension(filepath.Ext(requestedPath))
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
_, err = io.Copy(w, f)
|
||||
return err
|
||||
}
|
|
@ -12,191 +12,85 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/documize/community/core/env"
|
||||
"github.com/documize/community/core/streamutil"
|
||||
"github.com/documize/community/server/web"
|
||||
)
|
||||
|
||||
var dbCheckOK bool // default false
|
||||
|
||||
// Check that the database is configured correctly and that all the required tables exist.
|
||||
// It must be the first function called in this package.
|
||||
func Check(runtime *env.Runtime) bool {
|
||||
runtime.Log.Info("Database checks: started")
|
||||
runtime.Log.Info("Database: checking state")
|
||||
|
||||
csBits := strings.Split(runtime.Flags.DBConn, "/")
|
||||
if len(csBits) > 1 {
|
||||
web.SiteInfo.DBname = strings.Split(csBits[len(csBits)-1], "?")[0]
|
||||
}
|
||||
web.SiteInfo.DBname = runtime.StoreProvider.DatabaseName()
|
||||
|
||||
rows, err := runtime.Db.Query("SELECT VERSION() AS version, @@version_comment as comment, @@character_set_database AS charset, @@collation_database AS collation")
|
||||
rows, err := runtime.Db.Query(runtime.StoreProvider.QueryMeta())
|
||||
if err != nil {
|
||||
runtime.Log.Error("Can't get MySQL configuration", err)
|
||||
web.SiteInfo.Issue = "Can't get MySQL configuration: " + err.Error()
|
||||
runtime.Log.Error("Database: unable to load meta information from database provider", err)
|
||||
web.SiteInfo.Issue = "Unable to load meta information from database provider: " + err.Error()
|
||||
runtime.Flags.SiteMode = env.SiteModeBadDB
|
||||
return false
|
||||
}
|
||||
|
||||
defer streamutil.Close(rows)
|
||||
var version, dbComment, charset, collation string
|
||||
if rows.Next() {
|
||||
err = rows.Scan(&version, &dbComment, &charset, &collation)
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
err = rows.Err() // get any error encountered during iteration
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
runtime.Log.Error("no MySQL configuration returned", err)
|
||||
web.SiteInfo.Issue = "no MySQL configuration return issue: " + err.Error()
|
||||
runtime.Log.Error("Database: no meta data returned by database provider", err)
|
||||
web.SiteInfo.Issue = "No meta data returned by database provider: " + err.Error()
|
||||
runtime.Flags.SiteMode = env.SiteModeBadDB
|
||||
return false
|
||||
}
|
||||
|
||||
// Get SQL variant as this affects minimum version checking logic.
|
||||
// MySQL and Percona share same version scheme (e..g 5.7.10).
|
||||
// MariaDB starts at 10.2.x
|
||||
runtime.DbVariant = GetSQLVariant(runtime.Flags.DBType, dbComment)
|
||||
runtime.Log.Info(fmt.Sprintf("Database checks: SQL variant %v", runtime.DbVariant))
|
||||
runtime.Log.Info("Database checks: SQL version " + version)
|
||||
runtime.Log.Info(fmt.Sprintf("Database: provider name %v", runtime.StoreProvider.Type()))
|
||||
runtime.Log.Info(fmt.Sprintf("Database: provider version %s", version))
|
||||
|
||||
verNums, err := GetSQLVersion(version)
|
||||
if err != nil {
|
||||
runtime.Log.Error("Database version check failed", err)
|
||||
// Version OK?
|
||||
versionOK, minVersion := runtime.StoreProvider.VerfiyVersion(version)
|
||||
if !versionOK {
|
||||
msg := fmt.Sprintf("*** ERROR: database version needs to be %s or above ***", minVersion)
|
||||
runtime.Log.Info(msg)
|
||||
web.SiteInfo.Issue = msg
|
||||
runtime.Flags.SiteMode = env.SiteModeBadDB
|
||||
return false
|
||||
}
|
||||
|
||||
// Check minimum MySQL version as we need JSON column type.
|
||||
verInts := []int{5, 7, 10} // Minimum MySQL version
|
||||
if runtime.DbVariant == env.DBVariantMariaDB {
|
||||
verInts = []int{10, 3, 0} // Minimum MariaDB version
|
||||
// Character set and collation OK?
|
||||
charOK, charRequired := runtime.StoreProvider.VerfiyCharacterCollation(charset, collation)
|
||||
if !charOK {
|
||||
msg := fmt.Sprintf("*** ERROR: %s ***", charRequired)
|
||||
runtime.Log.Info(msg)
|
||||
web.SiteInfo.Issue = msg
|
||||
runtime.Flags.SiteMode = env.SiteModeBadDB
|
||||
return false
|
||||
}
|
||||
|
||||
for k, v := range verInts {
|
||||
// If major release is higher then skip minor/patch checks (e.g. 8.x.x > 5.x.x)
|
||||
if k == 0 && len(verNums) > 0 && verNums[0] > verInts[0] {
|
||||
break
|
||||
}
|
||||
if verNums[k] < v {
|
||||
want := fmt.Sprintf("%d.%d.%d", verInts[0], verInts[1], verInts[2])
|
||||
runtime.Log.Error("MySQL version element "+strconv.Itoa(k+1)+" of '"+version+"' not high enough, need at least version "+want, errors.New("bad MySQL version"))
|
||||
web.SiteInfo.Issue = "MySQL version element " + strconv.Itoa(k+1) + " of '" + version + "' not high enough, need at least version " + want
|
||||
runtime.Flags.SiteMode = env.SiteModeBadDB
|
||||
return false
|
||||
}
|
||||
// if there are no rows in the database, enter set-up mode
|
||||
var flds []string
|
||||
if err := runtime.Db.Select(&flds, runtime.StoreProvider.QueryTableList()); err != nil {
|
||||
msg := fmt.Sprintf("Database: unable to get database table list ")
|
||||
runtime.Log.Error(msg, err)
|
||||
web.SiteInfo.Issue = msg + err.Error()
|
||||
runtime.Flags.SiteMode = env.SiteModeBadDB
|
||||
return false
|
||||
}
|
||||
|
||||
{ // check the MySQL character set and collation
|
||||
if charset != "utf8" && charset != "utf8mb4" {
|
||||
runtime.Log.Error("MySQL character set not utf8/utf8mb4:", errors.New(charset))
|
||||
web.SiteInfo.Issue = "MySQL character set not utf8/utf8mb4: " + charset
|
||||
runtime.Flags.SiteMode = env.SiteModeBadDB
|
||||
return false
|
||||
}
|
||||
if !strings.HasPrefix(collation, "utf8") {
|
||||
runtime.Log.Error("MySQL collation sequence not utf8...:", errors.New(collation))
|
||||
web.SiteInfo.Issue = "MySQL collation sequence not utf8...: " + collation
|
||||
runtime.Flags.SiteMode = env.SiteModeBadDB
|
||||
return false
|
||||
}
|
||||
if len(flds) <= 5 {
|
||||
runtime.Log.Info("Database: starting setup mode for empty database")
|
||||
runtime.Flags.SiteMode = env.SiteModeSetup
|
||||
return false
|
||||
}
|
||||
|
||||
{ // if there are no rows in the database, enter set-up mode
|
||||
var flds []string
|
||||
if err := runtime.Db.Select(&flds,
|
||||
`SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '`+web.SiteInfo.DBname+
|
||||
`' and TABLE_TYPE='BASE TABLE'`); err != nil {
|
||||
runtime.Log.Error("Can't get MySQL number of tables", err)
|
||||
web.SiteInfo.Issue = "Can't get MySQL number of tables: " + err.Error()
|
||||
runtime.Flags.SiteMode = env.SiteModeBadDB
|
||||
return false
|
||||
}
|
||||
if strings.TrimSpace(flds[0]) == "0" {
|
||||
runtime.Log.Info("Entering database set-up mode because the database is empty.....")
|
||||
runtime.Flags.SiteMode = env.SiteModeSetup
|
||||
return false
|
||||
}
|
||||
}
|
||||
// We have good database, so proceed with app boot process.
|
||||
runtime.Flags.SiteMode = env.SiteModeNormal
|
||||
web.SiteInfo.DBname = ""
|
||||
|
||||
{ // check all the required tables exist
|
||||
var tables = []string{`account`,
|
||||
`attachment`, `document`,
|
||||
`label`, `organization`,
|
||||
`page`, `revision`, `search`, `user`}
|
||||
|
||||
for _, table := range tables {
|
||||
var dummy []string
|
||||
if err := runtime.Db.Select(&dummy, "SELECT 1 FROM "+table+" LIMIT 1;"); err != nil {
|
||||
runtime.Log.Error("Entering bad database mode because: SELECT 1 FROM "+table+" LIMIT 1;", err)
|
||||
web.SiteInfo.Issue = "MySQL database is not empty, but does not contain table: " + table
|
||||
runtime.Flags.SiteMode = env.SiteModeBadDB
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
runtime.Flags.SiteMode = env.SiteModeNormal // actually no need to do this (as already ""), this for documentation
|
||||
web.SiteInfo.DBname = "" // do not give this info when not in set-up mode
|
||||
dbCheckOK = true
|
||||
return true
|
||||
}
|
||||
|
||||
// GetSQLVariant uses database value form @@version_comment to deduce MySQL variant.
|
||||
func GetSQLVariant(dbType, vc string) env.DbVariant {
|
||||
vc = strings.ToLower(vc)
|
||||
dbType = strings.ToLower(dbType)
|
||||
|
||||
// determine type from database
|
||||
if strings.Contains(vc, "mariadb") {
|
||||
return env.DBVariantMariaDB
|
||||
} else if strings.Contains(vc, "percona") {
|
||||
return env.DBVariantPercona
|
||||
} else if strings.Contains(vc, "mysql") {
|
||||
return env.DbVariantMySQL
|
||||
}
|
||||
|
||||
// now determine type from command line switch
|
||||
if strings.Contains(dbType, "mariadb") {
|
||||
return env.DBVariantMariaDB
|
||||
} else if strings.Contains(dbType, "percona") {
|
||||
return env.DBVariantPercona
|
||||
} else if strings.Contains(dbType, "mysql") {
|
||||
return env.DbVariantMySQL
|
||||
}
|
||||
|
||||
// horrid default could cause app to crash
|
||||
return env.DbVariantMySQL
|
||||
}
|
||||
|
||||
// GetSQLVersion returns SQL version as major,minor,patch numerics.
|
||||
func GetSQLVersion(v string) (ints []int, err error) {
|
||||
ints = []int{0, 0, 0}
|
||||
|
||||
pos := strings.Index(v, "-")
|
||||
if pos > 1 {
|
||||
v = v[:pos]
|
||||
}
|
||||
|
||||
vs := strings.Split(v, ".")
|
||||
|
||||
if len(vs) < 3 {
|
||||
err = errors.New("MySQL version not of the form a.b.c")
|
||||
return
|
||||
}
|
||||
|
||||
for key, val := range vs {
|
||||
num, err := strconv.Atoi(val)
|
||||
|
||||
if err != nil {
|
||||
return ints, err
|
||||
}
|
||||
|
||||
ints[key] = num
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
package database
|
||||
|
||||
import "testing"
|
||||
|
||||
// go test github.com/documize/community/core/database -run TestGetVersion
|
||||
func TestGetVersion(t *testing.T) {
|
||||
ts2(t, "5.7.10", []int{5, 7, 10})
|
||||
ts2(t, "5.7.10-log", []int{5, 7, 10})
|
||||
ts2(t, "5.7.10-demo", []int{5, 7, 10})
|
||||
ts2(t, "5.7.10-debug", []int{5, 7, 10})
|
||||
ts2(t, "5.7.16-10", []int{5, 7, 16})
|
||||
ts2(t, "5.7.12-0ubuntu0-12.12.3", []int{5, 7, 12})
|
||||
ts2(t, "10.1.20-MariaDB-1~jessie", []int{10, 1, 20})
|
||||
ts2(t, "ubuntu0-12.12.3", []int{0, 0, 0})
|
||||
ts2(t, "junk-string", []int{0, 0, 0})
|
||||
ts2(t, "somethingstring", []int{0, 0, 0})
|
||||
}
|
||||
|
||||
func ts2(t *testing.T, in string, out []int) {
|
||||
got, _ := GetSQLVersion(in)
|
||||
|
||||
// if err != nil {
|
||||
// t.Errorf("Unable to GetSQLVersion %s", err)
|
||||
// }
|
||||
|
||||
for k, v := range got {
|
||||
if v != out[k] {
|
||||
t.Errorf("version input of %s got %d for position %d but expected %d\n", in, v, k, out[k])
|
||||
}
|
||||
}
|
||||
}
|
74
core/database/db_test.go
Normal file
74
core/database/db_test.go
Normal file
|
@ -0,0 +1,74 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
package database
|
||||
|
||||
import (
|
||||
"github.com/documize/community/core/env"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// go test github.com/documize/community/core/database -run TestGetVersion
|
||||
// func TestGetVersion(t *testing.T) {
|
||||
// ts2(t, "5.7.10", []int{5, 7, 10})
|
||||
// ts2(t, "5.7.10-log", []int{5, 7, 10})
|
||||
// ts2(t, "5.7.10-demo", []int{5, 7, 10})
|
||||
// ts2(t, "5.7.10-debug", []int{5, 7, 10})
|
||||
// ts2(t, "5.7.16-10", []int{5, 7, 16})
|
||||
// ts2(t, "5.7.12-0ubuntu0-12.12.3", []int{5, 7, 12})
|
||||
// ts2(t, "10.1.20-MariaDB-1~jessie", []int{10, 1, 20})
|
||||
// ts2(t, "ubuntu0-12.12.3", []int{0, 0, 0})
|
||||
// ts2(t, "junk-string", []int{0, 0, 0})
|
||||
// ts2(t, "somethingstring", []int{0, 0, 0})
|
||||
// }
|
||||
|
||||
// func ts2(t *testing.T, in string, out []int) {
|
||||
// got, _ := GetSQLVersion(in)
|
||||
|
||||
// // if err != nil {
|
||||
// // t.Errorf("Unable to GetSQLVersion %s", err)
|
||||
// // }
|
||||
|
||||
// for k, v := range got {
|
||||
// if v != out[k] {
|
||||
// t.Errorf("version input of %s got %d for position %d but expected %d\n", in, v, k, out[k])
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
func TestDatabaseVersionLegacy(t *testing.T) {
|
||||
i := extractVersionNumber("db_00021.sql")
|
||||
if i != 21 {
|
||||
t.Errorf("expected 21 got %d", i)
|
||||
}
|
||||
|
||||
i = extractVersionNumber("db_000.sql")
|
||||
if i != 0 {
|
||||
t.Errorf("expected 0 got %d", i)
|
||||
}
|
||||
|
||||
i = extractVersionNumber("26")
|
||||
if i != 26 {
|
||||
t.Errorf("expected 26 got %d", i)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParamRebind(t *testing.T) {
|
||||
q1in := "INSERT INTO dmz_org (c_refid, c_company, c_title) VALUES (?, ?, ?)"
|
||||
q1out := "INSERT INTO dmz_org (c_refid, c_company, c_title) VALUES ($1, $2, $3)"
|
||||
|
||||
test1 := RebindParams(q1in, env.StoreTypePostgreSQL)
|
||||
if test1 != q1out {
|
||||
t.Errorf("expected %s got %s", q1in, test1)
|
||||
}
|
||||
|
||||
t.Log(test1)
|
||||
}
|
|
@ -1,253 +0,0 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
package database
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/documize/community/core/api/plugins"
|
||||
"github.com/documize/community/core/env"
|
||||
"github.com/documize/community/core/secrets"
|
||||
"github.com/documize/community/core/stringutil"
|
||||
"github.com/documize/community/core/uniqueid"
|
||||
"github.com/documize/community/domain"
|
||||
"github.com/documize/community/server/web"
|
||||
)
|
||||
|
||||
// Handler contains the runtime information such as logging and database.
|
||||
type Handler struct {
|
||||
Runtime *env.Runtime
|
||||
Store *domain.Store
|
||||
}
|
||||
|
||||
// Setup the tables in a blank database
|
||||
func (h *Handler) Setup(w http.ResponseWriter, r *http.Request) {
|
||||
defer func() {
|
||||
target := "/setup"
|
||||
status := http.StatusBadRequest
|
||||
|
||||
if h.Runtime.Flags.SiteMode == env.SiteModeNormal {
|
||||
target = "/"
|
||||
status = http.StatusOK
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("GET", target, nil)
|
||||
if err != nil {
|
||||
h.Runtime.Log.Error("database.Setup error in defer ", err)
|
||||
}
|
||||
|
||||
http.Redirect(w, req, target, status)
|
||||
}()
|
||||
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
h.Runtime.Log.Error("database.Setup r.ParseForm()", err)
|
||||
return
|
||||
}
|
||||
|
||||
dbname := r.Form.Get("dbname")
|
||||
dbhash := r.Form.Get("dbhash")
|
||||
|
||||
if dbname != web.SiteInfo.DBname || dbhash != web.SiteInfo.DBhash {
|
||||
h.Runtime.Log.Error("database.Setup security credentials error ", errors.New("bad db name or validation code"))
|
||||
return
|
||||
}
|
||||
|
||||
details := onboardRequest{
|
||||
URL: "",
|
||||
Company: r.Form.Get("title"),
|
||||
CompanyLong: r.Form.Get("title"),
|
||||
Message: r.Form.Get("message"),
|
||||
Email: r.Form.Get("email"),
|
||||
Password: r.Form.Get("password"),
|
||||
Firstname: r.Form.Get("firstname"),
|
||||
Lastname: r.Form.Get("lastname"),
|
||||
Revised: time.Now().UTC(),
|
||||
}
|
||||
|
||||
if details.Company == "" ||
|
||||
details.CompanyLong == "" ||
|
||||
details.Message == "" ||
|
||||
details.Email == "" ||
|
||||
details.Password == "" ||
|
||||
details.Firstname == "" ||
|
||||
details.Lastname == "" {
|
||||
h.Runtime.Log.Error("database.Setup error ", errors.New("required field in database set-up form blank"))
|
||||
return
|
||||
}
|
||||
|
||||
if err = Migrate(h.Runtime, false /* no tables exist yet */); err != nil {
|
||||
h.Runtime.Log.Error("database.Setup migrate", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = setupAccount(h.Runtime, details, secrets.GenerateSalt())
|
||||
if err != nil {
|
||||
h.Runtime.Log.Error("database.Setup setup account ", err)
|
||||
return
|
||||
}
|
||||
|
||||
h.Runtime.Flags.SiteMode = env.SiteModeNormal
|
||||
|
||||
err = plugins.Setup(h.Store)
|
||||
if err != nil {
|
||||
h.Runtime.Log.Error("database.Setup plugin setup failed", err)
|
||||
}
|
||||
}
|
||||
|
||||
// The result of completing the onboarding process.
|
||||
type onboardRequest struct {
|
||||
URL string
|
||||
Company string
|
||||
CompanyLong string
|
||||
Message string
|
||||
Email string
|
||||
Password string
|
||||
Firstname string
|
||||
Lastname string
|
||||
Revised time.Time
|
||||
}
|
||||
|
||||
// setupAccount prepares the database for a newly onboard customer.
|
||||
// Once done, they can then login and use Documize.
|
||||
func setupAccount(rt *env.Runtime, completion onboardRequest, serial string) (err error) {
|
||||
//accountTitle := "This is where you will find documentation for your all projects. You can customize this message from the settings screen."
|
||||
salt := secrets.GenerateSalt()
|
||||
password := secrets.GeneratePassword(completion.Password, salt)
|
||||
|
||||
// Allocate organization to the user.
|
||||
orgID := uniqueid.Generate()
|
||||
|
||||
sql := fmt.Sprintf("insert into organization (refid, company, title, message, domain, email, serial) values (\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\")",
|
||||
orgID, completion.Company, completion.CompanyLong, completion.Message, completion.URL, completion.Email, serial)
|
||||
_, err = runSQL(rt, sql)
|
||||
|
||||
if err != nil {
|
||||
rt.Log.Error("Failed to insert into organization", err)
|
||||
return
|
||||
}
|
||||
|
||||
userID := uniqueid.Generate()
|
||||
|
||||
sql = fmt.Sprintf("insert into user (refid, firstname, lastname, email, initials, salt, password, global) values (\"%s\",\"%s\", \"%s\", \"%s\", \"%s\", \"%s\", \"%s\", 1)",
|
||||
userID, completion.Firstname, completion.Lastname, completion.Email, stringutil.MakeInitials(completion.Firstname, completion.Lastname), salt, password)
|
||||
_, err = runSQL(rt, sql)
|
||||
|
||||
if err != nil {
|
||||
rt.Log.Error("Failed with error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// Link user to organization.
|
||||
accountID := uniqueid.Generate()
|
||||
sql = fmt.Sprintf("insert into account (refid, userid, orgid, `admin`, editor, users, analytics) values (\"%s\", \"%s\", \"%s\", 1, 1, 1, 1)", accountID, userID, orgID)
|
||||
_, err = runSQL(rt, sql)
|
||||
|
||||
if err != nil {
|
||||
rt.Log.Error("Failed with error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// create space
|
||||
labelID := uniqueid.Generate()
|
||||
sql = fmt.Sprintf("insert into label (refid, orgid, label, type, userid) values (\"%s\", \"%s\", \"My Project\", 2, \"%s\")", labelID, orgID, userID)
|
||||
_, err = runSQL(rt, sql)
|
||||
if err != nil {
|
||||
rt.Log.Error("insert into label failed", err)
|
||||
}
|
||||
|
||||
// assign permissions to space
|
||||
perms := []string{"view", "manage", "own", "doc-add", "doc-edit", "doc-delete", "doc-move", "doc-copy", "doc-template", "doc-approve", "doc-version", "doc-lifecycle"}
|
||||
for _, p := range perms {
|
||||
sql = fmt.Sprintf("insert into permission (orgid, who, whoid, action, scope, location, refid) values (\"%s\", 'user', \"%s\", \"%s\", 'object', 'space', \"%s\")", orgID, userID, p, labelID)
|
||||
_, err = runSQL(rt, sql)
|
||||
if err != nil {
|
||||
rt.Log.Error("insert into permission failed", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Create some user groups
|
||||
groupDevID := uniqueid.Generate()
|
||||
sql = fmt.Sprintf("INSERT INTO role (refid, orgid, role, purpose) VALUES (\"%s\", \"%s\", \"Technology\", \"On-site and remote development teams\")", groupDevID, orgID)
|
||||
_, err = runSQL(rt, sql)
|
||||
if err != nil {
|
||||
rt.Log.Error("insert into role failed", err)
|
||||
}
|
||||
|
||||
groupProjectID := uniqueid.Generate()
|
||||
sql = fmt.Sprintf("INSERT INTO role (refid, orgid, role, purpose) VALUES (\"%s\", \"%s\", \"Project Management\", \"HQ project management\")", groupProjectID, orgID)
|
||||
_, err = runSQL(rt, sql)
|
||||
if err != nil {
|
||||
rt.Log.Error("insert into role failed", err)
|
||||
}
|
||||
|
||||
groupBackofficeID := uniqueid.Generate()
|
||||
sql = fmt.Sprintf("INSERT INTO role (refid, orgid, role, purpose) VALUES (\"%s\", \"%s\", \"Back Office\", \"Non-IT and PMO personnel\")", groupBackofficeID, orgID)
|
||||
_, err = runSQL(rt, sql)
|
||||
if err != nil {
|
||||
rt.Log.Error("insert into role failed", err)
|
||||
}
|
||||
|
||||
// Join some groups
|
||||
sql = fmt.Sprintf("INSERT INTO rolemember (orgid, roleid, userid) VALUES (\"%s\", \"%s\", \"%s\")", orgID, groupDevID, userID)
|
||||
_, err = runSQL(rt, sql)
|
||||
if err != nil {
|
||||
rt.Log.Error("insert into rolemember failed", err)
|
||||
}
|
||||
sql = fmt.Sprintf("INSERT INTO rolemember (orgid, roleid, userid) VALUES (\"%s\", \"%s\", \"%s\")", orgID, groupProjectID, userID)
|
||||
_, err = runSQL(rt, sql)
|
||||
if err != nil {
|
||||
rt.Log.Error("insert into rolemember failed", err)
|
||||
}
|
||||
sql = fmt.Sprintf("INSERT INTO rolemember (orgid, roleid, userid) VALUES (\"%s\", \"%s\", \"%s\")", orgID, groupBackofficeID, userID)
|
||||
_, err = runSQL(rt, sql)
|
||||
if err != nil {
|
||||
rt.Log.Error("insert into rolemember failed", err)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// runSQL creates a transaction per call
|
||||
func runSQL(rt *env.Runtime, sql string) (id uint64, err error) {
|
||||
if strings.TrimSpace(sql) == "" {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
tx, err := rt.Db.Beginx()
|
||||
if err != nil {
|
||||
rt.Log.Error("runSql - failed to get transaction", err)
|
||||
return
|
||||
}
|
||||
|
||||
result, err := tx.Exec(sql)
|
||||
|
||||
if err != nil {
|
||||
tx.Rollback()
|
||||
rt.Log.Error("runSql - unable to run sql", err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = tx.Commit(); err != nil {
|
||||
rt.Log.Error("runSql - unable to commit sql", err)
|
||||
return
|
||||
}
|
||||
|
||||
tempID, _ := result.LastInsertId()
|
||||
id = uint64(tempID)
|
||||
|
||||
return
|
||||
}
|
232
core/database/installer.go
Normal file
232
core/database/installer.go
Normal file
|
@ -0,0 +1,232 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
package database
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/documize/community/core/env"
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
// InstallUpgrade creates new database or upgrades existing database.
|
||||
func InstallUpgrade(runtime *env.Runtime, existingDB bool) (err error) {
|
||||
// amLeader := false
|
||||
|
||||
// Get all SQL scripts.
|
||||
scripts, err := LoadScripts(runtime)
|
||||
if err != nil {
|
||||
runtime.Log.Error("Database: unable to load scripts", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Get current database version.
|
||||
currentVersion := 0
|
||||
if existingDB {
|
||||
currentVersion, err = CurrentVersion(runtime)
|
||||
if err != nil {
|
||||
runtime.Log.Error("Database: unable to get current version", err)
|
||||
return
|
||||
}
|
||||
|
||||
runtime.Log.Info(fmt.Sprintf("Database: current version number is %d", currentVersion))
|
||||
}
|
||||
|
||||
// Filter out database specific scripts.
|
||||
dbTypeScripts := SpecificScripts(runtime, scripts)
|
||||
if len(dbTypeScripts) == 0 {
|
||||
runtime.Log.Info(fmt.Sprintf("Database: unable to load scripts for database type %s", runtime.StoreProvider.Type()))
|
||||
return
|
||||
}
|
||||
|
||||
runtime.Log.Info(fmt.Sprintf("Database: loaded %d SQL scripts for provider %s", len(dbTypeScripts), runtime.StoreProvider.Type()))
|
||||
|
||||
// Make a list of scripts to execute based upon current database state.
|
||||
toProcess := []Script{}
|
||||
for _, s := range dbTypeScripts {
|
||||
if s.Version > currentVersion || currentVersion == 0 {
|
||||
toProcess = append(toProcess, s)
|
||||
}
|
||||
}
|
||||
|
||||
runtime.Log.Info(fmt.Sprintf("Database: %d scripts to process", len(toProcess)))
|
||||
|
||||
// For MySQL type there was major new schema introduced in v24.
|
||||
// We check for this release and bypass usual locking code
|
||||
// because tables have changed.
|
||||
legacyMigration := runtime.StoreProvider.Type() == env.StoreTypeMySQL &&
|
||||
currentVersion > 0 && currentVersion < 25 && len(toProcess) >= 26 && toProcess[len(toProcess)-1].Version == 25
|
||||
|
||||
if legacyMigration {
|
||||
// Bypass all DB locking/checking processes as these look for new schema
|
||||
// which we are about to install.
|
||||
toProcess = toProcess[len(toProcess)-1:]
|
||||
|
||||
runtime.Log.Info(fmt.Sprintf("Database: legacy schema has %d scripts to process", len(toProcess)))
|
||||
}
|
||||
|
||||
err = runScripts(runtime, toProcess)
|
||||
if err != nil {
|
||||
runtime.Log.Error("Database: error processing SQL scripts", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Run SQL scripts to instal or upgrade this database.
|
||||
// We do not use transactions for Microsoft SQL Server because
|
||||
// CREATE FULLTEXT CATALOG statement cannot be used inside a user transaction.
|
||||
func runScripts(runtime *env.Runtime, scripts []Script) (err error) {
|
||||
tx, err := runtime.Db.Beginx()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// We can have multiple scripts as each Documize database change has it's own SQL script.
|
||||
for _, script := range scripts {
|
||||
runtime.Log.Info(fmt.Sprintf("Database: processing SQL script %d", script.Version))
|
||||
|
||||
err = executeSQL(tx, runtime, script.Script)
|
||||
if err != nil {
|
||||
runtime.Log.Error(fmt.Sprintf("error executing SQL script %d", script.Version), err)
|
||||
if runtime.StoreProvider.Type() != env.StoreTypeSQLServer {
|
||||
tx.Rollback()
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Record the fact we have processed this database script version.
|
||||
if runtime.StoreProvider.Type() != env.StoreTypeSQLServer {
|
||||
_, err = tx.Exec(runtime.StoreProvider.QueryRecordVersionUpgrade(script.Version))
|
||||
} else {
|
||||
_, err = runtime.Db.Exec(runtime.StoreProvider.QueryRecordVersionUpgrade(script.Version))
|
||||
}
|
||||
if err != nil {
|
||||
// For MySQL we try the legacy DB schema.
|
||||
if runtime.StoreProvider.Type() == env.StoreTypeMySQL {
|
||||
runtime.Log.Info(fmt.Sprintf("Database: attempting legacy fallback for SQL script %d", script.Version))
|
||||
|
||||
_, err = tx.Exec(runtime.StoreProvider.QueryRecordVersionUpgradeLegacy(script.Version))
|
||||
if err != nil {
|
||||
runtime.Log.Error(fmt.Sprintf("error recording execution of SQL script %d", script.Version), err)
|
||||
if runtime.StoreProvider.Type() != env.StoreTypeSQLServer {
|
||||
tx.Rollback()
|
||||
}
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
// Unknown issue running script on non-MySQL database.
|
||||
runtime.Log.Error(fmt.Sprintf("error executing SQL script %d", script.Version), err)
|
||||
if runtime.StoreProvider.Type() != env.StoreTypeSQLServer {
|
||||
tx.Rollback()
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tx.Commit()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// executeSQL runs specified SQL commands.
|
||||
func executeSQL(tx *sqlx.Tx, runtime *env.Runtime, SQLfile []byte) error {
|
||||
// Turn SQL file contents into runnable SQL statements.
|
||||
stmts := getStatements(SQLfile)
|
||||
|
||||
for _, stmt := range stmts {
|
||||
// MariaDB has no specific JSON column type (but has JSON queries)
|
||||
if runtime.StoreProvider.Type() == env.StoreTypeMySQL &&
|
||||
runtime.StoreProvider.TypeVariant() == env.StoreTypeMariaDB {
|
||||
stmt = strings.Replace(stmt, "` JSON", "` TEXT", -1)
|
||||
}
|
||||
|
||||
var err error
|
||||
if runtime.StoreProvider.Type() != env.StoreTypeSQLServer {
|
||||
_, err = tx.Exec(stmt)
|
||||
} else {
|
||||
_, err = runtime.Db.Exec(stmt)
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Println("sql statement error:", stmt)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getStatement strips out the comments and returns all the individual SQL commands (apart from "USE") as a []string.
|
||||
func getStatements(bytes []byte) (stmts []string) {
|
||||
// Strip comments of the form '-- comment' or like this one /**/
|
||||
stripped := regexp.MustCompile("(?s)--.*?\n|/\\*.*?\\*/").ReplaceAll(bytes, []byte("\n"))
|
||||
|
||||
// Break into lines using ; terminator.
|
||||
lines := strings.Split(string(stripped), ";")
|
||||
|
||||
// Prepare return data.
|
||||
stmts = make([]string, 0, len(lines))
|
||||
|
||||
for _, v := range lines {
|
||||
trimmed := strings.TrimSpace(v)
|
||||
// Process non-empty lines and exclude "USE dbname" command
|
||||
if len(trimmed) > 0 && !strings.HasPrefix(strings.ToUpper(trimmed), "USE ") {
|
||||
stmts = append(stmts, trimmed+";")
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// CurrentVersion returns number that represents the current database version number.
|
||||
// For example 23 represents the 23rd iteration of the database.
|
||||
func CurrentVersion(runtime *env.Runtime) (version int, err error) {
|
||||
currentVersion := "0"
|
||||
|
||||
row := runtime.Db.QueryRow(runtime.StoreProvider.QueryGetDatabaseVersion())
|
||||
err = row.Scan(¤tVersion)
|
||||
if err != nil {
|
||||
// For MySQL we try the legacy DB checks.
|
||||
if runtime.StoreProvider.Type() == env.StoreTypeMySQL {
|
||||
row := runtime.Db.QueryRow(runtime.StoreProvider.QueryGetDatabaseVersionLegacy())
|
||||
err = row.Scan(¤tVersion)
|
||||
}
|
||||
}
|
||||
|
||||
return extractVersionNumber(currentVersion), nil
|
||||
}
|
||||
|
||||
// Turns legacy "db_00021.sql" and new "21" format into version number 21.
|
||||
func extractVersionNumber(s string) int {
|
||||
// Good practice in case of human tampering.
|
||||
s = strings.TrimSpace(s)
|
||||
s = strings.ToLower(s)
|
||||
|
||||
// Remove any quotes from JSON string.
|
||||
s = strings.Replace(s, "\"", "", -1)
|
||||
|
||||
// Remove legacy version string formatting.
|
||||
// We know just store the number.
|
||||
s = strings.Replace(s, "db_000", "", 1)
|
||||
s = strings.Replace(s, ".sql", "", 1)
|
||||
|
||||
i, err := strconv.Atoi(s)
|
||||
if err != nil {
|
||||
i = 0
|
||||
}
|
||||
|
||||
return i
|
||||
}
|
|
@ -1,281 +0,0 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
package database
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/documize/community/core/env"
|
||||
"github.com/documize/community/core/streamutil"
|
||||
"github.com/documize/community/server/web"
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
const migrationsDir = "bindata/scripts"
|
||||
|
||||
// migrationsT holds a list of migration sql files to run.
|
||||
type migrationsT []string
|
||||
|
||||
// migrations returns a list of the migrations to update the database as required for this version of the code.
|
||||
func migrations(lastMigration string) (migrationsT, error) {
|
||||
lastMigration = strings.TrimPrefix(strings.TrimSuffix(lastMigration, `"`), `"`)
|
||||
|
||||
files, err := web.AssetDir(migrationsDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sort.Strings(files)
|
||||
|
||||
ret := make(migrationsT, 0, len(files))
|
||||
|
||||
hadLast := false
|
||||
|
||||
if len(lastMigration) == 0 {
|
||||
hadLast = true
|
||||
}
|
||||
|
||||
for _, v := range files {
|
||||
if v == lastMigration {
|
||||
hadLast = true
|
||||
} else {
|
||||
if hadLast {
|
||||
ret = append(ret, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//fmt.Println(`DEBUG Migrations("`+lastMigration+`")=`,ret)
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// migrate the database as required, by applying the migrations.
|
||||
func (m migrationsT) migrate(runtime *env.Runtime, tx *sqlx.Tx) error {
|
||||
for _, v := range m {
|
||||
runtime.Log.Info("Processing migration file: " + v)
|
||||
|
||||
buf, err := web.Asset(migrationsDir + "/" + v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = processSQLfile(tx, runtime.DbVariant, buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
json := `{"database":"` + v + `"}`
|
||||
sql := "INSERT INTO `config` (`key`,`config`) " +
|
||||
"VALUES ('META','" + json +
|
||||
"') ON DUPLICATE KEY UPDATE `config`='" + json + "';"
|
||||
|
||||
_, err = tx.Exec(sql) // add a record in the config file to say we have done the upgrade
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func lockDB(runtime *env.Runtime) (bool, error) {
|
||||
b := make([]byte, 2)
|
||||
_, err := rand.Read(b)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
wait := ((time.Duration(b[0]) << 8) | time.Duration(b[1])) * time.Millisecond / 10 // up to 6.5 secs wait
|
||||
time.Sleep(wait)
|
||||
|
||||
tx, err := runtime.Db.Beginx()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
_, err = tx.Exec("LOCK TABLE `config` WRITE;")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
defer func() {
|
||||
_, err = tx.Exec("UNLOCK TABLES;")
|
||||
if err != nil {
|
||||
runtime.Log.Error("unable to unlock tables", err)
|
||||
}
|
||||
tx.Commit()
|
||||
}()
|
||||
|
||||
_, err = tx.Exec("INSERT INTO `config` (`key`,`config`) " +
|
||||
fmt.Sprintf(`VALUES ('DBLOCK','{"pid": "%d"}');`, os.Getpid()))
|
||||
if err != nil {
|
||||
// good error would be "Error 1062: Duplicate entry 'DBLOCK' for key 'idx_config_area'"
|
||||
if strings.HasPrefix(err.Error(), "Error 1062:") {
|
||||
runtime.Log.Info("Database locked by another Documize instance")
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
runtime.Log.Info("Database locked by this Documize instance")
|
||||
return true, err // success!
|
||||
}
|
||||
|
||||
func unlockDB(rt *env.Runtime) error {
|
||||
tx, err := rt.Db.Beginx()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = tx.Exec("DELETE FROM `config` WHERE `key`='DBLOCK';")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
func migrateEnd(runtime *env.Runtime, tx *sqlx.Tx, err error, amLeader bool) error {
|
||||
if amLeader {
|
||||
defer func() { unlockDB(runtime) }()
|
||||
if tx != nil {
|
||||
if err == nil {
|
||||
tx.Commit()
|
||||
runtime.Log.Info("Database checks: completed")
|
||||
return nil
|
||||
}
|
||||
tx.Rollback()
|
||||
}
|
||||
runtime.Log.Error("Database checks: failed: ", err)
|
||||
return err
|
||||
}
|
||||
return nil // not the leader, so ignore errors
|
||||
}
|
||||
|
||||
func getLastMigration(tx *sqlx.Tx) (lastMigration string, err error) {
|
||||
var stmt *sql.Stmt
|
||||
stmt, err = tx.Prepare("SELECT JSON_EXTRACT(`config`,'$.database') FROM `config` WHERE `key` = 'META';")
|
||||
if err == nil {
|
||||
defer streamutil.Close(stmt)
|
||||
var item = make([]uint8, 0)
|
||||
|
||||
row := stmt.QueryRow()
|
||||
|
||||
err = row.Scan(&item)
|
||||
if err == nil {
|
||||
if len(item) > 1 {
|
||||
q := []byte(`"`)
|
||||
lastMigration = string(bytes.TrimPrefix(bytes.TrimSuffix(item, q), q))
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Migrate the database as required, consolidated action.
|
||||
func Migrate(runtime *env.Runtime, ConfigTableExists bool) error {
|
||||
amLeader := false
|
||||
|
||||
if ConfigTableExists {
|
||||
var err error
|
||||
amLeader, err = lockDB(runtime)
|
||||
if err != nil {
|
||||
runtime.Log.Error("unable to lock DB", err)
|
||||
}
|
||||
} else {
|
||||
amLeader = true // what else can you do?
|
||||
}
|
||||
|
||||
tx, err := runtime.Db.Beginx()
|
||||
if err != nil {
|
||||
return migrateEnd(runtime, tx, err, amLeader)
|
||||
}
|
||||
|
||||
lastMigration := ""
|
||||
|
||||
if ConfigTableExists {
|
||||
lastMigration, err = getLastMigration(tx)
|
||||
if err != nil {
|
||||
return migrateEnd(runtime, tx, err, amLeader)
|
||||
}
|
||||
runtime.Log.Info("Database checks: last applied " + lastMigration)
|
||||
}
|
||||
|
||||
mig, err := migrations(lastMigration)
|
||||
if err != nil {
|
||||
return migrateEnd(runtime, tx, err, amLeader)
|
||||
}
|
||||
|
||||
if len(mig) == 0 {
|
||||
runtime.Log.Info("Database checks: no updates required")
|
||||
return migrateEnd(runtime, tx, nil, amLeader) // no migrations to perform
|
||||
}
|
||||
|
||||
if amLeader {
|
||||
runtime.Log.Info("Database checks: will execute the following update files: " + strings.Join([]string(mig), ", "))
|
||||
return migrateEnd(runtime, tx, mig.migrate(runtime, tx), amLeader)
|
||||
}
|
||||
|
||||
// a follower instance
|
||||
targetMigration := string(mig[len(mig)-1])
|
||||
for targetMigration != lastMigration {
|
||||
time.Sleep(time.Second)
|
||||
runtime.Log.Info("Waiting for database migration completion")
|
||||
tx.Rollback() // ignore error
|
||||
tx, err := runtime.Db.Beginx() // need this in order to see the changed situation since last tx
|
||||
if err != nil {
|
||||
return migrateEnd(runtime, tx, err, amLeader)
|
||||
}
|
||||
lastMigration, _ = getLastMigration(tx)
|
||||
}
|
||||
|
||||
return migrateEnd(runtime, tx, nil, amLeader)
|
||||
}
|
||||
|
||||
func processSQLfile(tx *sqlx.Tx, v env.DbVariant, buf []byte) error {
|
||||
stmts := getStatements(buf)
|
||||
|
||||
for _, stmt := range stmts {
|
||||
// MariaDB has no specific JSON column type (but has JSON queries)
|
||||
if v == env.DBVariantMariaDB {
|
||||
stmt = strings.Replace(stmt, "` JSON", "` TEXT", -1)
|
||||
}
|
||||
|
||||
_, err := tx.Exec(stmt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// getStatement strips out the comments and returns all the individual SQL commands (apart from "USE") as a []string.
|
||||
func getStatements(bytes []byte) []string {
|
||||
/* Strip comments of the form '-- comment' or like this one */
|
||||
stripped := regexp.MustCompile("(?s)--.*?\n|/\\*.*?\\*/").ReplaceAll(bytes, []byte("\n"))
|
||||
sqls := strings.Split(string(stripped), ";")
|
||||
ret := make([]string, 0, len(sqls))
|
||||
|
||||
for _, v := range sqls {
|
||||
trimmed := strings.TrimSpace(v)
|
||||
if len(trimmed) > 0 &&
|
||||
!strings.HasPrefix(strings.ToUpper(trimmed), "USE ") { // make sure we don't USE the wrong database
|
||||
ret = append(ret, trimmed+";")
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
41
core/database/params.go
Normal file
41
core/database/params.go
Normal file
|
@ -0,0 +1,41 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
package database
|
||||
|
||||
import (
|
||||
"github.com/documize/community/core/env"
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
// RebindParams changes MySQL query parameter placeholder from "?" to
|
||||
// correct value for given database provider.
|
||||
//
|
||||
// MySQL uses ?, ?, ? (default for all Documize queries)
|
||||
// PostgreSQL uses $1, $2, $3
|
||||
// MS SQL Server uses @p1, @p2, @p3
|
||||
func RebindParams(sql string, s env.StoreType) string {
|
||||
bindParam := sqlx.QUESTION
|
||||
|
||||
switch s {
|
||||
case env.StoreTypePostgreSQL:
|
||||
bindParam = sqlx.DOLLAR
|
||||
case env.StoreTypeSQLServer:
|
||||
bindParam = sqlx.AT
|
||||
}
|
||||
|
||||
return sqlx.Rebind(bindParam, sql)
|
||||
}
|
||||
|
||||
// RebindPostgreSQL is a helper method on top of RebindParams.
|
||||
func RebindPostgreSQL(sql string) string {
|
||||
return RebindParams(sql, env.StoreTypePostgreSQL)
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
|
||||
## PENDING REMOVALS
|
||||
|
||||
NONE
|
||||
|
||||
## MYSQL ENCODING
|
||||
|
||||
https://stackoverflow.com/questions/37307146/difference-between-utf8mb4-unicode-ci-and-utf8mb4-unicode-520-ci-collations-in-m
|
||||
|
||||
https://mathiasbynens.be/notes/mysql-utf8mb4
|
||||
|
||||
https://medium.com/@adamhooper/in-mysql-never-use-utf8-use-utf8mb4-11761243e434
|
||||
|
||||
## MIGRATE ENCODING
|
||||
|
||||
ALTER DATABASE documize CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE account CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE attachment CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE block CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE config CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE document CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE feedback CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE label CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE labelrole CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE link CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE organization CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE page CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE pagemeta CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE participant CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE pin CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE revision CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE search CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE share CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE user CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE useraction CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE useractivity CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE userconfig CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE userevent CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
91
core/database/scripts.go
Normal file
91
core/database/scripts.go
Normal file
|
@ -0,0 +1,91 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
package database
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/documize/community/core/asset"
|
||||
"github.com/documize/community/core/env"
|
||||
)
|
||||
|
||||
// Scripts holds all .SQL files for all supported database providers.
|
||||
type Scripts struct {
|
||||
MySQL []Script
|
||||
PostgreSQL []Script
|
||||
SQLServer []Script
|
||||
}
|
||||
|
||||
// Script holds SQL script and it's associated version number.
|
||||
type Script struct {
|
||||
Version int
|
||||
Script []byte
|
||||
}
|
||||
|
||||
// LoadScripts returns .SQL scripts for supported database providers.
|
||||
func LoadScripts(runtime *env.Runtime) (s Scripts, err error) {
|
||||
// MySQL
|
||||
s.MySQL, err = loadFiles(runtime.Assets, "scripts/mysql")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// PostgreSQL
|
||||
s.PostgreSQL, err = loadFiles(runtime.Assets, "scripts/postgresql")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// PostgreSQL
|
||||
s.SQLServer, err = loadFiles(runtime.Assets, "scripts/sqlserver")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// SpecificScripts returns SQL scripts for current databasse provider.
|
||||
func SpecificScripts(runtime *env.Runtime, all Scripts) (s []Script) {
|
||||
switch runtime.StoreProvider.Type() {
|
||||
case env.StoreTypeMySQL, env.StoreTypeMariaDB, env.StoreTypePercona:
|
||||
return all.MySQL
|
||||
case env.StoreTypePostgreSQL:
|
||||
return all.PostgreSQL
|
||||
case env.StoreTypeSQLServer:
|
||||
return all.SQLServer
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// loadFiles returns all SQL scripts in specified folder as [][]byte.
|
||||
func loadFiles(fs embed.FS, path string) (b []Script, err error) {
|
||||
scripts, err := asset.FetchStaticDir(fs, path)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
sort.Strings(scripts)
|
||||
|
||||
for i := range scripts {
|
||||
filename := scripts[i]
|
||||
sqlfile, _, err := asset.FetchStatic(fs, fmt.Sprintf("%s/%s", path, filename))
|
||||
if err != nil {
|
||||
return b, err
|
||||
}
|
||||
|
||||
b = append(b, Script{Version: extractVersionNumber(filename), Script: []byte(sqlfile)})
|
||||
}
|
||||
|
||||
return b, nil
|
||||
}
|
|
@ -1,3 +1,3 @@
|
|||
/* community edition */
|
||||
ALTER TABLE organization ADD COLUMN `service` VARCHAR(100) NOT NULL DEFAULT 'https://api.documize.com' AFTER `domain`;
|
||||
ALTER TABLE organization ADD COLUMN `service` VARCHAR(100) NOT NULL DEFAULT '' AFTER `domain`;
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
/* community edition */
|
||||
|
||||
ALTER DATABASE documize CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE account CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE attachment CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
||||
ALTER TABLE block CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;
|
10
core/database/scripts/mysql/db_00024.sql
Normal file
10
core/database/scripts/mysql/db_00024.sql
Normal file
|
@ -0,0 +1,10 @@
|
|||
/* community edition */
|
||||
|
||||
-- max tags per document setting
|
||||
ALTER TABLE organization ADD COLUMN `maxtags` INT NOT NULL DEFAULT 3 AFTER `authconfig`;
|
||||
|
||||
-- support for network location link types
|
||||
ALTER TABLE link ADD COLUMN `externalid` NVARCHAR(1000) NOT NULL DEFAULT '' AFTER `targetid`;
|
||||
|
||||
-- deprecations
|
||||
ALTER TABLE organization DROP COLUMN `url`;
|
335
core/database/scripts/mysql/db_00025.sql
Normal file
335
core/database/scripts/mysql/db_00025.sql
Normal file
|
@ -0,0 +1,335 @@
|
|||
/* community edition */
|
||||
|
||||
-- table renaming
|
||||
RENAME TABLE
|
||||
`organization` TO dmz_org,
|
||||
`label` TO dmz_space,
|
||||
`category` TO dmz_category,
|
||||
`categorymember` TO dmz_category_member,
|
||||
`role` TO dmz_group,
|
||||
`rolemember` TO dmz_group_member,
|
||||
`permission` TO dmz_permission,
|
||||
`document` TO dmz_doc,
|
||||
`share` TO dmz_doc_share,
|
||||
`vote` TO dmz_doc_vote,
|
||||
`feedback` TO dmz_doc_comment,
|
||||
`attachment` TO dmz_doc_attachment,
|
||||
`link` TO dmz_doc_link,
|
||||
`page` TO dmz_section,
|
||||
`pagemeta` TO dmz_section_meta,
|
||||
`block` TO dmz_section_template,
|
||||
`revision` TO dmz_section_revision,
|
||||
`user` TO dmz_user,
|
||||
`account` TO dmz_user_account,
|
||||
`useractivity` TO dmz_user_activity,
|
||||
`userconfig` TO dmz_user_config,
|
||||
`config` TO dmz_config,
|
||||
`pin` TO dmz_pin,
|
||||
`search` TO dmz_search,
|
||||
`userevent` TO dmz_audit_log,
|
||||
`useraction` TO dmz_action;
|
||||
|
||||
-- field renaming
|
||||
ALTER TABLE dmz_org
|
||||
CHANGE `refid` `c_refid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `company` `c_company` VARCHAR(500) NOT NULL,
|
||||
CHANGE `title` `c_title` VARCHAR(500) NOT NULL,
|
||||
CHANGE `message` `c_message` VARCHAR(500) NOT NULL,
|
||||
CHANGE `domain` `c_domain` VARCHAR(200) NOT NULL DEFAULT '',
|
||||
CHANGE `service` `c_service` VARCHAR(200) NOT NULL DEFAULT '',
|
||||
CHANGE `email` `c_email` VARCHAR(500) NOT NULL DEFAULT '',
|
||||
CHANGE `allowanonymousaccess` `c_anonaccess` BOOL NOT NULL DEFAULT 0,
|
||||
CHANGE `authprovider` `c_authprovider` CHAR(20) NOT NULL DEFAULT 'documize',
|
||||
CHANGE `authconfig` `c_authconfig` JSON,
|
||||
CHANGE `maxtags` `c_maxtags` INT NOT NULL DEFAULT 3,
|
||||
CHANGE `verified` `c_verified` BOOL NOT NULL DEFAULT 0,
|
||||
CHANGE `serial` `c_serial` VARCHAR(50) NOT NULL DEFAULT '',
|
||||
CHANGE `active` `c_active` BOOL NOT NULL DEFAULT 1,
|
||||
CHANGE `created` `c_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CHANGE `revised` `c_revised` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_space
|
||||
CHANGE `refid` `c_refid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `userid` `c_userid` VARCHAR(20) NOT NULL DEFAULT '',
|
||||
CHANGE `type` `c_type` INT NOT NULL DEFAULT 1,
|
||||
CHANGE `lifecycle` `c_lifecycle` INT NOT NULL DEFAULT 1,
|
||||
CHANGE `label` `c_name` VARCHAR(300) NOT NULL,
|
||||
CHANGE `likes` `c_likes` VARCHAR(1000) NOT NULL DEFAULT '',
|
||||
CHANGE `created` `c_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CHANGE `revised` `c_revised` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_category
|
||||
CHANGE `refid` `c_refid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `labelid` `c_spaceid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `category` `c_name` VARCHAR(50) NOT NULL,
|
||||
CHANGE `created` `c_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CHANGE `revised` `c_revised` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_category_member
|
||||
CHANGE `refid` `c_refid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `labelid` `c_spaceid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `categoryid` `c_categoryid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `documentid` `c_docid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `created` `c_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CHANGE `revised` `c_revised` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_group
|
||||
CHANGE `refid` `c_refid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `role` `c_name` VARCHAR(50) NOT NULL DEFAULT '',
|
||||
CHANGE `purpose` `c_desc` VARCHAR(100) DEFAULT '',
|
||||
CHANGE `created` `c_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CHANGE `revised` `c_revised` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_group_member
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `roleid` `c_groupid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `userid` `c_userid` VARCHAR(20) NOT NULL;
|
||||
|
||||
ALTER TABLE dmz_permission
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `who` `c_who` VARCHAR(30) NOT NULL,
|
||||
CHANGE `whoid` `c_whoid` VARCHAR(20) NOT NULL DEFAULT '',
|
||||
CHANGE `action` `c_action` VARCHAR(30) NOT NULL,
|
||||
CHANGE `scope` `c_scope` VARCHAR(30) NOT NULL,
|
||||
CHANGE `location` `c_location` VARCHAR(100) NOT NULL,
|
||||
CHANGE `refid` `c_refid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `created` `c_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_doc
|
||||
CHANGE `refid` `c_refid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `labelid` `c_spaceid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `userid` `c_userid` VARCHAR(20) NOT NULL DEFAULT '',
|
||||
CHANGE `job` `c_job` CHAR(36) NOT NULL DEFAULT '',
|
||||
CHANGE `location` `c_location` VARCHAR(2000) NOT NULL DEFAULT '',
|
||||
CHANGE `title` `c_name` VARCHAR(2000) NOT NULL DEFAULT '',
|
||||
CHANGE `excerpt` `c_desc` VARCHAR(2000) NOT NULL DEFAULT '',
|
||||
CHANGE `slug` `c_slug` VARCHAR(2000) NOT NULL DEFAULT '',
|
||||
CHANGE `tags` `c_tags` VARCHAR(1000) NOT NULL DEFAULT '',
|
||||
CHANGE `template` `c_template` BOOL NOT NULL DEFAULT 0,
|
||||
CHANGE `protection` `c_protection` INT NOT NULL DEFAULT 0,
|
||||
CHANGE `approval` `c_approval` INT NOT NULL DEFAULT 0,
|
||||
CHANGE `lifecycle` `c_lifecycle` INT NOT NULL DEFAULT 1,
|
||||
CHANGE `versioned` `c_versioned` BOOL NOT NULL DEFAULT 0,
|
||||
CHANGE `versionid` `c_versionid` VARCHAR(100) NOT NULL DEFAULT '',
|
||||
CHANGE `versionorder` `c_versionorder` INT NOT NULL DEFAULT 0,
|
||||
CHANGE `groupid` `c_groupid` VARCHAR(20) NOT NULL DEFAULT '',
|
||||
CHANGE `created` `c_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CHANGE `revised` `c_revised` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_doc_share
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `documentid` `c_docid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `userid` `c_userid` VARCHAR(20) DEFAULT '',
|
||||
CHANGE `email` `c_email` VARCHAR(250) NOT NULL DEFAULT '',
|
||||
CHANGE `message` `c_message` VARCHAR(500) NOT NULL DEFAULT '',
|
||||
CHANGE `viewed` `c_viewed` VARCHAR(500) NOT NULL DEFAULT '',
|
||||
CHANGE `secret` `c_secret` VARCHAR(250) NOT NULL DEFAULT '',
|
||||
CHANGE `expires` `c_expires` VARCHAR(20) DEFAULT '',
|
||||
CHANGE `active` `c_active` BOOL NOT NULL DEFAULT 1,
|
||||
CHANGE `created` `c_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_doc_vote
|
||||
CHANGE `refid` `c_refid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `documentid` `c_docid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `voter` `c_voter` VARCHAR(20) NOT NULL DEFAULT '',
|
||||
CHANGE `vote` `c_vote` INT NOT NULL DEFAULT 0,
|
||||
CHANGE `created` `c_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CHANGE `revised` `c_revised` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_doc_comment
|
||||
CHANGE `refid` `c_refid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `documentid` `c_docid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `userid` `c_userid` VARCHAR(20) DEFAULT '',
|
||||
CHANGE `email` `c_email` VARCHAR(250) NOT NULL DEFAULT '',
|
||||
CHANGE `feedback` `c_feedback` LONGTEXT,
|
||||
CHANGE `created` `c_created` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_doc_attachment
|
||||
CHANGE `refid` `c_refid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `documentid` `c_docid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `job` `c_job` CHAR(36) NOT NULL,
|
||||
CHANGE `fileid` `c_fileid` CHAR(10) NOT NULL,
|
||||
CHANGE `filename` `c_filename` VARCHAR(255) NOT NULL,
|
||||
CHANGE `data` `c_data` LONGBLOB,
|
||||
CHANGE `extension` `c_extension` CHAR(6) NOT NULL,
|
||||
CHANGE `created` `c_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
CHANGE `revised` `c_revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_doc_link
|
||||
CHANGE `refid` `c_refid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `folderid` `c_spaceid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `userid` `c_userid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `sourcedocumentid` `c_sourcedocid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `sourcepageid` `c_sourcesectionid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `linktype` `c_type` VARCHAR(20) NOT NULL,
|
||||
CHANGE `targetdocumentid` `c_targetdocid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `targetid` `c_targetid` VARCHAR(20) NOT NULL DEFAULT '',
|
||||
CHANGE `externalid` `c_externalid` VARCHAR(1000) NOT NULL DEFAULT '',
|
||||
CHANGE `orphan` `c_orphan` BOOL NOT NULL DEFAULT 0,
|
||||
CHANGE `created` `c_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
CHANGE `revised` `c_revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_section
|
||||
CHANGE `refid` `c_refid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `documentid` `c_docid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `userid` `c_userid` VARCHAR(20) NOT NULL DEFAULT '',
|
||||
CHANGE `pagetype` `c_type` CHAR(10) NOT NULL DEFAULT 'section',
|
||||
CHANGE `contenttype` `c_contenttype` CHAR(20) NOT NULL DEFAULT 'wysiwyg',
|
||||
CHANGE `blockid` `c_templateid` VARCHAR(20) NOT NULL DEFAULT '',
|
||||
CHANGE `level` `c_level` INT UNSIGNED NOT NULL,
|
||||
CHANGE `sequence` `c_sequence` DOUBLE NOT NULL,
|
||||
CHANGE `title` `c_name` VARCHAR(2000) NOT NULL DEFAULT '',
|
||||
CHANGE `body` `c_body` LONGTEXT,
|
||||
CHANGE `revisions` `c_revisions` INT UNSIGNED NOT NULL,
|
||||
CHANGE `status` `c_status` INT NOT NULL DEFAULT 0,
|
||||
CHANGE `relativeid` `c_relativeid` VARCHAR(20) NOT NULL DEFAULT '',
|
||||
CHANGE `created` `c_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
CHANGE `revised` `c_revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_section_meta
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `documentid` `c_docid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `userid` `c_userid` VARCHAR(20) NOT NULL DEFAULT '',
|
||||
CHANGE `pageid` `c_sectionid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `rawbody` `c_rawbody` LONGBLOB,
|
||||
CHANGE `config` `c_config` JSON,
|
||||
CHANGE `externalsource` `c_external` BOOL DEFAULT 0,
|
||||
CHANGE `created` `c_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
CHANGE `revised` `c_revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_section_template
|
||||
CHANGE `refid` `c_refid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `labelid` `c_spaceid` VARCHAR(20) DEFAULT '',
|
||||
CHANGE `userid` `c_userid` VARCHAR(20) DEFAULT '',
|
||||
CHANGE `pagetype` `c_type` CHAR(10) NOT NULL DEFAULT 'section',
|
||||
CHANGE `contenttype` `c_contenttype` CHAR(20) NOT NULL DEFAULT 'wysiwyg',
|
||||
CHANGE `title` `c_name` VARCHAR(2000) NOT NULL DEFAULT '',
|
||||
CHANGE `body` `c_body` LONGTEXT,
|
||||
CHANGE `excerpt` `c_desc` VARCHAR(2000) NOT NULL DEFAULT '',
|
||||
CHANGE `used` `c_used` INT UNSIGNED NOT NULL,
|
||||
CHANGE `rawbody` `c_rawbody` LONGBLOB,
|
||||
CHANGE `config` `c_config` JSON,
|
||||
CHANGE `externalsource` `c_external` BOOL DEFAULT 0,
|
||||
CHANGE `created` `c_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
CHANGE `revised` `c_revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_section_revision
|
||||
CHANGE `refid` `c_refid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `documentid` `c_docid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `ownerid` `c_ownerid` VARCHAR(20) DEFAULT '',
|
||||
CHANGE `pageid` `c_sectionid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `userid` `c_userid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `pagetype` `c_type` CHAR(10) NOT NULL DEFAULT 'section',
|
||||
CHANGE `contenttype` `c_contenttype` CHAR(20) NOT NULL DEFAULT 'wysiwyg',
|
||||
CHANGE `title` `c_name` VARCHAR(2000) NOT NULL DEFAULT '',
|
||||
CHANGE `body` `c_body` LONGTEXT,
|
||||
CHANGE `rawbody` `c_rawbody` LONGBLOB,
|
||||
CHANGE `config` `c_config` JSON,
|
||||
CHANGE `created` `c_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
CHANGE `revised` `c_revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_user
|
||||
CHANGE `refid` `c_refid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `firstname` `c_firstname` VARCHAR(500) NOT NULL DEFAULT '',
|
||||
CHANGE `lastname` `c_lastname` VARCHAR(500) NOT NULL DEFAULT '',
|
||||
CHANGE `email` `c_email` VARCHAR(500) NOT NULL DEFAULT '',
|
||||
CHANGE `initials` `c_initials` VARCHAR(20) NOT NULL DEFAULT '',
|
||||
CHANGE `global` `c_globaladmin` BOOL NOT NULL DEFAULT 0,
|
||||
CHANGE `password` `c_password` VARCHAR(500) NOT NULL DEFAULT '',
|
||||
CHANGE `salt` `c_salt` VARCHAR(500) NOT NULL DEFAULT '',
|
||||
CHANGE `reset` `c_reset` VARCHAR(500) NOT NULL DEFAULT '',
|
||||
CHANGE `active` `c_active` BOOL NOT NULL DEFAULT 1,
|
||||
CHANGE `lastversion` `c_lastversion` VARCHAR(20) NOT NULL DEFAULT '',
|
||||
CHANGE `created` `c_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
CHANGE `revised` `c_revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_user_account
|
||||
CHANGE `refid` `c_refid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `userid` `c_userid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `editor` `c_editor` BOOL NOT NULL DEFAULT 0,
|
||||
CHANGE `admin` `c_admin` BOOL NOT NULL DEFAULT 0,
|
||||
CHANGE `users` `c_users` BOOL NOT NULL DEFAULT 1,
|
||||
CHANGE `analytics` `c_analytics` BOOL NOT NULL DEFAULT 0,
|
||||
CHANGE `active` `c_active` BOOL NOT NULL DEFAULT 1,
|
||||
CHANGE `created` `c_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
CHANGE `revised` `c_revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_user_activity
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `userid` `c_userid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `labelid` `c_spaceid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `documentid` `c_docid` VARCHAR(20) NOT NULL DEFAULT '',
|
||||
CHANGE `pageid` `c_sectionid` VARCHAR(20) NOT NULL DEFAULT '',
|
||||
CHANGE `sourcetype` `c_sourcetype` INT NOT NULL DEFAULT 0,
|
||||
CHANGE `activitytype` `c_activitytype` INT NOT NULL DEFAULT 0,
|
||||
CHANGE `metadata` `c_metadata` VARCHAR(1000) NOT NULL DEFAULT '',
|
||||
CHANGE `created` `c_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_user_config
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `userid` `c_userid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `key` `c_key` CHAR(200) NOT NULL,
|
||||
CHANGE `config` `c_config` JSON;
|
||||
|
||||
ALTER TABLE dmz_config
|
||||
CHANGE `key` `c_key` CHAR(200) NOT NULL,
|
||||
CHANGE `config` `c_config` JSON;
|
||||
|
||||
ALTER TABLE dmz_pin
|
||||
CHANGE `refid` `c_refid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `userid` `c_userid` VARCHAR(20) DEFAULT '',
|
||||
CHANGE `labelid` `c_spaceid` VARCHAR(20) DEFAULT '',
|
||||
CHANGE `documentid` `c_docid` VARCHAR(20) DEFAULT '',
|
||||
CHANGE `sequence` `c_sequence` INT UNSIGNED NOT NULL DEFAULT 99,
|
||||
CHANGE `pin` `c_name` CHAR(100) NOT NULL DEFAULT '',
|
||||
CHANGE `created` `c_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
CHANGE `revised` `c_revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_search
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `documentid` `c_docid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `itemid` `c_itemid` VARCHAR(20) NOT NULL DEFAULT '',
|
||||
CHANGE `itemtype` `c_itemtype` VARCHAR(10) NOT NULL,
|
||||
CHANGE `content` `c_content` LONGTEXT,
|
||||
CHANGE `created` `c_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_audit_log
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `userid` `c_userid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `eventtype` `c_eventtype` VARCHAR(100) NOT NULL DEFAULT '',
|
||||
CHANGE `ip` `c_ip` VARCHAR(39) NOT NULL DEFAULT '',
|
||||
CHANGE `created` `c_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE dmz_action
|
||||
CHANGE `refid` `c_refid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `orgid` `c_orgid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `documentid` `c_docid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `userid` `c_userid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `requestorid` `c_requestorid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `actiontype` `c_actiontype` INT NOT NULL DEFAULT 0,
|
||||
CHANGE `note` `c_note` VARCHAR(2000) NOT NULL DEFAULT '',
|
||||
CHANGE `requested` `c_requested` TIMESTAMP NULL,
|
||||
CHANGE `due` `c_due` TIMESTAMP NULL,
|
||||
CHANGE `completed` `c_completed` TIMESTAMP NULL,
|
||||
CHANGE `iscomplete` `c_iscomplete` BOOL NOT NULL DEFAULT 0,
|
||||
CHANGE `reftype` `c_reftype` CHAR(1) NOT NULL DEFAULT 'D',
|
||||
CHANGE `reftypeid` `c_reftypeid` VARCHAR(20) NOT NULL,
|
||||
CHANGE `created` `c_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
CHANGE `revised` `c_revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
-- deprecations
|
||||
DROP TABLE IF EXISTS `participant`;
|
6
core/database/scripts/mysql/db_00026.sql
Normal file
6
core/database/scripts/mysql/db_00026.sql
Normal file
|
@ -0,0 +1,6 @@
|
|||
/* community edition */
|
||||
|
||||
-- add subscription
|
||||
ALTER TABLE dmz_org ADD COLUMN `c_sub` JSON NULL AFTER `c_authconfig`;
|
||||
|
||||
-- deprecations
|
37
core/database/scripts/mysql/db_00027.sql
Normal file
37
core/database/scripts/mysql/db_00027.sql
Normal file
|
@ -0,0 +1,37 @@
|
|||
/* Community Edition */
|
||||
|
||||
-- Space labels provide name/color grouping
|
||||
DROP TABLE IF EXISTS `dmz_space_label`;
|
||||
CREATE TABLE IF NOT EXISTS `dmz_space_label` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`c_refid` VARCHAR(20) NOT NULL COLLATE utf8_bin,
|
||||
`c_orgid` VARCHAR(20) NOT NULL COLLATE utf8_bin,
|
||||
`c_name` VARCHAR(50) NOT NULL DEFAULT '',
|
||||
`c_color` VARCHAR(10) NOT NULL DEFAULT '',
|
||||
`c_created` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
`c_revised` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE INDEX `idx_space_label_1` (`id` ASC),
|
||||
INDEX `idx_space_label_2` (`c_refid` ASC),
|
||||
INDEX `idx_space_label_3` (`c_orgid` ASC))
|
||||
DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
|
||||
ENGINE = InnoDB;
|
||||
|
||||
-- Space table upgrade to support labelling, icon and summary stats
|
||||
ALTER TABLE dmz_space ADD COLUMN `c_desc` VARCHAR(200) NOT NULL DEFAULT '' AFTER `c_name`;
|
||||
ALTER TABLE dmz_space ADD COLUMN `c_labelid` VARCHAR(20) NOT NULL DEFAULT '' COLLATE utf8_bin AFTER `c_likes`;
|
||||
ALTER TABLE dmz_space ADD COLUMN `c_icon` VARCHAR(20) NOT NULL DEFAULT '' AFTER `c_labelid`;
|
||||
ALTER TABLE dmz_space ADD COLUMN `c_count_category` INT NOT NULL DEFAULT 0 AFTER `c_icon`;
|
||||
ALTER TABLE dmz_space ADD COLUMN `c_count_content` INT NOT NULL DEFAULT 0 AFTER `c_count_category`;
|
||||
|
||||
-- Org/tenant upgrade to support theming and custom logo
|
||||
ALTER TABLE dmz_org ADD COLUMN `c_theme` VARCHAR(20) NOT NULL DEFAULT '' AFTER `c_maxtags`;
|
||||
ALTER TABLE dmz_org ADD COLUMN `c_logo` LONGBLOB AFTER `c_theme`;
|
||||
|
||||
-- Populate default values for new fields
|
||||
UPDATE dmz_space s SET c_count_category=(SELECT COUNT(*) FROM dmz_category WHERE c_spaceid=s.c_refid);
|
||||
UPDATE dmz_space s SET c_count_content=(SELECT COUNT(*) FROM dmz_doc WHERE c_spaceid=s.c_refid);
|
||||
|
||||
-- BUGFIX: Remove zombie group membership records
|
||||
DELETE FROM dmz_group_member WHERE c_userid NOT IN (SELECT c_userid FROM dmz_user_account);
|
||||
|
||||
-- Deprecations
|
6
core/database/scripts/mysql/db_00028.sql
Normal file
6
core/database/scripts/mysql/db_00028.sql
Normal file
|
@ -0,0 +1,6 @@
|
|||
/* Community Edition */
|
||||
|
||||
-- BUGFIX: Increase column size
|
||||
ALTER TABLE dmz_space MODIFY `c_icon` VARCHAR(50) NOT NULL DEFAULT '';
|
||||
|
||||
-- Deprecations
|
4
core/database/scripts/mysql/db_00029.sql
Normal file
4
core/database/scripts/mysql/db_00029.sql
Normal file
|
@ -0,0 +1,4 @@
|
|||
/* Community Edition */
|
||||
|
||||
-- Support per section attachments
|
||||
ALTER TABLE dmz_doc_attachment ADD COLUMN `c_sectionid` VARCHAR(20) NOT NULL DEFAULT '' COLLATE utf8_bin AFTER `c_docid`;
|
5
core/database/scripts/mysql/db_00030.sql
Normal file
5
core/database/scripts/mysql/db_00030.sql
Normal file
|
@ -0,0 +1,5 @@
|
|||
/* Enterprise edition */
|
||||
|
||||
-- Feedback feature: support threaded comments and section references
|
||||
ALTER TABLE dmz_doc_comment ADD COLUMN `c_replyto` VARCHAR(20) NOT NULL DEFAULT '' COLLATE utf8_bin AFTER `c_docid`;
|
||||
ALTER TABLE dmz_doc_comment ADD COLUMN `c_sectionid` VARCHAR(20) NOT NULL DEFAULT '' COLLATE utf8_bin AFTER `c_docid`;
|
5
core/database/scripts/mysql/db_00031.sql
Normal file
5
core/database/scripts/mysql/db_00031.sql
Normal file
|
@ -0,0 +1,5 @@
|
|||
/* Community edition */
|
||||
|
||||
-- Indexes to improve performance
|
||||
CREATE UNIQUE INDEX idx_doc_4 ON dmz_doc(c_orgid,c_refid);
|
||||
CREATE UNIQUE INDEX idx_section_4 ON dmz_section(c_orgid,c_refid);
|
7
core/database/scripts/mysql/db_00032.sql
Normal file
7
core/database/scripts/mysql/db_00032.sql
Normal file
|
@ -0,0 +1,7 @@
|
|||
/* Community Edition */
|
||||
|
||||
-- Increase column sizes to support rich text data entry
|
||||
ALTER TABLE dmz_org MODIFY `c_message` VARCHAR(800) NOT NULL DEFAULT '';
|
||||
ALTER TABLE dmz_space MODIFY `c_desc` VARCHAR(800) NOT NULL DEFAULT '';
|
||||
ALTER TABLE dmz_category MODIFY `c_name` VARCHAR(200) NOT NULL DEFAULT '';
|
||||
ALTER TABLE dmz_category ADD COLUMN `c_default` BOOL NOT NULL DEFAULT 0 AFTER `c_name`;
|
4
core/database/scripts/mysql/db_00033.sql
Normal file
4
core/database/scripts/mysql/db_00033.sql
Normal file
|
@ -0,0 +1,4 @@
|
|||
/* Community Edition */
|
||||
|
||||
-- Allow for pinned documents per space.
|
||||
ALTER TABLE dmz_doc ADD COLUMN `c_seq` INT NOT NULL DEFAULT 99999 AFTER `c_versionorder`;
|
5
core/database/scripts/mysql/db_00034.sql
Normal file
5
core/database/scripts/mysql/db_00034.sql
Normal file
|
@ -0,0 +1,5 @@
|
|||
/* Community Edition */
|
||||
|
||||
-- Local aware.
|
||||
ALTER TABLE dmz_org ADD COLUMN `c_locale` VARCHAR(20) NOT NULL DEFAULT 'en-US';
|
||||
ALTER TABLE dmz_user ADD COLUMN `c_locale` VARCHAR(20) NOT NULL DEFAULT 'en-US';
|
479
core/database/scripts/postgresql/db_00001.sql
Normal file
479
core/database/scripts/postgresql/db_00001.sql
Normal file
|
@ -0,0 +1,479 @@
|
|||
-- SQL to set up the Documize database
|
||||
-- select * from information_schema.tables WHERE table_catalog='documize';
|
||||
-- http://www.postgresqltutorial.com/postgresql-json/
|
||||
-- https://en.wikibooks.org/wiki/Converting_MySQL_to_PostgreSQL
|
||||
|
||||
DROP TABLE IF EXISTS dmz_action;
|
||||
CREATE TABLE dmz_action (
|
||||
id bigserial NOT NULL,
|
||||
c_refid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_userid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_docid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_requestorid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_actiontype int NOT NULL DEFAULT '0',
|
||||
c_note varchar(2000) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_requested timestamp NULL DEFAULT NULL,
|
||||
c_due timestamp NULL DEFAULT NULL,
|
||||
c_completed timestamp NULL DEFAULT NULL,
|
||||
c_iscomplete bool NOT NULL DEFAULT '0',
|
||||
c_reftype varchar(1) COLLATE ucs_basic NOT NULL DEFAULT 'D',
|
||||
c_reftypeid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
CREATE INDEX idx_action_1 ON dmz_action (c_refid);
|
||||
CREATE INDEX idx_action_2 ON dmz_action (c_userid);
|
||||
CREATE INDEX idx_action_3 ON dmz_action (c_docid);
|
||||
CREATE INDEX idx_action_4 ON dmz_action (c_requestorid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_audit_log;
|
||||
CREATE TABLE dmz_audit_log (
|
||||
id bigserial NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_userid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_eventtype varchar(100) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_ip varchar(39) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
CREATE INDEX idx_audit_log_1 ON dmz_audit_log (c_orgid);
|
||||
CREATE INDEX idx_audit_log_2 ON dmz_audit_log (c_userid);
|
||||
CREATE INDEX idx_audit_log_3 ON dmz_audit_log (c_eventtype);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_category;
|
||||
CREATE TABLE dmz_category (
|
||||
id bigserial NOT NULL,
|
||||
c_refid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_spaceid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_name varchar(50) COLLATE ucs_basic NOT NULL,
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE (id)
|
||||
);
|
||||
CREATE INDEX idx_category_1 ON dmz_category (c_refid);
|
||||
CREATE INDEX idx_category_2 ON dmz_category (c_orgid);
|
||||
CREATE INDEX idx_category_3 ON dmz_category (c_orgid,c_spaceid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_category_member;
|
||||
CREATE TABLE dmz_category_member (
|
||||
id bigserial NOT NULL,
|
||||
c_refid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_spaceid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_categoryid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_docid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE (id)
|
||||
);
|
||||
CREATE INDEX idx_category_member_1 ON dmz_category_member (c_docid);
|
||||
CREATE INDEX idx_category_member_2 ON dmz_category_member (c_orgid,c_docid);
|
||||
CREATE INDEX idx_category_member_3 ON dmz_category_member (c_orgid,c_spaceid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_config;
|
||||
CREATE TABLE dmz_config (
|
||||
c_key varchar(200) COLLATE ucs_basic NOT NULL,
|
||||
c_config json DEFAULT NULL,
|
||||
UNIQUE (c_key)
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_doc;
|
||||
CREATE TABLE dmz_doc (
|
||||
id bigserial NOT NULL,
|
||||
c_refid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_spaceid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_userid varchar(20) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_job varchar(36) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_location varchar(2000) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_name varchar(2000) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_desc varchar(2000) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_slug varchar(2000) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_tags varchar(1000) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_template bool NOT NULL DEFAULT '0',
|
||||
c_protection int NOT NULL DEFAULT '0',
|
||||
c_approval int NOT NULL DEFAULT '0',
|
||||
c_lifecycle int NOT NULL DEFAULT '1',
|
||||
c_versioned bool NOT NULL DEFAULT '0',
|
||||
c_versionid varchar(100) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_versionorder int NOT NULL DEFAULT '0',
|
||||
c_groupid varchar(20) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (c_refid)
|
||||
);
|
||||
CREATE INDEX idx_doc_1 ON dmz_doc (id);
|
||||
CREATE INDEX idx_doc_2 ON dmz_doc (c_orgid);
|
||||
CREATE INDEX idx_doc_3 ON dmz_doc (c_spaceid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_doc_attachment;
|
||||
CREATE TABLE dmz_doc_attachment (
|
||||
id bigserial NOT NULL,
|
||||
c_refid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_docid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_job varchar(36) COLLATE ucs_basic NOT NULL,
|
||||
c_fileid varchar(10) COLLATE ucs_basic NOT NULL,
|
||||
c_filename varchar(255) COLLATE ucs_basic NOT NULL,
|
||||
c_data BYTEA,
|
||||
c_extension varchar(6) COLLATE ucs_basic NOT NULL,
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (c_refid)
|
||||
);
|
||||
CREATE INDEX idx_doc_attachment_1 ON dmz_doc_attachment (id);
|
||||
CREATE INDEX idx_doc_attachment_2 ON dmz_doc_attachment (c_orgid);
|
||||
CREATE INDEX idx_doc_attachment_3 ON dmz_doc_attachment (c_docid);
|
||||
CREATE INDEX idx_doc_attachment_4 ON dmz_doc_attachment (c_job,c_fileid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_doc_comment;
|
||||
CREATE TABLE dmz_doc_comment (
|
||||
id bigserial NOT NULL,
|
||||
c_refid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_docid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_userid varchar(20) COLLATE ucs_basic DEFAULT '',
|
||||
c_email varchar(250) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_feedback text COLLATE ucs_basic,
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
CREATE INDEX idx_doc_comment_1 ON dmz_doc_comment (c_refid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_doc_link;
|
||||
CREATE TABLE dmz_doc_link (
|
||||
id bigserial NOT NULL,
|
||||
c_refid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_spaceid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_userid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_sourcedocid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_sourcesectionid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_type varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_targetdocid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_targetid varchar(20) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_externalid varchar(1000) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_orphan bool NOT NULL DEFAULT '0',
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_doc_share;
|
||||
CREATE TABLE dmz_doc_share (
|
||||
id bigserial NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_docid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_userid varchar(20) COLLATE ucs_basic DEFAULT '',
|
||||
c_email varchar(250) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_message varchar(500) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_viewed varchar(500) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_secret varchar(250) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_expires varchar(20) COLLATE ucs_basic DEFAULT '',
|
||||
c_active bool NOT NULL DEFAULT '1',
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_doc_vote;
|
||||
CREATE TABLE dmz_doc_vote (
|
||||
id bigserial NOT NULL,
|
||||
c_refid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_docid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_voter varchar(20) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_vote int NOT NULL DEFAULT '0',
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE (id)
|
||||
);
|
||||
CREATE INDEX idx_doc_vote_1 ON dmz_doc_vote (c_refid);
|
||||
CREATE INDEX idx_doc_vote_2 ON dmz_doc_vote (c_docid);
|
||||
CREATE INDEX idx_doc_vote_3 ON dmz_doc_vote (c_orgid);
|
||||
CREATE INDEX idx_doc_vote_4 ON dmz_doc_vote (c_orgid,c_docid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_group;
|
||||
CREATE TABLE dmz_group (
|
||||
id bigserial NOT NULL,
|
||||
c_refid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_name varchar(50) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_desc varchar(100) COLLATE ucs_basic DEFAULT '',
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE (id)
|
||||
);
|
||||
CREATE INDEX idx_group_1 ON dmz_group (c_refid);
|
||||
CREATE INDEX idx_group_2 ON dmz_group (c_orgid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_group_member;
|
||||
CREATE TABLE dmz_group_member (
|
||||
id bigserial NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_groupid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_userid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
UNIQUE (id)
|
||||
);
|
||||
CREATE INDEX idx_group_member_1 ON dmz_group_member (c_groupid,c_userid);
|
||||
CREATE INDEX idx_group_member_2 ON dmz_group_member (c_orgid,c_groupid,c_userid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_org;
|
||||
CREATE TABLE dmz_org (
|
||||
id bigserial NOT NULL,
|
||||
c_refid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_company varchar(500) COLLATE ucs_basic NOT NULL,
|
||||
c_title varchar(500) COLLATE ucs_basic NOT NULL,
|
||||
c_message varchar(500) COLLATE ucs_basic NOT NULL,
|
||||
c_domain varchar(200) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_service varchar(200) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_email varchar(500) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_anonaccess bool NOT NULL DEFAULT '0',
|
||||
c_authprovider varchar(20) COLLATE ucs_basic NOT NULL DEFAULT 'documize',
|
||||
c_authconfig json DEFAULT NULL,
|
||||
c_maxtags int NOT NULL DEFAULT '3',
|
||||
c_verified bool NOT NULL DEFAULT '0',
|
||||
c_serial varchar(50) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_active bool NOT NULL DEFAULT '1',
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (c_refid)
|
||||
);
|
||||
CREATE INDEX idx_org_1 ON dmz_org (id);
|
||||
CREATE INDEX idx_org_2 ON dmz_org (c_domain);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_permission;
|
||||
CREATE TABLE dmz_permission (
|
||||
id bigserial NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_who varchar(30) COLLATE ucs_basic NOT NULL,
|
||||
c_whoid varchar(20) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_action varchar(30) COLLATE ucs_basic NOT NULL,
|
||||
c_scope varchar(30) COLLATE ucs_basic NOT NULL,
|
||||
c_location varchar(100) COLLATE ucs_basic NOT NULL,
|
||||
c_refid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE (id)
|
||||
);
|
||||
CREATE INDEX idx_permission_1 ON dmz_permission (c_orgid);
|
||||
CREATE INDEX idx_permission_2 ON dmz_permission (c_orgid,c_who,c_whoid,c_location);
|
||||
CREATE INDEX idx_permission_3 ON dmz_permission (c_orgid,c_who,c_whoid,c_location,c_action);
|
||||
CREATE INDEX idx_permission_4 ON dmz_permission (c_orgid,c_location,c_refid);
|
||||
CREATE INDEX idx_permission_5 ON dmz_permission (c_orgid,c_who,c_location,c_action);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_pin;
|
||||
CREATE TABLE dmz_pin (
|
||||
id bigserial NOT NULL,
|
||||
c_refid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_userid varchar(20) COLLATE ucs_basic DEFAULT '',
|
||||
c_spaceid varchar(20) COLLATE ucs_basic DEFAULT '',
|
||||
c_docid varchar(20) COLLATE ucs_basic DEFAULT '',
|
||||
c_sequence BIGINT NOT NULL DEFAULT '99',
|
||||
c_name varchar(100) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
CREATE INDEX idx_pin_1 ON dmz_pin (c_userid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_search;
|
||||
CREATE TABLE dmz_search (
|
||||
id bigserial NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_docid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_itemid varchar(20) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_itemtype varchar(10) COLLATE ucs_basic NOT NULL,
|
||||
c_content text COLLATE ucs_basic,
|
||||
c_token TSVECTOR,
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE (id)
|
||||
);
|
||||
CREATE INDEX idx_search_1 ON dmz_search (c_orgid);
|
||||
CREATE INDEX idx_search_2 ON dmz_search (c_docid);
|
||||
CREATE INDEX idx_search_3 ON dmz_search USING GIN(c_token);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_section;
|
||||
CREATE TABLE dmz_section (
|
||||
id bigserial NOT NULL,
|
||||
c_refid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_docid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_userid varchar(20) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_contenttype varchar(20) COLLATE ucs_basic NOT NULL DEFAULT 'wysiwyg',
|
||||
c_type varchar(10) COLLATE ucs_basic NOT NULL DEFAULT 'section',
|
||||
c_templateid varchar(20) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_level bigint NOT NULL,
|
||||
c_sequence double precision NOT NULL,
|
||||
c_name varchar(2000) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_body text COLLATE ucs_basic,
|
||||
c_revisions bigint NOT NULL,
|
||||
c_status int NOT NULL DEFAULT '0',
|
||||
c_relativeid varchar(20) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (c_refid)
|
||||
);
|
||||
CREATE INDEX idx_section_1 ON dmz_section (id);
|
||||
CREATE INDEX idx_section_2 ON dmz_section (c_orgid);
|
||||
CREATE INDEX idx_section_3 ON dmz_section (c_docid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_section_meta;
|
||||
CREATE TABLE dmz_section_meta (
|
||||
id bigserial NOT NULL,
|
||||
c_sectionid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_userid varchar(20) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_docid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_rawbody BYTEA,
|
||||
c_config json DEFAULT NULL,
|
||||
c_external bool DEFAULT '0',
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (c_sectionid)
|
||||
);
|
||||
CREATE INDEX idx_section_meta_1 ON dmz_section_meta (id);
|
||||
CREATE INDEX idx_section_meta_2 ON dmz_section_meta (c_sectionid);
|
||||
CREATE INDEX idx_section_meta_3 ON dmz_section_meta (c_orgid);
|
||||
CREATE INDEX idx_section_meta_4 ON dmz_section_meta (c_docid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_section_revision;
|
||||
CREATE TABLE dmz_section_revision (
|
||||
id bigserial NOT NULL,
|
||||
c_refid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_docid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_ownerid varchar(20) COLLATE ucs_basic DEFAULT '',
|
||||
c_sectionid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_userid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_contenttype varchar(20) COLLATE ucs_basic NOT NULL DEFAULT 'wysiwyg',
|
||||
c_type varchar(10) COLLATE ucs_basic NOT NULL DEFAULT 'section',
|
||||
c_name varchar(2000) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_body text COLLATE ucs_basic,
|
||||
c_rawbody BYTEA,
|
||||
c_config json DEFAULT NULL,
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (c_refid)
|
||||
);
|
||||
CREATE INDEX idx_section_revision_1 ON dmz_section_revision (id);
|
||||
CREATE INDEX idx_section_revision_2 ON dmz_section_revision (c_orgid);
|
||||
CREATE INDEX idx_section_revision_3 ON dmz_section_revision (c_docid);
|
||||
CREATE INDEX idx_section_revision_4 ON dmz_section_revision (c_sectionid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_section_template;
|
||||
CREATE TABLE dmz_section_template (
|
||||
id bigserial NOT NULL,
|
||||
c_refid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_spaceid varchar(20) COLLATE ucs_basic DEFAULT '',
|
||||
c_userid varchar(20) COLLATE ucs_basic DEFAULT '',
|
||||
c_contenttype varchar(20) COLLATE ucs_basic NOT NULL DEFAULT 'wysiwyg',
|
||||
c_type varchar(10) COLLATE ucs_basic NOT NULL DEFAULT 'section',
|
||||
c_name varchar(2000) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_body text COLLATE ucs_basic,
|
||||
c_desc varchar(2000) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_used bigint NOT NULL,
|
||||
c_rawbody BYTEA,
|
||||
c_config json DEFAULT NULL,
|
||||
c_external bool DEFAULT '0',
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
CREATE INDEX idx_section_template_1 ON dmz_section_template (c_refid);
|
||||
CREATE INDEX idx_section_template_2 ON dmz_section_template (c_spaceid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_space;
|
||||
CREATE TABLE dmz_space (
|
||||
id bigserial NOT NULL,
|
||||
c_refid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_name varchar(300) COLLATE ucs_basic NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_userid varchar(20) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_type int NOT NULL DEFAULT '1',
|
||||
c_lifecycle int NOT NULL DEFAULT '1',
|
||||
c_likes varchar(1000) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (c_refid)
|
||||
);
|
||||
CREATE INDEX idx_space_1 ON dmz_space (id);
|
||||
CREATE INDEX idx_space_2 ON dmz_space (c_userid);
|
||||
CREATE INDEX idx_space_3 ON dmz_space (c_orgid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_user;
|
||||
CREATE TABLE dmz_user (
|
||||
id bigserial NOT NULL,
|
||||
c_refid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_firstname varchar(500) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_lastname varchar(500) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_email varchar(500) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_initials varchar(20) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_globaladmin bool NOT NULL DEFAULT '0',
|
||||
c_password varchar(500) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_salt varchar(500) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_reset varchar(500) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_active bool NOT NULL DEFAULT '1',
|
||||
c_lastversion varchar(20) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (c_refid)
|
||||
);
|
||||
CREATE INDEX idx_user_1 ON dmz_user (id);
|
||||
CREATE INDEX idx_user_2 ON dmz_user (c_email);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_user_account;
|
||||
CREATE TABLE dmz_user_account (
|
||||
id bigserial NOT NULL,
|
||||
c_refid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_userid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_editor bool NOT NULL DEFAULT '0',
|
||||
c_admin bool NOT NULL DEFAULT '0',
|
||||
c_users bool NOT NULL DEFAULT '1',
|
||||
c_analytics bool NOT NULL DEFAULT '0',
|
||||
c_active bool NOT NULL DEFAULT '1',
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (c_refid)
|
||||
);
|
||||
CREATE INDEX idx_user_account_1 ON dmz_user_account (id);
|
||||
CREATE INDEX idx_user_account_2 ON dmz_user_account (c_userid);
|
||||
CREATE INDEX idx_user_account_3 ON dmz_user_account (c_orgid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_user_activity;
|
||||
CREATE TABLE dmz_user_activity (
|
||||
id bigserial NOT NULL,
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_userid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_spaceid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_docid varchar(20) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_sectionid varchar(20) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_sourcetype int NOT NULL DEFAULT '0',
|
||||
c_activitytype int NOT NULL DEFAULT '0',
|
||||
c_metadata varchar(1000) COLLATE ucs_basic NOT NULL DEFAULT '',
|
||||
c_created timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
CREATE INDEX idx_user_activity_1 ON dmz_user_activity (c_orgid);
|
||||
CREATE INDEX idx_user_activity_2 ON dmz_user_activity (c_userid);
|
||||
CREATE INDEX idx_user_activity_3 ON dmz_user_activity (c_activitytype);
|
||||
CREATE INDEX idx_user_activity_4 ON dmz_user_activity (c_orgid,c_docid,c_sourcetype);
|
||||
CREATE INDEX idx_user_activity_5 ON dmz_user_activity (c_orgid,c_docid,c_userid,c_sourcetype);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_user_config;
|
||||
CREATE TABLE dmz_user_config (
|
||||
c_orgid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_userid varchar(20) COLLATE ucs_basic NOT NULL,
|
||||
c_key varchar(200) COLLATE ucs_basic NOT NULL,
|
||||
c_config json DEFAULT NULL,
|
||||
UNIQUE (c_orgid,c_userid,c_key)
|
||||
);
|
||||
|
||||
INSERT INTO dmz_config VALUES ('SMTP','{"userid": "","password": "","host": "","port": "","sender": ""}');
|
||||
INSERT INTO dmz_config VALUES ('FILEPLUGINS', '[{"Comment": "Disable (or not) built-in html import (NOTE: no Plugin name)","Disabled": false,"API": "Convert","Actions": ["htm","html"]},{"Comment": "Disable (or not) built-in Documize API import used from SDK (NOTE: no Plugin name)","Disabled": false,"API": "Convert","Actions": ["documizeapi"]}]');
|
||||
INSERT INTO dmz_config VALUES ('SECTION-TRELLO','{"appKey": ""}');
|
||||
INSERT INTO dmz_config VALUES ('META','{"database": "0"}');
|
6
core/database/scripts/postgresql/db_00002.sql
Normal file
6
core/database/scripts/postgresql/db_00002.sql
Normal file
|
@ -0,0 +1,6 @@
|
|||
/* community edition */
|
||||
|
||||
-- add subscription
|
||||
ALTER TABLE dmz_org ADD COLUMN c_sub JSON NULL;
|
||||
|
||||
-- deprecations
|
36
core/database/scripts/postgresql/db_00003.sql
Normal file
36
core/database/scripts/postgresql/db_00003.sql
Normal file
|
@ -0,0 +1,36 @@
|
|||
/* Community Edition */
|
||||
|
||||
-- Space labels provide name/color grouping
|
||||
DROP TABLE IF EXISTS dmz_space_label;
|
||||
CREATE TABLE dmz_space_label (
|
||||
id bigserial NOT NULL,
|
||||
c_refid VARCHAR(20) NOT NULL COLLATE ucs_basic,
|
||||
c_orgid VARCHAR(20) NOT NULL COLLATE ucs_basic,
|
||||
c_name VARCHAR(50) NOT NULL DEFAULT '',
|
||||
c_color VARCHAR(10) NOT NULL DEFAULT '',
|
||||
c_created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (c_refid)
|
||||
);
|
||||
CREATE INDEX idx_space_label_1 ON dmz_space_label (id);
|
||||
CREATE INDEX idx_space_label_2 ON dmz_space_label (c_orgid);
|
||||
|
||||
-- Space table upgrade to support label, icon and summary stats
|
||||
ALTER TABLE dmz_space ADD COLUMN c_desc VARCHAR(200) NOT NULL DEFAULT '';
|
||||
ALTER TABLE dmz_space ADD COLUMN c_labelid VARCHAR(20) NOT NULL DEFAULT '' COLLATE ucs_basic;
|
||||
ALTER TABLE dmz_space ADD COLUMN c_icon VARCHAR(20) NOT NULL DEFAULT '';
|
||||
ALTER TABLE dmz_space ADD COLUMN c_count_category INT NOT NULL DEFAULT 0;
|
||||
ALTER TABLE dmz_space ADD COLUMN c_count_content INT NOT NULL DEFAULT 0;
|
||||
|
||||
-- Org/tenant upgrade to support theming and custom logo
|
||||
ALTER TABLE dmz_org ADD COLUMN c_theme VARCHAR(20) NOT NULL DEFAULT '';
|
||||
ALTER TABLE dmz_org ADD COLUMN c_logo BYTEA;
|
||||
|
||||
-- Populate default values for new fields
|
||||
UPDATE dmz_space s SET c_count_category=(SELECT COUNT(*) FROM dmz_category WHERE c_spaceid=s.c_refid);
|
||||
UPDATE dmz_space s SET c_count_content=(SELECT COUNT(*) FROM dmz_doc WHERE c_spaceid=s.c_refid);
|
||||
|
||||
-- BUGFIX: Remove zombie group membership records
|
||||
DELETE FROM dmz_group_member WHERE c_userid NOT IN (SELECT c_userid FROM dmz_user_account);
|
||||
|
||||
-- Deprecations
|
6
core/database/scripts/postgresql/db_00004.sql
Normal file
6
core/database/scripts/postgresql/db_00004.sql
Normal file
|
@ -0,0 +1,6 @@
|
|||
/* Community Edition */
|
||||
|
||||
-- BUGFIX: Increase column size
|
||||
ALTER TABLE dmz_space ALTER COLUMN c_icon TYPE VARCHAR(50);
|
||||
|
||||
-- Deprecations
|
4
core/database/scripts/postgresql/db_00005.sql
Normal file
4
core/database/scripts/postgresql/db_00005.sql
Normal file
|
@ -0,0 +1,4 @@
|
|||
/* Community Edition */
|
||||
|
||||
-- Support per section attachments
|
||||
ALTER TABLE dmz_doc_attachment ADD COLUMN c_sectionid VARCHAR(20) NOT NULL DEFAULT '' COLLATE ucs_basic;
|
5
core/database/scripts/postgresql/db_00006.sql
Normal file
5
core/database/scripts/postgresql/db_00006.sql
Normal file
|
@ -0,0 +1,5 @@
|
|||
/* Enterprise edition */
|
||||
|
||||
-- Feedback feature: support threaded comments and section references
|
||||
ALTER TABLE dmz_doc_comment ADD COLUMN c_replyto VARCHAR(20) NOT NULL DEFAULT '' COLLATE ucs_basic;
|
||||
ALTER TABLE dmz_doc_comment ADD COLUMN c_sectionid VARCHAR(20) NOT NULL DEFAULT '' COLLATE ucs_basic;
|
5
core/database/scripts/postgresql/db_00007.sql
Normal file
5
core/database/scripts/postgresql/db_00007.sql
Normal file
|
@ -0,0 +1,5 @@
|
|||
/* Community edition */
|
||||
|
||||
-- Indexes to improve performance
|
||||
CREATE UNIQUE INDEX idx_doc_4 ON dmz_doc (c_orgid,c_refid);
|
||||
CREATE UNIQUE INDEX idx_section_4 ON dmz_section (c_orgid,c_refid);
|
7
core/database/scripts/postgresql/db_00008.sql
Normal file
7
core/database/scripts/postgresql/db_00008.sql
Normal file
|
@ -0,0 +1,7 @@
|
|||
/* Community Edition */
|
||||
|
||||
-- Increase column sizes to support rich text data entry
|
||||
ALTER TABLE dmz_org ALTER COLUMN c_message TYPE VARCHAR(2000);
|
||||
ALTER TABLE dmz_space ALTER COLUMN c_desc TYPE VARCHAR(2000);
|
||||
ALTER TABLE dmz_category ALTER COLUMN c_name TYPE VARCHAR(200);
|
||||
ALTER TABLE dmz_category ADD COLUMN c_default bool NOT NULL DEFAULT '0';
|
5
core/database/scripts/postgresql/db_00009.sql
Normal file
5
core/database/scripts/postgresql/db_00009.sql
Normal file
|
@ -0,0 +1,5 @@
|
|||
/* Community Edition */
|
||||
|
||||
-- Allow for pinned documents per space.
|
||||
ALTER TABLE dmz_doc ADD COLUMN c_seq INT NOT NULL DEFAULT '99999';
|
||||
|
5
core/database/scripts/postgresql/db_00010.sql
Normal file
5
core/database/scripts/postgresql/db_00010.sql
Normal file
|
@ -0,0 +1,5 @@
|
|||
/* Community Edition */
|
||||
|
||||
-- Local aware.
|
||||
ALTER TABLE dmz_org ADD COLUMN c_locale VARCHAR(20) NOT NULL DEFAULT 'en-US';
|
||||
ALTER TABLE dmz_user ADD COLUMN c_locale VARCHAR(20) NOT NULL DEFAULT 'en-US';
|
469
core/database/scripts/sqlserver/db_00001.sql
Normal file
469
core/database/scripts/sqlserver/db_00001.sql
Normal file
|
@ -0,0 +1,469 @@
|
|||
-- SQL to set up the Documize database
|
||||
|
||||
DROP TABLE IF EXISTS dmz_action;
|
||||
CREATE TABLE dmz_action (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_refid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_userid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_docid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_requestorid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_actiontype INT NOT NULL DEFAULT '0',
|
||||
c_note NVARCHAR(2000) NOT NULL DEFAULT '',
|
||||
c_requested DATETIME2 NULL DEFAULT NULL,
|
||||
c_due DATETIME2 NULL DEFAULT NULL,
|
||||
c_completed DATETIME2 NULL DEFAULT NULL,
|
||||
c_iscomplete BIT NOT NULL DEFAULT '0',
|
||||
c_reftype NVARCHAR(1) NOT NULL DEFAULT 'D',
|
||||
c_reftypeid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_action_1 ON dmz_action (c_refid);
|
||||
CREATE INDEX idx_action_2 ON dmz_action (c_userid);
|
||||
CREATE INDEX idx_action_3 ON dmz_action (c_docid);
|
||||
CREATE INDEX idx_action_4 ON dmz_action (c_requestorid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_audit_log;
|
||||
CREATE TABLE dmz_audit_log (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_userid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_eventtype NVARCHAR(100) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_ip NVARCHAR(39) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_audit_log_1 ON dmz_audit_log (c_orgid);
|
||||
CREATE INDEX idx_audit_log_2 ON dmz_audit_log (c_userid);
|
||||
CREATE INDEX idx_audit_log_3 ON dmz_audit_log (c_eventtype);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_category;
|
||||
CREATE TABLE dmz_category (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_refid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_spaceid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_name NVARCHAR(50) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_category_1 ON dmz_category (c_refid);
|
||||
CREATE INDEX idx_category_2 ON dmz_category (c_orgid);
|
||||
CREATE INDEX idx_category_3 ON dmz_category (c_orgid,c_spaceid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_category_member;
|
||||
CREATE TABLE dmz_category_member (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_refid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_spaceid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_categoryid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_docid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_category_member_1 ON dmz_category_member (c_docid);
|
||||
CREATE INDEX idx_category_member_2 ON dmz_category_member (c_orgid,c_docid);
|
||||
CREATE INDEX idx_category_member_3 ON dmz_category_member (c_orgid,c_spaceid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_config;
|
||||
CREATE TABLE dmz_config (
|
||||
c_key NVARCHAR(200) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_config NVARCHAR(MAX) DEFAULT NULL
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_doc;
|
||||
CREATE TABLE dmz_doc (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_refid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_spaceid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_userid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_job NVARCHAR(36) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_location NVARCHAR(2000) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_name NVARCHAR(2000) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_desc NVARCHAR(2000) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_slug NVARCHAR(2000) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_tags NVARCHAR(1000) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_template BIT NOT NULL DEFAULT '0',
|
||||
c_protection INT NOT NULL DEFAULT '0',
|
||||
c_approval INT NOT NULL DEFAULT '0',
|
||||
c_lifecycle INT NOT NULL DEFAULT '1',
|
||||
c_versioned BIT NOT NULL DEFAULT '0',
|
||||
c_versionid NVARCHAR(100) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_versionorder INT NOT NULL DEFAULT '0',
|
||||
c_groupid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_doc_1 ON dmz_doc (id);
|
||||
CREATE INDEX idx_doc_2 ON dmz_doc (c_orgid);
|
||||
CREATE INDEX idx_doc_3 ON dmz_doc (c_spaceid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_doc_attachment;
|
||||
CREATE TABLE dmz_doc_attachment (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_refid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_docid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_job NVARCHAR(36) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_fileid NVARCHAR(10) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_filename NVARCHAR(255) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_data VARBINARY(MAX),
|
||||
c_extension NVARCHAR(6) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_doc_attachment_1 ON dmz_doc_attachment (id);
|
||||
CREATE INDEX idx_doc_attachment_2 ON dmz_doc_attachment (c_orgid);
|
||||
CREATE INDEX idx_doc_attachment_3 ON dmz_doc_attachment (c_docid);
|
||||
CREATE INDEX idx_doc_attachment_4 ON dmz_doc_attachment (c_job,c_fileid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_doc_comment;
|
||||
CREATE TABLE dmz_doc_comment (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_refid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_docid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_userid NVARCHAR(20) COLLATE Latin1_General_CS_AS DEFAULT '',
|
||||
c_email NVARCHAR(250) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_feedback NVARCHAR(MAX) COLLATE Latin1_General_CS_AS,
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_doc_comment_1 ON dmz_doc_comment (c_refid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_doc_link;
|
||||
CREATE TABLE dmz_doc_link (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_refid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_spaceid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_userid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_sourcedocid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_sourcesectionid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_type NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_targetdocid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_targetid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_externalid NVARCHAR(1000) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_orphan BIT NOT NULL DEFAULT '0',
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_doc_share;
|
||||
CREATE TABLE dmz_doc_share (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_docid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_userid NVARCHAR(20) COLLATE Latin1_General_CS_AS DEFAULT '',
|
||||
c_email NVARCHAR(250) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_message NVARCHAR(500) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_viewed NVARCHAR(500) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_secret NVARCHAR(250) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_expires NVARCHAR(20) COLLATE Latin1_General_CS_AS DEFAULT '',
|
||||
c_active BIT NOT NULL DEFAULT '1',
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_doc_vote;
|
||||
CREATE TABLE dmz_doc_vote (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_refid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_docid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_voter NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_vote INT NOT NULL DEFAULT '0',
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_doc_vote_1 ON dmz_doc_vote (c_refid);
|
||||
CREATE INDEX idx_doc_vote_2 ON dmz_doc_vote (c_docid);
|
||||
CREATE INDEX idx_doc_vote_3 ON dmz_doc_vote (c_orgid);
|
||||
CREATE INDEX idx_doc_vote_4 ON dmz_doc_vote (c_orgid,c_docid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_group;
|
||||
CREATE TABLE dmz_group (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_refid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_name NVARCHAR(50) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_desc NVARCHAR(100) COLLATE Latin1_General_CS_AS DEFAULT '',
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_group_1 ON dmz_group (c_refid);
|
||||
CREATE INDEX idx_group_2 ON dmz_group (c_orgid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_group_member;
|
||||
CREATE TABLE dmz_group_member (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_groupid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_userid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL
|
||||
);
|
||||
CREATE INDEX idx_group_member_1 ON dmz_group_member (c_groupid,c_userid);
|
||||
CREATE INDEX idx_group_member_2 ON dmz_group_member (c_orgid,c_groupid,c_userid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_org;
|
||||
CREATE TABLE dmz_org (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_refid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_company NVARCHAR(500) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_title NVARCHAR(500) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_message NVARCHAR(500) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_domain NVARCHAR(200) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_service NVARCHAR(200) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_email NVARCHAR(500) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_anonaccess BIT NOT NULL DEFAULT '0',
|
||||
c_authprovider NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT 'documize',
|
||||
c_authconfig NVARCHAR(MAX) DEFAULT NULL,
|
||||
c_maxtags INT NOT NULL DEFAULT '3',
|
||||
c_sub NVARCHAR(MAX) NULL,
|
||||
c_theme NVARCHAR(20) NOT NULL DEFAULT '',
|
||||
c_logo VARBINARY(MAX),
|
||||
c_verified BIT NOT NULL DEFAULT '0',
|
||||
c_serial NVARCHAR(50) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_active BIT NOT NULL DEFAULT '1',
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
);
|
||||
CREATE INDEX idx_org_1 ON dmz_org (id);
|
||||
CREATE INDEX idx_org_2 ON dmz_org (c_domain);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_permission;
|
||||
CREATE TABLE dmz_permission (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_who NVARCHAR(30) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_whoid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_action NVARCHAR(30) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_scope NVARCHAR(30) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_location NVARCHAR(100) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_refid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_permission_1 ON dmz_permission (c_orgid);
|
||||
CREATE INDEX idx_permission_2 ON dmz_permission (c_orgid,c_who,c_whoid,c_location);
|
||||
CREATE INDEX idx_permission_3 ON dmz_permission (c_orgid,c_who,c_whoid,c_location,c_action);
|
||||
CREATE INDEX idx_permission_4 ON dmz_permission (c_orgid,c_location,c_refid);
|
||||
CREATE INDEX idx_permission_5 ON dmz_permission (c_orgid,c_who,c_location,c_action);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_pin;
|
||||
CREATE TABLE dmz_pin (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_refid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_userid NVARCHAR(20) COLLATE Latin1_General_CS_AS DEFAULT '',
|
||||
c_spaceid NVARCHAR(20) COLLATE Latin1_General_CS_AS DEFAULT '',
|
||||
c_docid NVARCHAR(20) COLLATE Latin1_General_CS_AS DEFAULT '',
|
||||
c_sequence BIGINT NOT NULL DEFAULT '99',
|
||||
c_name NVARCHAR(100) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_pin_1 ON dmz_pin (c_userid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_search;
|
||||
CREATE TABLE dmz_search (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_docid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_itemid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_itemtype NVARCHAR(10) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_content NVARCHAR(MAX) COLLATE Latin1_General_CS_AS,
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_search_1 ON dmz_search (c_orgid);
|
||||
CREATE INDEX idx_search_2 ON dmz_search (c_docid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_section;
|
||||
CREATE TABLE dmz_section (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_refid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_docid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_userid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_contenttype NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT 'wysiwyg',
|
||||
c_type NVARCHAR(10) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT 'section',
|
||||
c_templateid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_level bigint NOT NULL,
|
||||
c_sequence double precision NOT NULL,
|
||||
c_name NVARCHAR(2000) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_body NVARCHAR(MAX) COLLATE Latin1_General_CS_AS,
|
||||
c_revisions bigint NOT NULL,
|
||||
c_status INT NOT NULL DEFAULT '0',
|
||||
c_relativeid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_section_1 ON dmz_section (id);
|
||||
CREATE INDEX idx_section_2 ON dmz_section (c_orgid);
|
||||
CREATE INDEX idx_section_3 ON dmz_section (c_docid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_section_meta;
|
||||
CREATE TABLE dmz_section_meta (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_sectionid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_userid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_docid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_rawbody NVARCHAR(MAX),
|
||||
c_config NVARCHAR(MAX) DEFAULT NULL,
|
||||
c_external BIT DEFAULT '0',
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_section_meta_1 ON dmz_section_meta (id);
|
||||
CREATE INDEX idx_section_meta_2 ON dmz_section_meta (c_sectionid);
|
||||
CREATE INDEX idx_section_meta_3 ON dmz_section_meta (c_orgid);
|
||||
CREATE INDEX idx_section_meta_4 ON dmz_section_meta (c_docid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_section_revision;
|
||||
CREATE TABLE dmz_section_revision (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_refid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_docid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_ownerid NVARCHAR(20) COLLATE Latin1_General_CS_AS DEFAULT '',
|
||||
c_sectionid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_userid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_contenttype NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT 'wysiwyg',
|
||||
c_type NVARCHAR(10) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT 'section',
|
||||
c_name NVARCHAR(2000) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_body NVARCHAR(MAX) COLLATE Latin1_General_CS_AS,
|
||||
c_rawbody NVARCHAR(MAX),
|
||||
c_config NVARCHAR(MAX) DEFAULT NULL,
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_section_revision_1 ON dmz_section_revision (id);
|
||||
CREATE INDEX idx_section_revision_2 ON dmz_section_revision (c_orgid);
|
||||
CREATE INDEX idx_section_revision_3 ON dmz_section_revision (c_docid);
|
||||
CREATE INDEX idx_section_revision_4 ON dmz_section_revision (c_sectionid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_section_template;
|
||||
CREATE TABLE dmz_section_template (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_refid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_spaceid NVARCHAR(20) COLLATE Latin1_General_CS_AS DEFAULT '',
|
||||
c_userid NVARCHAR(20) COLLATE Latin1_General_CS_AS DEFAULT '',
|
||||
c_contenttype NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT 'wysiwyg',
|
||||
c_type NVARCHAR(10) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT 'section',
|
||||
c_name NVARCHAR(2000) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_body NVARCHAR(MAX) COLLATE Latin1_General_CS_AS,
|
||||
c_desc NVARCHAR(2000) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_used INT NOT NULL,
|
||||
c_rawbody NVARCHAR(MAX),
|
||||
c_config NVARCHAR(MAX) DEFAULT NULL,
|
||||
c_external BIT DEFAULT '0',
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_section_template_1 ON dmz_section_template (c_refid);
|
||||
CREATE INDEX idx_section_template_2 ON dmz_section_template (c_spaceid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_space;
|
||||
CREATE TABLE dmz_space (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_refid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_name NVARCHAR(300) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_userid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_type INT NOT NULL DEFAULT '1',
|
||||
c_lifecycle INT NOT NULL DEFAULT '1',
|
||||
c_desc NVARCHAR(200) NOT NULL DEFAULT '',
|
||||
c_labelid NVARCHAR(20) NOT NULL DEFAULT '' COLLATE Latin1_General_CS_AS,
|
||||
c_likes NVARCHAR(1000) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_icon NVARCHAR(50) NOT NULL DEFAULT '',
|
||||
c_count_category INT NOT NULL DEFAULT 0,
|
||||
c_count_content INT NOT NULL DEFAULT 0,
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_space_1 ON dmz_space (id);
|
||||
CREATE INDEX idx_space_2 ON dmz_space (c_userid);
|
||||
CREATE INDEX idx_space_3 ON dmz_space (c_orgid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_space_label;
|
||||
CREATE TABLE dmz_space_label (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_refid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_name NVARCHAR(50) NOT NULL DEFAULT '',
|
||||
c_color NVARCHAR(10) NOT NULL DEFAULT '',
|
||||
c_created DATETIME2 DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised DATETIME2 DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_space_label_1 ON dmz_space_label (id);
|
||||
CREATE INDEX idx_space_label_2 ON dmz_space_label (c_orgid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_user;
|
||||
CREATE TABLE dmz_user (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_refid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_firstname NVARCHAR(500) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_lastname NVARCHAR(500) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_email NVARCHAR(500) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_initials NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_globaladmin BIT NOT NULL DEFAULT '0',
|
||||
c_password NVARCHAR(500) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_salt NVARCHAR(500) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_reset NVARCHAR(500) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_active BIT NOT NULL DEFAULT '1',
|
||||
c_lastversion NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_user_1 ON dmz_user (id);
|
||||
CREATE INDEX idx_user_2 ON dmz_user (c_email);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_user_account;
|
||||
CREATE TABLE dmz_user_account (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_refid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_userid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_editor BIT NOT NULL DEFAULT '0',
|
||||
c_admin BIT NOT NULL DEFAULT '0',
|
||||
c_users BIT NOT NULL DEFAULT '1',
|
||||
c_analytics BIT NOT NULL DEFAULT '0',
|
||||
c_active BIT NOT NULL DEFAULT '1',
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
c_revised DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_user_account_1 ON dmz_user_account (id);
|
||||
CREATE INDEX idx_user_account_2 ON dmz_user_account (c_userid);
|
||||
CREATE INDEX idx_user_account_3 ON dmz_user_account (c_orgid);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_user_activity;
|
||||
CREATE TABLE dmz_user_activity (
|
||||
id BIGINT PRIMARY KEY IDENTITY (1, 1) NOT NULL,
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_userid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_spaceid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_docid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_sectionid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_sourcetype INT NOT NULL DEFAULT '0',
|
||||
c_activitytype INT NOT NULL DEFAULT '0',
|
||||
c_metadata NVARCHAR(1000) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '',
|
||||
c_created DATETIME2 NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
CREATE INDEX idx_user_activity_1 ON dmz_user_activity (c_orgid);
|
||||
CREATE INDEX idx_user_activity_2 ON dmz_user_activity (c_userid);
|
||||
CREATE INDEX idx_user_activity_3 ON dmz_user_activity (c_activitytype);
|
||||
CREATE INDEX idx_user_activity_4 ON dmz_user_activity (c_orgid,c_docid,c_sourcetype);
|
||||
CREATE INDEX idx_user_activity_5 ON dmz_user_activity (c_orgid,c_docid,c_userid,c_sourcetype);
|
||||
|
||||
DROP TABLE IF EXISTS dmz_user_config;
|
||||
CREATE TABLE dmz_user_config (
|
||||
c_orgid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_userid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_key NVARCHAR(200) COLLATE Latin1_General_CS_AS NOT NULL,
|
||||
c_config NVARCHAR(MAX) DEFAULT NULL
|
||||
);
|
||||
|
||||
INSERT INTO dmz_config VALUES ('SMTP','{"userid": "","password": "","host": "","port": "","sender": ""}');
|
||||
INSERT INTO dmz_config VALUES ('FILEPLUGINS', '[{"Comment": "Disable (or not) built-in html import (NOTE: no Plugin name)","Disabled": false,"API": "Convert","Actions": ["htm","html"]},{"Comment": "Disable (or not) built-in Documize API import used from SDK (NOTE: no Plugin name)","Disabled": false,"API": "Convert","Actions": ["documizeapi"]}]');
|
||||
INSERT INTO dmz_config VALUES ('SECTION-TRELLO','{"appKey": ""}');
|
||||
INSERT INTO dmz_config VALUES ('META','{"database": "0"}');
|
4
core/database/scripts/sqlserver/db_00002.sql
Normal file
4
core/database/scripts/sqlserver/db_00002.sql
Normal file
|
@ -0,0 +1,4 @@
|
|||
/* Community Edition */
|
||||
|
||||
-- Support per section attachments
|
||||
ALTER TABLE dmz_doc_attachment ADD c_sectionid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '';
|
5
core/database/scripts/sqlserver/db_00003.sql
Normal file
5
core/database/scripts/sqlserver/db_00003.sql
Normal file
|
@ -0,0 +1,5 @@
|
|||
/* Enterprise edition */
|
||||
|
||||
-- Feedback feature: support threaded comments and section references
|
||||
ALTER TABLE dmz_doc_comment ADD c_replyto NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '';
|
||||
ALTER TABLE dmz_doc_comment ADD c_sectionid NVARCHAR(20) COLLATE Latin1_General_CS_AS NOT NULL DEFAULT '';
|
16
core/database/scripts/sqlserver/db_00004.sql
Normal file
16
core/database/scripts/sqlserver/db_00004.sql
Normal file
|
@ -0,0 +1,16 @@
|
|||
/* Community edition */
|
||||
|
||||
-- Fulltext search support
|
||||
IF EXISTS (SELECT * FROM sysfulltextcatalogs ftc WHERE ftc.name = N'dmz_search_catalog')
|
||||
DROP FULLTEXT CATALOG dmz_search_catalog;
|
||||
|
||||
CREATE FULLTEXT CATALOG dmz_search_catalog;
|
||||
|
||||
CREATE UNIQUE INDEX idx_doc_4 ON dmz_doc(c_refid);
|
||||
CREATE UNIQUE INDEX idx_section_4 ON dmz_section(c_refid);
|
||||
|
||||
CREATE FULLTEXT INDEX ON dmz_doc (c_name, c_desc) KEY INDEX idx_doc_4 ON dmz_search_catalog
|
||||
WITH CHANGE_TRACKING AUTO;
|
||||
|
||||
CREATE FULLTEXT INDEX ON dmz_section (c_name, c_body) KEY INDEX idx_section_4 ON dmz_search_catalog
|
||||
WITH CHANGE_TRACKING AUTO;
|
7
core/database/scripts/sqlserver/db_00005.sql
Normal file
7
core/database/scripts/sqlserver/db_00005.sql
Normal file
|
@ -0,0 +1,7 @@
|
|||
/* Community edition */
|
||||
|
||||
-- Increase column sizes to support rich text data entry
|
||||
ALTER TABLE dmz_org ALTER COLUMN c_message NVARCHAR(2000);
|
||||
ALTER TABLE dmz_space ALTER COLUMN c_desc NVARCHAR(2000);
|
||||
ALTER TABLE dmz_category ALTER COLUMN c_name NVARCHAR(200);
|
||||
ALTER TABLE dmz_category ADD c_default BIT NOT NULL DEFAULT '0';
|
4
core/database/scripts/sqlserver/db_00006.sql
Normal file
4
core/database/scripts/sqlserver/db_00006.sql
Normal file
|
@ -0,0 +1,4 @@
|
|||
/* Community edition */
|
||||
|
||||
-- Allow for pinned documents per space.
|
||||
ALTER TABLE dmz_doc ADD c_seq INT NOT NULL DEFAULT '99999';
|
5
core/database/scripts/sqlserver/db_00007.sql
Normal file
5
core/database/scripts/sqlserver/db_00007.sql
Normal file
|
@ -0,0 +1,5 @@
|
|||
/* Community edition */
|
||||
|
||||
-- Local aware.
|
||||
ALTER TABLE dmz_org ADD c_locale NVARCHAR(20) NOT NULL DEFAULT 'en-US';
|
||||
ALTER TABLE dmz_user ADD c_locale NVARCHAR(20) NOT NULL DEFAULT 'en-US';
|
4
core/database/scripts/sqlserver/db_00008.sql
Normal file
4
core/database/scripts/sqlserver/db_00008.sql
Normal file
|
@ -0,0 +1,4 @@
|
|||
/* Community edition */
|
||||
|
||||
-- Performance indexes
|
||||
CREATE INDEX idx_action_5 ON dmz_action (c_orgid,c_userid,c_docid,c_actiontype,c_iscomplete,c_reftype,c_reftypeid);
|
8
core/database/scripts/sqlserver/db_00009.sql
Normal file
8
core/database/scripts/sqlserver/db_00009.sql
Normal file
|
@ -0,0 +1,8 @@
|
|||
/* Community edition */
|
||||
|
||||
-- Performance indexes
|
||||
CREATE INDEX idx_action_6 ON dmz_action (c_orgid,c_reftypeid,c_reftype);
|
||||
|
||||
CREATE INDEX idx_action_7 ON dmz_action (c_orgid,c_refid);
|
||||
|
||||
CREATE INDEX idx_section_5 ON dmz_section (c_orgid,c_refid);
|
6
core/database/scripts/sqlserver/db_00010.sql
Normal file
6
core/database/scripts/sqlserver/db_00010.sql
Normal file
|
@ -0,0 +1,6 @@
|
|||
/* Community edition */
|
||||
|
||||
-- Performance indexes
|
||||
CREATE INDEX idx_action_8 ON dmz_action (c_orgid,c_docid);
|
||||
|
||||
CREATE INDEX idx_user_3 ON dmz_user (c_refid);
|
207
core/database/setup_endpoint.go
Normal file
207
core/database/setup_endpoint.go
Normal file
|
@ -0,0 +1,207 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
package database
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"encoding/xml"
|
||||
"errors"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/documize/community/core/api/plugins"
|
||||
"github.com/documize/community/core/env"
|
||||
"github.com/documize/community/core/secrets"
|
||||
"github.com/documize/community/core/stringutil"
|
||||
"github.com/documize/community/core/uniqueid"
|
||||
"github.com/documize/community/domain"
|
||||
"github.com/documize/community/domain/store"
|
||||
"github.com/documize/community/server/web"
|
||||
)
|
||||
|
||||
// Handler contains the runtime information such as logging and database.
|
||||
type Handler struct {
|
||||
Runtime *env.Runtime
|
||||
Store *store.Store
|
||||
}
|
||||
|
||||
// Setup the tables in a blank database
|
||||
func (h *Handler) Setup(w http.ResponseWriter, r *http.Request) {
|
||||
defer func() {
|
||||
target := "/setup"
|
||||
status := http.StatusBadRequest
|
||||
|
||||
if h.Runtime.Flags.SiteMode == env.SiteModeNormal {
|
||||
target = "/"
|
||||
status = http.StatusOK
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("GET", target, nil)
|
||||
if err != nil {
|
||||
h.Runtime.Log.Error("database.Setup error in defer ", err)
|
||||
}
|
||||
|
||||
http.Redirect(w, req, target, status)
|
||||
}()
|
||||
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
h.Runtime.Log.Error("database.Setup r.ParseForm()", err)
|
||||
return
|
||||
}
|
||||
|
||||
dbname := r.Form.Get("dbname")
|
||||
dbhash := r.Form.Get("dbhash")
|
||||
|
||||
if dbname != web.SiteInfo.DBname || dbhash != web.SiteInfo.DBhash {
|
||||
h.Runtime.Log.Error("database.Setup security credentials error ", errors.New("bad db name or validation code"))
|
||||
return
|
||||
}
|
||||
|
||||
details := onboardRequest{
|
||||
URL: "",
|
||||
Company: r.Form.Get("title"),
|
||||
CompanyLong: r.Form.Get("title"),
|
||||
Message: r.Form.Get("message"),
|
||||
Email: r.Form.Get("email"),
|
||||
Password: r.Form.Get("password"),
|
||||
Firstname: r.Form.Get("firstname"),
|
||||
Lastname: r.Form.Get("lastname"),
|
||||
ActivationKey: r.Form.Get("activationKey"),
|
||||
Revised: time.Now().UTC(),
|
||||
}
|
||||
|
||||
if details.Company == "" ||
|
||||
details.CompanyLong == "" ||
|
||||
details.Message == "" ||
|
||||
details.Email == "" ||
|
||||
details.Password == "" ||
|
||||
details.Firstname == "" ||
|
||||
details.Lastname == "" {
|
||||
h.Runtime.Log.Error("database.Setup error ", errors.New("required field in database set-up form blank"))
|
||||
return
|
||||
}
|
||||
|
||||
if err = InstallUpgrade(h.Runtime, false); err != nil {
|
||||
h.Runtime.Log.Error("database.Setup migrate", err)
|
||||
return
|
||||
}
|
||||
|
||||
err = setupAccount(h.Runtime, details, secrets.GenerateSalt())
|
||||
if err != nil {
|
||||
h.Runtime.Log.Error("database.Setup setup account ", err)
|
||||
return
|
||||
}
|
||||
|
||||
h.Runtime.Flags.SiteMode = env.SiteModeNormal
|
||||
|
||||
err = plugins.Setup(h.Store)
|
||||
if err != nil {
|
||||
h.Runtime.Log.Error("database.Setup plugin setup failed", err)
|
||||
}
|
||||
}
|
||||
|
||||
// The result of completing the onboarding process.
|
||||
type onboardRequest struct {
|
||||
URL string
|
||||
Company string
|
||||
CompanyLong string
|
||||
Message string
|
||||
Email string
|
||||
Password string
|
||||
Firstname string
|
||||
Lastname string
|
||||
ActivationKey string
|
||||
Revised time.Time
|
||||
}
|
||||
|
||||
// setupAccount prepares the database for a newly onboard customer.
|
||||
// Once done, they can then login and use Documize.
|
||||
func setupAccount(rt *env.Runtime, completion onboardRequest, serial string) (err error) {
|
||||
tx, err := rt.Db.Beginx()
|
||||
if err != nil {
|
||||
rt.Log.Error("setup - failed to get transaction", err)
|
||||
return
|
||||
}
|
||||
|
||||
salt := secrets.GenerateSalt()
|
||||
password := secrets.GeneratePassword(completion.Password, salt)
|
||||
|
||||
// Process activation key if we have one.
|
||||
activationKey := processActivationKey(rt, completion)
|
||||
|
||||
// Allocate organization to the user.
|
||||
orgID := uniqueid.Generate()
|
||||
_, err = tx.Exec(RebindParams("INSERT INTO dmz_org (c_refid, c_company, c_title, c_message, c_domain, c_email, c_serial, c_sub) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
|
||||
rt.StoreProvider.Type()),
|
||||
orgID, completion.Company, completion.CompanyLong, completion.Message, completion.URL, completion.Email, serial, activationKey)
|
||||
if err != nil {
|
||||
rt.Log.Error("INSERT INTO dmz_org failed", err)
|
||||
rt.Rollback(tx)
|
||||
return
|
||||
}
|
||||
|
||||
// Create user.
|
||||
userID := uniqueid.Generate()
|
||||
_, err = tx.Exec(RebindParams("INSERT INTO dmz_user (c_refid, c_firstname, c_lastname, c_email, c_initials, c_salt, c_password, c_globaladmin) VALUES (?, ?, ?, ?, ?, ?, ?, ?)", rt.StoreProvider.Type()),
|
||||
userID, completion.Firstname, completion.Lastname, completion.Email, stringutil.MakeInitials(completion.Firstname, completion.Lastname), salt, password, true)
|
||||
if err != nil {
|
||||
rt.Log.Error("INSERT INTO dmz_user failed", err)
|
||||
rt.Rollback(tx)
|
||||
return
|
||||
}
|
||||
|
||||
// Link user to organization.
|
||||
accountID := uniqueid.Generate()
|
||||
_, err = tx.Exec(RebindParams("INSERT INTO dmz_user_account (c_refid, c_userid, c_orgid, c_admin, c_editor, c_users, c_analytics) VALUES (?, ?, ?, ?, ?, ?, ?)", rt.StoreProvider.Type()),
|
||||
accountID, userID, orgID, true, true, true, true)
|
||||
if err != nil {
|
||||
rt.Log.Error("INSERT INTO dmz_user_account failed", err)
|
||||
rt.Rollback(tx)
|
||||
return
|
||||
}
|
||||
|
||||
// Finish up.
|
||||
if err = tx.Commit(); err != nil {
|
||||
rt.Log.Error("setup - unable to commit sql", err)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func processActivationKey(rt *env.Runtime, or onboardRequest) (key string) {
|
||||
key = "{}"
|
||||
if len(or.ActivationKey) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
j := domain.SubscriptionData{}
|
||||
x := domain.SubscriptionXML{Key: "", Signature: ""}
|
||||
|
||||
err1 := xml.Unmarshal([]byte(or.ActivationKey), &x)
|
||||
if err1 == nil {
|
||||
j.Key = x.Key
|
||||
j.Signature = x.Signature
|
||||
} else {
|
||||
rt.Log.Error("failed to XML unmarshal subscription XML", err1)
|
||||
}
|
||||
|
||||
d, err2 := json.Marshal(j)
|
||||
if err2 == nil {
|
||||
key = string(d)
|
||||
} else {
|
||||
rt.Log.Error("failed to JSON marshal subscription XML", err2)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
html {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
background-color: #1b75bb;
|
||||
|
@ -22,54 +22,54 @@
|
|||
color: #ffffff;
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
.logo {
|
||||
margin: 0 15px;
|
||||
}
|
||||
|
||||
|
||||
.content {
|
||||
margin: 0 15px;
|
||||
}
|
||||
|
||||
|
||||
.content > div {
|
||||
margin: 50px 0;
|
||||
}
|
||||
|
||||
|
||||
.content h1 {
|
||||
font-size: 24px;
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
margin: 0 0 30px;
|
||||
}
|
||||
|
||||
|
||||
.content p {
|
||||
font-size: 18px;
|
||||
line-height: 28px;
|
||||
margin: 30px 0 0 0;
|
||||
}
|
||||
|
||||
|
||||
.content .image {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
.clearfix {
|
||||
overflow: auto;
|
||||
zoom: 1;
|
||||
}
|
||||
|
||||
|
||||
.btn-main {
|
||||
border: 1px solid #ffffff;
|
||||
padding: 12px 20px;
|
||||
border-radius: 5px;
|
||||
margin-left: 25px;
|
||||
}
|
||||
|
||||
|
||||
@media (min-width: 768px) {
|
||||
body {
|
||||
margin-top: 100px;
|
||||
|
@ -102,7 +102,7 @@
|
|||
<body>
|
||||
<div class="container">
|
||||
<div class="logo">
|
||||
<img src="/assets/img/setup/logo.png" alt="Documize">
|
||||
<img src="/assets/img/setup/logo.png" alt="Documize Community">
|
||||
</div>
|
||||
<div class="content clearfix">
|
||||
<div class="image">
|
||||
|
@ -110,11 +110,11 @@
|
|||
</div>
|
||||
<div class="text">
|
||||
<h1>Database Error</h1>
|
||||
<p>There seems to be a problem with the Documize database: <strong>{{.DBname}}</strong></p>
|
||||
<p>There seems to be a problem with the Documize Community database: <strong>{{.DBname}}</strong></p>
|
||||
<p><em>{{.Issue}}</em></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
|
File diff suppressed because one or more lines are too long
108
core/env/command_line.go
vendored
Normal file
108
core/env/command_line.go
vendored
Normal file
|
@ -0,0 +1,108 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
// Package env provides runtime, server level setup and configuration
|
||||
package env
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// prefix provides the prefix for all environment variables
|
||||
const prefix = "DOCUMIZE"
|
||||
const goInit = "(default)"
|
||||
|
||||
var flagList progFlags
|
||||
var cliMutex sync.Mutex
|
||||
|
||||
type flagItem struct {
|
||||
target *string
|
||||
name, setter, value string
|
||||
required bool
|
||||
}
|
||||
|
||||
type progFlags struct {
|
||||
items []flagItem
|
||||
}
|
||||
|
||||
// Len is part of sort.Interface.
|
||||
func (v *progFlags) Len() int {
|
||||
return len(v.items)
|
||||
}
|
||||
|
||||
// Swap is part of sort.Interface.
|
||||
func (v *progFlags) Swap(i, j int) {
|
||||
v.items[i], v.items[j] = v.items[j], v.items[i]
|
||||
}
|
||||
|
||||
// Less is part of sort.Interface.
|
||||
func (v *progFlags) Less(i, j int) bool {
|
||||
return v.items[i].name < v.items[j].name
|
||||
}
|
||||
|
||||
// register prepares flag for subsequent parsing
|
||||
func register(target *string, name string, required bool, usage string) {
|
||||
cliMutex.Lock()
|
||||
defer cliMutex.Unlock()
|
||||
|
||||
name = strings.ToLower(strings.TrimSpace(name))
|
||||
setter := prefix + strings.ToUpper(name)
|
||||
|
||||
value := os.Getenv(setter)
|
||||
if value == "" {
|
||||
value = *target // use the Go initialized value
|
||||
setter = goInit
|
||||
}
|
||||
|
||||
flag.StringVar(target, name, value, usage)
|
||||
flagList.items = append(flagList.items, flagItem{target: target, name: name, required: required, value: value, setter: setter})
|
||||
}
|
||||
|
||||
// parse loads flags from OS environment and command line switches
|
||||
func parse(doFirst string) (ok bool) {
|
||||
cliMutex.Lock()
|
||||
defer cliMutex.Unlock()
|
||||
|
||||
flag.Parse()
|
||||
sort.Sort(&flagList)
|
||||
|
||||
for pass := 1; pass <= 2; pass++ {
|
||||
for vi, v := range flagList.items {
|
||||
if (pass == 1 && v.name == doFirst) || (pass == 2 && v.name != doFirst) {
|
||||
if v.value != *(v.target) || (v.value != "" && *(v.target) == "") {
|
||||
flagList.items[vi].setter = "-" + v.name // v is a local copy, not the underlying data
|
||||
}
|
||||
if v.required {
|
||||
if *(v.target) == "" {
|
||||
fmt.Fprintln(os.Stderr)
|
||||
fmt.Fprintln(os.Stderr, "In order to run", os.Args[0], "the following must be provided:")
|
||||
for _, vv := range flagList.items {
|
||||
if vv.required {
|
||||
fmt.Fprintf(os.Stderr, "* setting from environment variable '%s' or flag '-%s' or an application setting '%s', current value: '%s' set by '%s'\n",
|
||||
prefix+strings.ToUpper(vv.name), vv.name, vv.name, *(vv.target), vv.setter)
|
||||
}
|
||||
}
|
||||
fmt.Fprintln(os.Stderr)
|
||||
flag.Usage()
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
138
core/env/flags.go
vendored
138
core/env/flags.go
vendored
|
@ -12,25 +12,19 @@
|
|||
// Package env provides runtime, server level setup and configuration
|
||||
package env
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Flags provides access to environment and command line switches for this program.
|
||||
type Flags struct {
|
||||
DBType string // database type
|
||||
DBConn string // database connection string
|
||||
Salt string // the salt string used to encode JWT tokens
|
||||
DBType string // (optional) database type
|
||||
SSLCertFile string // (optional) name of SSL certificate PEM file
|
||||
SSLKeyFile string // (optional) name of SSL key PEM file
|
||||
HTTPPort string // (optional) HTTP or HTTPS port
|
||||
ForceHTTPPort2SSL string // (optional) HTTP that should be redirected to HTTPS
|
||||
SSLCertFile string // (optional) name of SSL certificate PEM file
|
||||
SSLKeyFile string // (optional) name of SSL key PEM file
|
||||
TLSVersion string // (optional) minimum TLS version for SSL connections
|
||||
SiteMode string // (optional) if 1 then serve offline web page
|
||||
Location string // reserved
|
||||
ConfigSource string // tells us if configuration info was obtained from command line or config file
|
||||
}
|
||||
|
||||
// SSLEnabled returns true if both cert and key were provided at runtime.
|
||||
|
@ -38,113 +32,27 @@ func (f *Flags) SSLEnabled() bool {
|
|||
return f.SSLCertFile != "" && f.SSLKeyFile != ""
|
||||
}
|
||||
|
||||
type flagItem struct {
|
||||
target *string
|
||||
name, setter, value string
|
||||
required bool
|
||||
// ConfigToml represents configuration file that contains all flags as per above.
|
||||
type ConfigToml struct {
|
||||
HTTP httpConfig `toml:"http"`
|
||||
Database databaseConfig `toml:"database"`
|
||||
Install installConfig `toml:"install"`
|
||||
}
|
||||
|
||||
type progFlags struct {
|
||||
items []flagItem
|
||||
type httpConfig struct {
|
||||
Port int
|
||||
ForceSSLPort int
|
||||
Cert string
|
||||
Key string
|
||||
TLSVersion string
|
||||
}
|
||||
|
||||
// Len is part of sort.Interface.
|
||||
func (v *progFlags) Len() int {
|
||||
return len(v.items)
|
||||
type databaseConfig struct {
|
||||
Type string
|
||||
Connection string
|
||||
Salt string
|
||||
}
|
||||
|
||||
// Swap is part of sort.Interface.
|
||||
func (v *progFlags) Swap(i, j int) {
|
||||
v.items[i], v.items[j] = v.items[j], v.items[i]
|
||||
}
|
||||
|
||||
// Less is part of sort.Interface.
|
||||
func (v *progFlags) Less(i, j int) bool {
|
||||
return v.items[i].name < v.items[j].name
|
||||
}
|
||||
|
||||
// prefix provides the prefix for all environment variables
|
||||
const prefix = "DOCUMIZE"
|
||||
const goInit = "(default)"
|
||||
|
||||
var flagList progFlags
|
||||
var loadMutex sync.Mutex
|
||||
|
||||
// ParseFlags loads command line and OS environment variables required by the program to function.
|
||||
func ParseFlags() (f Flags) {
|
||||
var dbConn, dbType, jwtKey, siteMode, port, certFile, keyFile, forcePort2SSL string
|
||||
|
||||
register(&jwtKey, "salt", false, "the salt string used to encode JWT tokens, if not set a random value will be generated")
|
||||
register(&certFile, "cert", false, "the cert.pem file used for https")
|
||||
register(&keyFile, "key", false, "the key.pem file used for https")
|
||||
register(&port, "port", false, "http/https port number")
|
||||
register(&forcePort2SSL, "forcesslport", false, "redirect given http port number to TLS")
|
||||
register(&siteMode, "offline", false, "set to '1' for OFFLINE mode")
|
||||
register(&dbType, "dbtype", false, "set to database type mysql|percona|mariadb")
|
||||
register(&dbConn, "db", true, `'username:password@protocol(hostname:port)/databasename" for example "fred:bloggs@tcp(localhost:3306)/documize"`)
|
||||
|
||||
parse("db")
|
||||
|
||||
f.DBConn = dbConn
|
||||
f.ForceHTTPPort2SSL = forcePort2SSL
|
||||
f.HTTPPort = port
|
||||
f.Salt = jwtKey
|
||||
f.SiteMode = siteMode
|
||||
f.SSLCertFile = certFile
|
||||
f.SSLKeyFile = keyFile
|
||||
f.DBType = dbType
|
||||
|
||||
return f
|
||||
}
|
||||
|
||||
// register prepares flag for subsequent parsing
|
||||
func register(target *string, name string, required bool, usage string) {
|
||||
loadMutex.Lock()
|
||||
defer loadMutex.Unlock()
|
||||
|
||||
name = strings.ToLower(strings.TrimSpace(name))
|
||||
setter := prefix + strings.ToUpper(name)
|
||||
|
||||
value := os.Getenv(setter)
|
||||
if value == "" {
|
||||
value = *target // use the Go initialized value
|
||||
setter = goInit
|
||||
}
|
||||
|
||||
flag.StringVar(target, name, value, usage)
|
||||
flagList.items = append(flagList.items, flagItem{target: target, name: name, required: required, value: value, setter: setter})
|
||||
}
|
||||
|
||||
// parse loads flags from OS environment and command line switches
|
||||
func parse(doFirst string) {
|
||||
loadMutex.Lock()
|
||||
defer loadMutex.Unlock()
|
||||
|
||||
flag.Parse()
|
||||
sort.Sort(&flagList)
|
||||
|
||||
for pass := 1; pass <= 2; pass++ {
|
||||
for vi, v := range flagList.items {
|
||||
if (pass == 1 && v.name == doFirst) || (pass == 2 && v.name != doFirst) {
|
||||
if v.value != *(v.target) || (v.value != "" && *(v.target) == "") {
|
||||
flagList.items[vi].setter = "-" + v.name // v is a local copy, not the underlying data
|
||||
}
|
||||
if v.required {
|
||||
if *(v.target) == "" {
|
||||
fmt.Fprintln(os.Stderr)
|
||||
fmt.Fprintln(os.Stderr, "In order to run", os.Args[0], "the following must be provided:")
|
||||
for _, vv := range flagList.items {
|
||||
if vv.required {
|
||||
fmt.Fprintf(os.Stderr, "* setting from environment variable '%s' or flag '-%s' or an application setting '%s', current value: '%s' set by '%s'\n",
|
||||
prefix+strings.ToUpper(vv.name), vv.name, vv.name, *(vv.target), vv.setter)
|
||||
}
|
||||
}
|
||||
fmt.Fprintln(os.Stderr)
|
||||
flag.Usage()
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
type installConfig struct {
|
||||
Location string
|
||||
}
|
||||
|
|
1
core/env/logger.go
vendored
1
core/env/logger.go
vendored
|
@ -15,6 +15,7 @@ package env
|
|||
// Logger provides the interface for Documize compatible loggers.
|
||||
type Logger interface {
|
||||
Info(message string)
|
||||
Infof(message string, a ...interface{})
|
||||
Trace(message string)
|
||||
Error(message string, err error)
|
||||
// SetDB(l Logger, db *sqlx.DB) Logger
|
||||
|
|
145
core/env/parser.go
vendored
Normal file
145
core/env/parser.go
vendored
Normal file
|
@ -0,0 +1,145 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
// Package env provides runtime, server level setup and configuration
|
||||
package env
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
)
|
||||
|
||||
// LoadConfig loads runtime parameters like port numbers and DB connections.
|
||||
// We first check for -config switch that would point us towards a .CONF file.
|
||||
// If not found, we then read parameters from command line and environment vars.
|
||||
func LoadConfig() (f Flags, ok bool) {
|
||||
// Check and process config file
|
||||
f, ok = configFile()
|
||||
|
||||
// If not OK then get parameters from command line and environment variables.
|
||||
if !ok {
|
||||
f, ok = commandLineEnv()
|
||||
}
|
||||
|
||||
// reserved
|
||||
if len(f.Location) == 0 {
|
||||
f.Location = "selfhost"
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// configFile checks for the presence of zero or one command argument.
|
||||
// If no arguments are provided then we look for and load documize.conf file.
|
||||
// If one argument is provided then we load the specified config file.
|
||||
// If more than one argument is provided then we exit as flags as have passed.
|
||||
// checks to see if it is a TOML format config file.
|
||||
func configFile() (f Flags, ok bool) {
|
||||
ok = false
|
||||
var configFile string
|
||||
|
||||
// First argument is always program being executed.
|
||||
// No additional arguments means check for documize.conf file.
|
||||
if len(os.Args) == 1 {
|
||||
// No arguments, so we default to default config filename.
|
||||
configFile = "documize.conf"
|
||||
} else if len(os.Args) == 2 {
|
||||
// Config filename passed in, so we use it.
|
||||
configFile = os.Args[1]
|
||||
} else {
|
||||
// Too many arguments means flags passed in so we return.
|
||||
return
|
||||
}
|
||||
|
||||
// Does file exist?
|
||||
if len(configFile) == 0 || !configFileExists(configFile) {
|
||||
return
|
||||
}
|
||||
|
||||
// Tell caller where the config came from.
|
||||
f.ConfigSource = configFile
|
||||
|
||||
// We parse the TOML format config file.
|
||||
var ct ConfigToml
|
||||
if _, err := toml.DecodeFile(configFile, &ct); err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
f.DBType = strings.ToLower(ct.Database.Type)
|
||||
f.DBConn = ct.Database.Connection
|
||||
f.Salt = ct.Database.Salt
|
||||
f.HTTPPort = strconv.Itoa(ct.HTTP.Port)
|
||||
f.ForceHTTPPort2SSL = strconv.Itoa(ct.HTTP.ForceSSLPort)
|
||||
f.SSLCertFile = ct.HTTP.Cert
|
||||
f.SSLKeyFile = ct.HTTP.Key
|
||||
f.TLSVersion = ct.HTTP.TLSVersion
|
||||
f.Location = strings.ToLower(ct.Install.Location)
|
||||
|
||||
if len(f.TLSVersion) == 0 {
|
||||
f.TLSVersion = "1.3"
|
||||
}
|
||||
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
// commandLineEnv loads command line and OS environment variables required by the program to function.
|
||||
func commandLineEnv() (f Flags, ok bool) {
|
||||
ok = true
|
||||
var dbConn, dbType, jwtKey, siteMode, port, certFile, keyFile, forcePort2SSL, TLSVersion, location string
|
||||
|
||||
// register(&configFile, "salt", false, "the salt string used to encode JWT tokens, if not set a random value will be generated")
|
||||
register(&jwtKey, "salt", false, "the salt string used to encode JWT tokens, if not set a random value will be generated")
|
||||
register(&certFile, "cert", false, "the cert.pem file used for https")
|
||||
register(&keyFile, "key", false, "the key.pem file used for https")
|
||||
register(&port, "port", false, "http/https port number")
|
||||
register(&forcePort2SSL, "forcesslport", false, "redirect given http port number to TLS")
|
||||
register(&TLSVersion, "tlsversion", false, "select minimum TLS: 1.0, 1.1, 1.2, 1.3")
|
||||
register(&siteMode, "offline", false, "set to '1' for OFFLINE mode")
|
||||
register(&dbType, "dbtype", true, "specify the database provider: mysql|percona|mariadb|postgresql|sqlserver")
|
||||
register(&dbConn, "db", true, `'database specific connection string for example "user:password@tcp(localhost:3306)/dbname"`)
|
||||
register(&location, "location", false, `reserved`)
|
||||
|
||||
if !parse("db") {
|
||||
ok = false
|
||||
}
|
||||
|
||||
f.DBType = strings.ToLower(dbType)
|
||||
f.DBConn = dbConn
|
||||
f.ForceHTTPPort2SSL = forcePort2SSL
|
||||
f.HTTPPort = port
|
||||
f.Salt = jwtKey
|
||||
f.SiteMode = siteMode
|
||||
f.SSLCertFile = certFile
|
||||
f.SSLKeyFile = keyFile
|
||||
f.TLSVersion = TLSVersion
|
||||
f.Location = strings.ToLower(location)
|
||||
f.ConfigSource = "flags/environment"
|
||||
|
||||
if len(f.TLSVersion) == 0 {
|
||||
f.TLSVersion = "1.3"
|
||||
}
|
||||
|
||||
return f, ok
|
||||
}
|
||||
|
||||
func configFileExists(fn string) bool {
|
||||
info, err := os.Stat(fn)
|
||||
if os.IsNotExist(err) {
|
||||
return false
|
||||
}
|
||||
|
||||
return !info.IsDir()
|
||||
}
|
70
core/env/product.go
vendored
70
core/env/product.go
vendored
|
@ -1,70 +0,0 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
package env
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ProdInfo describes a product
|
||||
type ProdInfo struct {
|
||||
Edition string
|
||||
Title string
|
||||
Version string
|
||||
Major string
|
||||
Minor string
|
||||
Patch string
|
||||
License License
|
||||
}
|
||||
|
||||
// License holds details of product license.
|
||||
type License struct {
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
Edition string `json:"edition"`
|
||||
Start time.Time `json:"start"`
|
||||
End time.Time `json:"end"`
|
||||
Seats int `json:"seats"`
|
||||
Trial bool `json:"trial"`
|
||||
Valid bool
|
||||
}
|
||||
|
||||
// IsEmpty determines if we have a license.
|
||||
func (l *License) IsEmpty() bool {
|
||||
return l.Seats == 0 && len(l.Name) == 0 && len(l.Email) == 0 && l.Start.Year() == 1 && l.End.Year() == 1
|
||||
}
|
||||
|
||||
// Status returns formatted message stating if license is empty/populated and invalid/valid.
|
||||
func (l *License) Status() string {
|
||||
lp := "populated"
|
||||
if l.IsEmpty() {
|
||||
lp = "empty"
|
||||
}
|
||||
lv := "invalid"
|
||||
if l.Valid {
|
||||
lv = "valid"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("License is %s and %s", lp, lv)
|
||||
}
|
||||
|
||||
// IsValid returns if license is valid
|
||||
func (l *License) IsValid() bool {
|
||||
return l.Valid == true
|
||||
}
|
||||
|
||||
// LicenseData holds encrypted data and is unpacked into License.
|
||||
type LicenseData struct {
|
||||
Key string `json:"key"`
|
||||
Signature string `json:"signature"`
|
||||
}
|
117
core/env/provider.go
vendored
Normal file
117
core/env/provider.go
vendored
Normal file
|
@ -0,0 +1,117 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
// Package env provides runtime, server level setup and configuration
|
||||
package env
|
||||
|
||||
// StoreType represents name of database system
|
||||
type StoreType string
|
||||
|
||||
const (
|
||||
// StoreTypeMySQL is MySQL
|
||||
StoreTypeMySQL StoreType = "MySQL"
|
||||
|
||||
// StoreTypePercona is Percona
|
||||
StoreTypePercona StoreType = "Percona"
|
||||
|
||||
// StoreTypeMariaDB is MariaDB
|
||||
StoreTypeMariaDB StoreType = "MariaDB"
|
||||
|
||||
// StoreTypePostgreSQL is PostgreSQL
|
||||
StoreTypePostgreSQL StoreType = "PostgreSQL"
|
||||
|
||||
// StoreTypeSQLServer is Microsoft SQL Server
|
||||
StoreTypeSQLServer StoreType = "SQLServer"
|
||||
)
|
||||
|
||||
// StoreProvider defines a database provider.
|
||||
type StoreProvider interface {
|
||||
// Name of provider
|
||||
Type() StoreType
|
||||
|
||||
// TypeVariant returns flavor of database provider.
|
||||
TypeVariant() StoreType
|
||||
|
||||
// SQL driver name used to open DB connection.
|
||||
DriverName() string
|
||||
|
||||
// Database connection string parameters that must be present before connecting to DB.
|
||||
Params() map[string]string
|
||||
|
||||
// Example holds storage provider specific connection string format.
|
||||
// used in error messages
|
||||
Example() string
|
||||
|
||||
// DatabaseName holds the SQL database name where Documize tables live.
|
||||
DatabaseName() string
|
||||
|
||||
// Make connection string with default parameters.
|
||||
MakeConnectionString() string
|
||||
|
||||
// QueryMeta is how to extract version number, collation, character set from database provider.
|
||||
QueryMeta() string
|
||||
|
||||
// QueryRecordVersionUpgrade returns database specific insert statement
|
||||
// that records the database version number.
|
||||
QueryRecordVersionUpgrade(version int) string
|
||||
|
||||
// QueryRecordVersionUpgrade returns database specific insert statement
|
||||
// that records the database version number.
|
||||
// For use on databases before The Great Schema Migration (v25, MySQL).
|
||||
QueryRecordVersionUpgradeLegacy(version int) string
|
||||
|
||||
// QueryGetDatabaseVersion returns the schema version number.
|
||||
QueryGetDatabaseVersion() string
|
||||
|
||||
// QueryGetDatabaseVersionLegacy returns the schema version number before The Great Schema Migration (v25, MySQL).
|
||||
QueryGetDatabaseVersionLegacy() string
|
||||
|
||||
// QueryTableList returns a list tables in Documize database.
|
||||
QueryTableList() string
|
||||
|
||||
// QueryDateInterval returns provider specific
|
||||
// interval style date SQL.
|
||||
QueryDateInterval(days int64) string
|
||||
|
||||
// JSONEmpty returns empty SQL JSON object.
|
||||
// Typically used as 2nd parameter to COALESCE().
|
||||
JSONEmpty() string
|
||||
|
||||
// JSONGetValue returns JSON attribute selection syntax.
|
||||
// Typically used in SELECT <my_json_field> query.
|
||||
JSONGetValue(column, attribute string) string
|
||||
|
||||
// VerfiyVersion checks to see if actual database meets
|
||||
// minimum version requirements.
|
||||
VerfiyVersion(dbVersion string) (versionOK bool, minVerRequired string)
|
||||
|
||||
// VerfiyCharacterCollation checks to see if actual database
|
||||
// has correct character set and collation settings.
|
||||
VerfiyCharacterCollation(charset, collation string) (charOK bool, requirements string)
|
||||
|
||||
// ConvertTimestamp returns SQL function to correctly convert
|
||||
// ISO 8601 format (e.g. '2016-09-08T06:37:23Z') to SQL specific
|
||||
// timestamp value (e.g. 2016-09-08 06:37:23).
|
||||
// Must use ? for parameter placeholder character as DB layer
|
||||
// will convert to database specific parameter placeholder character.
|
||||
ConvertTimestamp() (statement string)
|
||||
|
||||
// IsTrue returns storage provider boolean TRUE:
|
||||
// MySQL is 1, PostgresSQL is TRUE, SQL Server is 1
|
||||
IsTrue() string
|
||||
|
||||
// IsFalse returns storage provider boolean FALSE:
|
||||
// MySQL is 0, PostgresSQL is FALSE, SQL Server is 0
|
||||
IsFalse() string
|
||||
|
||||
// RowLimit returns SQL for limited number of returned rows
|
||||
RowLimit(max int) string
|
||||
}
|
82
core/env/runtime.go
vendored
82
core/env/runtime.go
vendored
|
@ -12,48 +12,70 @@
|
|||
// Package env provides runtime, server level setup and configuration
|
||||
package env
|
||||
|
||||
import "github.com/jmoiron/sqlx"
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"embed"
|
||||
|
||||
// Runtime provides access to database, logger and other server-level scoped objects.
|
||||
// Use Context for per-request values.
|
||||
type Runtime struct {
|
||||
Flags Flags
|
||||
Db *sqlx.DB
|
||||
DbVariant DbVariant
|
||||
Log Logger
|
||||
Product ProdInfo
|
||||
}
|
||||
"github.com/documize/community/domain"
|
||||
"github.com/jmoiron/sqlx"
|
||||
)
|
||||
|
||||
const (
|
||||
// SiteModeNormal serves app
|
||||
SiteModeNormal = ""
|
||||
|
||||
// SiteModeOffline serves offline.html
|
||||
SiteModeOffline = "1"
|
||||
|
||||
// SiteModeSetup tells Ember to serve setup route
|
||||
SiteModeSetup = "2"
|
||||
|
||||
// SiteModeBadDB redirects to db-error.html page
|
||||
SiteModeBadDB = "3"
|
||||
)
|
||||
|
||||
// DbVariant details SQL database variant
|
||||
type DbVariant string
|
||||
// Runtime provides access to database, logger and other server-level scoped objects.
|
||||
// Use Context for per-request values.
|
||||
type Runtime struct {
|
||||
Flags Flags
|
||||
Db *sqlx.DB
|
||||
StoreProvider StoreProvider
|
||||
Log Logger
|
||||
Product domain.Product
|
||||
Assets embed.FS
|
||||
}
|
||||
|
||||
const (
|
||||
// DbVariantMySQL is MySQL
|
||||
DbVariantMySQL DbVariant = "MySQL"
|
||||
// DBVariantPercona is Percona
|
||||
DBVariantPercona DbVariant = "Percona"
|
||||
// DBVariantMariaDB is MariaDB
|
||||
DBVariantMariaDB DbVariant = "MariaDB"
|
||||
// DBVariantMSSQL is Microsoft SQL Server
|
||||
DBVariantMSSQL DbVariant = "MSSQL"
|
||||
// DBVariantPostgreSQL is PostgreSQL
|
||||
DBVariantPostgreSQL DbVariant = "PostgreSQL"
|
||||
)
|
||||
// StartTx begins database transaction with given transaction isolation level.
|
||||
// Any error encountered during this operation is logged to runtime logger.
|
||||
func (r *Runtime) StartTx(i sql.IsolationLevel) (tx *sqlx.Tx, ok bool) {
|
||||
tx, err := r.Db.BeginTxx(context.Background(), &sql.TxOptions{Isolation: i})
|
||||
if err != nil {
|
||||
r.Log.Error("unable to start database transaction", err)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
const (
|
||||
// CommunityEdition is AGPL product variant
|
||||
CommunityEdition = "Community"
|
||||
// EnterpriseEdition is commercial licensed product variant
|
||||
EnterpriseEdition = "Enterprise"
|
||||
)
|
||||
return tx, true
|
||||
}
|
||||
|
||||
// Rollback aborts active database transaction.
|
||||
// Any error encountered during this operation is logged to runtime logger.
|
||||
func (r *Runtime) Rollback(tx *sqlx.Tx) bool {
|
||||
if err := tx.Commit(); err != nil {
|
||||
r.Log.Error("unable to commit database transaction", err)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Commit flushes pending changes to database.
|
||||
// Any error encountered during this operation is logged to runtime logger.
|
||||
func (r *Runtime) Commit(tx *sqlx.Tx) bool {
|
||||
if err := tx.Commit(); err != nil {
|
||||
r.Log.Error("unable to commit database transaction", err)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
|
91
core/i18n/localize.go
Normal file
91
core/i18n/localize.go
Normal file
|
@ -0,0 +1,91 @@
|
|||
package i18n
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/documize/community/core/asset"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const (
|
||||
DefaultLocale = "en-US"
|
||||
)
|
||||
|
||||
var localeMap map[string]map[string]string
|
||||
|
||||
// SupportedLocales returns array of locales.
|
||||
func SupportedLocales() (locales []string) {
|
||||
locales = append(locales, "en-US")
|
||||
locales = append(locales, "de-DE")
|
||||
locales = append(locales, "zh-CN")
|
||||
locales = append(locales, "pt-BR")
|
||||
locales = append(locales, "fr-FR")
|
||||
locales = append(locales, "ja-JP")
|
||||
locales = append(locales, "it-IT")
|
||||
locales = append(locales, "es-AR")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Intialize will load language files
|
||||
func Initialize(e embed.FS) (err error) {
|
||||
localeMap = make(map[string]map[string]string)
|
||||
|
||||
locales := SupportedLocales()
|
||||
|
||||
for i := range locales {
|
||||
content, _, err := asset.FetchStatic(e, "i18n/"+locales[i]+".json")
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, fmt.Sprintf("missing locale %s", locales[i]))
|
||||
return err
|
||||
}
|
||||
|
||||
var payload interface{}
|
||||
json.Unmarshal([]byte(content), &payload)
|
||||
m := payload.(map[string]interface{})
|
||||
|
||||
translations := make(map[string]string)
|
||||
|
||||
for j := range m {
|
||||
translations[j] = m[j].(string)
|
||||
}
|
||||
|
||||
localeMap[locales[i]] = translations
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Localize will returns string value for given key using specified locale).
|
||||
// e.g. locale = "en-US", key = "admin_billing"
|
||||
//
|
||||
// Replacements are for replacing string placeholders ({1} {2} {3}) with
|
||||
// replacement text.
|
||||
// e.g. "This is {1} example" --> replacements[0] will replace {1}
|
||||
func Localize(locale string, key string, replacements ...string) (s string) {
|
||||
l, ok := localeMap[locale]
|
||||
if !ok {
|
||||
// fallback
|
||||
l = localeMap[DefaultLocale]
|
||||
}
|
||||
|
||||
s, ok = l[key]
|
||||
if !ok {
|
||||
// missing translation key is echo'ed back
|
||||
s = fmt.Sprintf("!! %s !!", key)
|
||||
}
|
||||
|
||||
// placeholders are one-based: {1} {2} {3}
|
||||
// replacements array is zero-based hence the +1 below
|
||||
if len(replacements) > 0 {
|
||||
for i := range replacements {
|
||||
s = strings.Replace(s, fmt.Sprintf("{%d}", i+1), replacements[i], 1)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
|
@ -14,10 +14,9 @@ package osutil
|
|||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
"github.com/documize/community/core/log"
|
||||
)
|
||||
|
||||
var errTimeout = errors.New("conversion timelimit exceeded")
|
||||
|
@ -39,7 +38,7 @@ func CommandWithTimeout(command *exec.Cmd, timeout time.Duration) ([]byte, error
|
|||
select {
|
||||
case <-time.After(timeout):
|
||||
if err := command.Process.Kill(); err != nil {
|
||||
log.Error("failed to kill: ", err)
|
||||
fmt.Printf("failed to kill: %s", err.Error())
|
||||
}
|
||||
<-done // prevent memory leak
|
||||
//fmt.Println("DEBUG timeout")
|
||||
|
|
29
core/request/url.go
Normal file
29
core/request/url.go
Normal file
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
// Package request provides HTTP request parsing functions.
|
||||
package request
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// IsSSL returns true if Referer header contains "https".
|
||||
// If Referer header is empty we look at r.TLS setting.
|
||||
func IsSSL(r *http.Request) bool {
|
||||
rf := r.Referer()
|
||||
if len(rf) > 1 {
|
||||
return strings.HasPrefix(rf, "https")
|
||||
}
|
||||
|
||||
return r.TLS != nil
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue