Compare commits
892 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 209c50c585 | |||
| d726f5ffe9 | |||
| cecc1e4b52 | |||
| 157c0a2479 | |||
| 3d3a836c52 | |||
| 24efa54481 | |||
| 1bf85ab1db | |||
| 1d94c4b9bb | |||
| 13e704e36c | |||
| 413b266335 | |||
| 7cb0886b35 | |||
| d0e7344e2d | |||
| 8fdc14f360 | |||
| 915b24e4e4 | |||
| a24e5bd10c | |||
| 3457018fb4 | |||
| bfc87922cb | |||
| 09def9f352 | |||
| 934e2066a0 | |||
| b254b4fcda | |||
| 4dad427a64 | |||
| 9e1424fb24 | |||
| ad978c60df | |||
| dfe96dccde | |||
| 981519eac0 | |||
| 16ab7b70cf | |||
| b2093e6dfa | |||
| 3f8dffee3f | |||
| 204a9c9d53 | |||
| 531dee1e75 | |||
| 297e054381 | |||
| e9eecb2031 | |||
| 4f289a222f | |||
| e92631c623 | |||
| 93bb75511b | |||
| 5d9e1087f4 | |||
| 0308c8096e | |||
| 02469f110f | |||
| 851a2a3de8 | |||
| 74ccc34124 | |||
| f5a445101d | |||
| 2cdeb38521 | |||
| b3834c296b | |||
| 198b74f4de | |||
| 3c7580ff7b | |||
| c0ad292ebb | |||
| 4ef55aa7d0 | |||
| 3dc0bbeff3 | |||
| b205f19f40 | |||
| 727c32843c | |||
| 78a63b20c7 | |||
| c3e99205de | |||
| 66ba6f51da | |||
| 8625c8da43 | |||
| d86db3fc11 | |||
| ac4128d89e | |||
| 11f2855442 | |||
| d09be604d9 | |||
| d8355c368f | |||
| 703092c12c | |||
| 9b212121e3 | |||
| 88145d70fc | |||
| 320cc48132 | |||
| ac6e399847 | |||
| d2649e9354 | |||
| 0aaf284f7f | |||
| a21c9420b1 | |||
| b396cc340c | |||
| 4b9ce6bb10 | |||
| 55d0ca2557 | |||
| d57ebf021c | |||
| a2899b21b6 | |||
| 1089b4b9bb | |||
| 2428af3c40 | |||
| ffd5d61f9f | |||
| 5b1f2ef95d | |||
| 08c3b6bff5 | |||
| ccc2a0e811 | |||
| 445e6d41b7 | |||
| 82e11d7e0a | |||
| 2cc5256c00 | |||
| 6f83d3c865 | |||
| 3325627fd2 | |||
| bec54a0467 | |||
| 4fc265275b | |||
| a95360036d | |||
| 6873c12f04 | |||
| 0daa80efa4 | |||
| 1f2c4e38ac | |||
| b9b4721295 | |||
| 7a7adfb61f | |||
| defcb727f9 | |||
| e4f19f7192 | |||
| 0e565ddbf8 | |||
| 438133ae1f | |||
| 7ef7b23e93 | |||
| 6e1314ae30 | |||
| 75ff3b26c1 | |||
| 505b541040 | |||
| fbc12b607d | |||
| cb7440bbbf | |||
| cd355910b3 | |||
| 5452ebaf6d | |||
| cec4376d19 | |||
| 53c52abde5 | |||
| 0d63b13bf0 | |||
| 65b2d08997 | |||
| 2b7154622e | |||
| 0baf5eab0a | |||
| 16ac2c5589 | |||
| 4743fc0e1d | |||
| f8409be506 | |||
| f1f9e1742e | |||
| 455395154a | |||
| 3087eff147 | |||
| 8e2eccb392 | |||
| a0af474c75 | |||
| 7e8364eae4 | |||
| e7a9ee8142 | |||
| 806d835a90 | |||
| 617fd9ab17 | |||
| fe6df58e66 | |||
| 6bd647f8c6 | |||
| 8d0df6cec3 | |||
| 5997e0ce8c | |||
| 8bdd694a12 | |||
| ee2068de56 | |||
| dfed93a4ab | |||
| 4e17463eb8 | |||
| df391c86f3 | |||
| 67f0a65811 | |||
| 9d77114d50 | |||
| d2be30a228 | |||
| 9ed1101f27 | |||
| f60b91110f | |||
| db6714d3b8 | |||
| 47c8de4ca1 | |||
| 802e6d7979 | |||
| 249126a2b5 | |||
| ea591c87a2 | |||
| f3fc83fae6 | |||
| d005af2b11 | |||
| 3b60815e53 | |||
| b0b05cf785 | |||
| d5d213cd44 | |||
| 2d56879d92 | |||
| 13d07c7ba3 | |||
| ece7178ef5 | |||
| ab63d2664c | |||
| f829ac4e6c | |||
| 28dd9aa081 | |||
| eb8556c792 | |||
| 84e4c78bb9 | |||
| 6123c0d475 | |||
| 12ad9dd36b | |||
| ba040674cb | |||
| 3fa77dbf3d | |||
| 9fa435dbb2 | |||
| 02c1e88da2 | |||
| 87e60ef26b | |||
| 87845ee907 | |||
| 405538544f | |||
| afca2e70bd | |||
| 31d67161ab | |||
| 66e3869b06 | |||
| 600be987a7 | |||
| fdcfc48e06 | |||
| eb46b16800 | |||
| 392445b53a | |||
| 7c93b8f157 | |||
| 2f84e76952 | |||
| 12a30d3ffd | |||
| 7e1f90fb3b | |||
| 9865596dcc | |||
| 7393d9c372 | |||
| c87a22f347 | |||
| dc44a7a3a7 | |||
| 79c4d7797c | |||
| feb5567621 | |||
| 9cab789425 | |||
| ab3202b560 | |||
| a0cd542ba3 | |||
| e10ce234db | |||
| 7f02bc7d1d | |||
| 44b6738b0d | |||
| fbb19cba0b | |||
| 84554101f2 | |||
| 8a3b2e038c | |||
| ff595df7ca | |||
| 01a895bbf7 | |||
| 296d7964ae | |||
| 88349c6b66 | |||
| ed5effd190 | |||
| c6671f7f8e | |||
| 44c966bd44 | |||
| 046ed8ec85 | |||
| aabe6defb2 | |||
| 3245c82ea6 | |||
| beacc5bba8 | |||
| 57e58c6cf7 | |||
| 34e45abcc7 | |||
| 7ffe0398f9 | |||
| ce5b3531e0 | |||
| b3497011e8 | |||
| a398881fa1 | |||
| a9a5d00916 | |||
| 2cf3a7831c | |||
| 62a71f8052 | |||
| 0138091a6c | |||
| 36eccb472c | |||
| 6c0fb2f849 | |||
| 289d50d170 | |||
| e495faf83c | |||
| 0517f29134 | |||
| 467cf8d762 | |||
| 2cdb6d86ad | |||
| d474f60465 | |||
| caf4d1fe34 | |||
| e4f346620e | |||
| be4536cf16 | |||
| 89429bd65a | |||
| 6d3faf91d8 | |||
| 345e6091d2 | |||
| 86a97c30d1 | |||
| 14915e9da7 | |||
| 366058581a | |||
| 9f6a7dec2e | |||
| be30bb0ad0 | |||
| 600a29514f | |||
| 9efec9244b | |||
| ded1a22e45 | |||
| 2e83ac9282 | |||
| 9538981730 | |||
| 791222c3ce | |||
| 1095815878 | |||
| a8bdab8f5c | |||
| ff952a6df1 | |||
| 87e7cec02e | |||
| 5c8cd60275 | |||
| e2483dc874 | |||
| 6482d849e3 | |||
| 34f137c8cf | |||
| 16d8f8846e | |||
| 108416638c | |||
| 20d28ea215 | |||
| 27bc309c55 | |||
| b5b4ee79b4 | |||
| 45227357fd | |||
| a2ba0f6a4c | |||
| 415916c527 | |||
| 40a55cb9df | |||
| 5a9ca8d09f | |||
| 1bfcc9053e | |||
| 3930ae244c | |||
| 365ad2981d | |||
| ca56655d07 | |||
| 8721423f40 | |||
| 49b3351c72 | |||
| 4612c03657 | |||
| 41093e5b8b | |||
| faef449750 | |||
| 4a24064783 | |||
| 0ab84fc443 | |||
| fca74ad8d7 | |||
| 7bc7dba86d | |||
| efd6bd82bd | |||
| 17527c99eb | |||
| 361557dc39 | |||
| ca75a25802 | |||
| ece31733a9 | |||
| 28a8027179 | |||
| 4fa523db43 | |||
| 186460ac08 | |||
| a97604d6c4 | |||
| 308f929f7b | |||
| 342b2087e9 | |||
| c8d7df1515 | |||
| 2c795662d2 | |||
| 8a43e3a87e | |||
| 210e43fcb0 | |||
| beb8c7ac7c | |||
| 2f8979bbc3 | |||
| a8ed7f2c17 | |||
| 1c6bf55e5d | |||
| dc371c1979 | |||
| c246044ac7 | |||
| 5126521d37 | |||
| 27223738c6 | |||
| 2faa4defd8 | |||
| bb8356d7db | |||
| 686f6752f3 | |||
| 66ff4d191a | |||
| 21218b0332 | |||
| 23ccdeb2cf | |||
| 6148ce4e52 | |||
| 06850ed25c | |||
| 0320a56cb5 | |||
| 968463912a | |||
| b9e44f381b | |||
| cd27bb210f | |||
| 67f680a675 | |||
| 47c3e3a79f | |||
| 02f49a0039 | |||
| 05c6b856f9 | |||
| b07df63422 | |||
| 487e45b45b | |||
| 929c84822a | |||
| 993f11cd2c | |||
| 6544b5c272 | |||
| 817a458334 | |||
| f3bfc1ffb2 | |||
| 3603090421 | |||
| 6fe3089207 | |||
| 79159b684d | |||
| 26d4d056be | |||
| 6ad28f1103 | |||
| 89cd655df2 | |||
| 14c4c4815d | |||
| bfb69a34ef | |||
| b675f6252c | |||
| d52420183e | |||
| 0cbe0b4796 | |||
| 06b136fdf6 | |||
| c6246b5404 | |||
| 3062f40ef5 | |||
| dcd0d38419 | |||
| 0feb053e51 | |||
| c01a8f8f13 | |||
| 09c8ae4e7e | |||
| da71a94c39 | |||
| f6413af3f4 | |||
| 2aaca865e7 | |||
| 2ec8281163 | |||
| 77dda5a70f | |||
| 440e649d6d | |||
| f6a8d487cc | |||
| 47dcd37d1d | |||
| d60fc63e78 | |||
| b0c4042e87 | |||
| da525513a3 | |||
| 2ac5e61e44 | |||
| 101a8b6c78 | |||
| f7a10e3a15 | |||
| 4e0dd728a8 | |||
| 320ccf8105 | |||
| 62f924a757 | |||
| c47a08b553 | |||
| de9241bcf5 | |||
| 7c03fe3c1f | |||
| 82eb241119 | |||
| 1073e6257c | |||
| bc3e4847fe | |||
| 1a7251909c | |||
| 61a18297d9 | |||
| bdd413f9ee | |||
| fd8ca35e63 | |||
| fdd9aee773 | |||
| 59bf24c461 | |||
| 2748c3635d | |||
| d31e71a838 | |||
| 3c2a92d3b6 | |||
| cf49e6160a | |||
| 2252db0d55 | |||
| ec93030e21 | |||
| 1d49c8626e | |||
| 89bb94aa1a | |||
| 03a4b75176 | |||
| 943b54dcf7 | |||
| 39bd18ec1a | |||
| df896af476 | |||
| e93ddff46b | |||
| 3144b51c91 | |||
| e92f68d040 | |||
| 469054e9b3 | |||
| d17022d87d | |||
| 6865629090 | |||
| a4749f201d | |||
| ad90264ef1 | |||
| 9ba7e7742a | |||
| 6473f600c7 | |||
| 78735ff349 | |||
| 4b605b2580 | |||
| 80d7f1b2c9 | |||
| 1af43498d9 | |||
| 6329dfa629 | |||
| 5ada85df29 | |||
| 015ad64e30 | |||
| 2cd0173534 | |||
| 6dbb988903 | |||
| 926acb910e | |||
| a0bcfeddcc | |||
| c4b5483d8c | |||
| 57e3187e3a | |||
| 988d51c4c8 | |||
| 4733256ca1 | |||
| 4133a1fe76 | |||
| 37bf6fe938 | |||
| 31716e574c | |||
| 126c4cbd46 | |||
| 7cc91f71c2 | |||
| 7c52b9602c | |||
| c5f1cc15fd | |||
| d089518681 | |||
| cd6ef35bf9 | |||
| 47cdc79fcb | |||
| f7382255c2 | |||
| 2167eada0c | |||
| df11935598 | |||
| d3b4b9fe64 | |||
| 33aff7ff61 | |||
| 4d2c551b79 | |||
| 5b7ae7150f | |||
| 5bf29a907a | |||
| 96d5bdd7b2 | |||
| 7b4023fd5a | |||
| af72729905 | |||
| d5bc54cf6c | |||
| 5625102e2c | |||
| 66abd7b50c | |||
| 2a9bcf0e98 | |||
| e6484687e5 | |||
| 5da1e64bbc | |||
| 7b0979f9fd | |||
| 1a437c1c6a | |||
| 3c0565e516 | |||
| 178b1ccf40 | |||
| c03cd81c23 | |||
| 3d3647b476 | |||
| a4cac670df | |||
| c414dd06cc | |||
| 4ed746e4ef | |||
| c270d8ecac | |||
| ade9bb7324 | |||
| 4134dd16df | |||
| f81588bb13 | |||
| 09793a1744 | |||
| ba7cd48b8f | |||
| 640d2cedb9 | |||
| 0a6237af04 | |||
| 503183331f | |||
| 3effc66b2c | |||
| b64f303537 | |||
| 760f6a1647 | |||
| 0b64e34f05 | |||
| f01be09075 | |||
| 1c5ed58074 | |||
| 42d86f147f | |||
| fa4acb255b | |||
| 1885767ef1 | |||
| 80e6880bb7 | |||
| fabacd1689 | |||
| 23a7654cea | |||
| b2d019bfe1 | |||
| 9f817bf032 | |||
| 01c89bd338 | |||
| e5956e4955 | |||
| 958c3b147b | |||
| 4a33ca99ba | |||
| 568835f7e2 | |||
| 84aa861a5b | |||
| ee2ebc7d14 | |||
| 9ce996cbba | |||
| 580ba79619 | |||
| fbe184ef6e | |||
| 2f7bf413ed | |||
| 390613c796 | |||
| b3e3475bf5 | |||
| 5333b23c23 | |||
| 734086fcf5 | |||
| 12dff9bca3 | |||
| f370e738da | |||
| a018ed9e52 | |||
| 17f73b88dc | |||
| 405e9a79be | |||
| 4d90322842 | |||
| a8b5d69be0 | |||
| 5ebd90aba5 | |||
| bec909c284 | |||
| 46e0b08d65 | |||
| 7a178be031 | |||
| 9d14c9e0b7 | |||
| ef19633a90 | |||
| 80ffd026f6 | |||
| cb7300688c | |||
| 040ebfe9dd | |||
| 44e567aa34 | |||
| 8c5f253b41 | |||
| 7b99e55148 | |||
| ba27eff5cf | |||
| 01d5a12039 | |||
| 6d4d26009f | |||
| 857a8b163d | |||
| acbe82f4c8 | |||
| fad33a97b2 | |||
| 3bfd9b71e2 | |||
| ef714ac258 | |||
| 975816ddd7 | |||
| 8831860174 | |||
| fbf3015de4 | |||
| be587b2064 | |||
| 347c2e8238 | |||
| f5fde0f19e | |||
| ac586c5207 | |||
| 8033931e31 | |||
| 8e29810598 | |||
| be96e2cf08 | |||
| 534ee67ad2 | |||
| 571a3bc257 | |||
| c12bdaacbf | |||
| e7a30d0a5d | |||
| a55323176f | |||
| 1b83e0a87d | |||
| ca15f340b0 | |||
| 23b8e1cce8 | |||
| cf53ba363d | |||
| 1c4b262c57 | |||
| 90d591e5a8 | |||
| ad121bd758 | |||
| 8d67e39e9a | |||
| bd8e344736 | |||
| 014eba971e | |||
| 2f309a2fd6 | |||
| a5fb2d2025 | |||
| 40311f8590 | |||
| a0c51fb212 | |||
| b306e41560 | |||
| 9f45d41a4a | |||
| e8d6daf59a | |||
| a0966be565 | |||
| ba064ba4f5 | |||
| 1994194656 | |||
| 1da2c00f0a | |||
| 71d076aba2 | |||
| c7ec1deee6 | |||
| 36559b8761 | |||
| 8fe7c5599a | |||
| 4dd325cec9 | |||
| d558646d75 | |||
| afac4bb918 | |||
| 0869bf27c7 | |||
| 383a8617ce | |||
| 3865f4fb50 | |||
| d7d58644e5 | |||
| 3e74bbfb45 | |||
| 966b07ba1c | |||
| 56669b5c84 | |||
| 60ed6f6b20 | |||
| 903c163a57 | |||
| 41b8294ce3 | |||
| d4311fe4ab | |||
| eab597a2a8 | |||
| 003ee1a991 | |||
| 601d48277e | |||
| aed6ef28e6 | |||
| 339ae32c3d | |||
| 7d990a2cbb | |||
| b98812b119 | |||
| fafd045ed2 | |||
| acf63fc74d | |||
| 85565f2c5f | |||
| ac6625a80c | |||
| 6d7b439aec | |||
| 9fffdb407a | |||
| 9170061810 | |||
| a7da3d741f | |||
| 255bd10296 | |||
| 4fca0bb735 | |||
| f7aaad86c5 | |||
| 8d12170def | |||
| d2655a9f2f | |||
| c4c2082fa9 | |||
| 40d4a8fe6a | |||
| 4c443b9e2e | |||
| 2898203cb9 | |||
| 5ebdfc7b1c | |||
| 31d7e58191 | |||
| ad4416f663 | |||
| b55d2a8a41 | |||
| 17a4799b97 | |||
| b0121c44b1 | |||
| be9d8e7da7 | |||
| d129989c3d | |||
| 2870ce5e0a | |||
| da1e2680cb | |||
| cd2ce2486a | |||
| 5d4f2ec697 | |||
| c2cb85f1cd | |||
| 4df838c20c | |||
| 4e44871671 | |||
| 37d3692cd0 | |||
| f4b2ff93fc | |||
| 5ea6ebcc66 | |||
| f6ac64f705 | |||
| fcfb107653 | |||
| 7557c584d8 | |||
| f829bb8023 | |||
| 1dd2c1cb91 | |||
| 23702ee4dc | |||
| 5c2b0647f3 | |||
| c7a725ad94 | |||
| 5c6a9480a6 | |||
| c1be8e3f00 | |||
| d8dbda8e94 | |||
| a0ab7ace07 | |||
| 7c27189e2e | |||
| 76cbfdb787 | |||
| 56545ad7f1 | |||
| 832dc7f4a5 | |||
| 62dc68e7b2 | |||
| 348c79d841 | |||
| 994c6eed50 | |||
| 9614740410 | |||
| 62e6168e03 | |||
| b6d762c279 | |||
| ab93c4ff2d | |||
| 473c39f7c4 | |||
| 811aea7898 | |||
| 07358eb46d | |||
| 067af64dff | |||
| cb428bb288 | |||
| b69c981100 | |||
| 1709879b14 | |||
| cff5046a9e | |||
| 9f6da2ca4b | |||
| 0c8b0edcda | |||
| 68f9e89a32 | |||
| fecadeec51 | |||
| d3b675a213 | |||
| 316ab6becb | |||
| 9a45bda430 | |||
| 7c11943836 | |||
| 94d2a5cbad | |||
| 99cabe564d | |||
| b0488d2d94 | |||
| 600c8ebbbf | |||
| 3bf43d7ce3 | |||
| 15b1d35c17 | |||
| 872db5877f | |||
| 977c1d9585 | |||
| 46f4984add | |||
| e39e132feb | |||
| 17b479275e | |||
| 9927ff3c86 | |||
| 81077c2681 | |||
| f4593778cb | |||
| 16f6bbcbd4 | |||
| c597da8f97 | |||
| 5775a8b614 | |||
| cc4a7653e5 | |||
| 5b546cc425 | |||
| 7f5f304d2d | |||
| 0827ced915 | |||
| 9c252131f7 | |||
| dec042fce4 | |||
| 8eafadc29b | |||
| c5347a97ce | |||
| 8a19cd4bbc | |||
| 2797011fb0 | |||
| 1307ee7ced | |||
| e0059f1fad | |||
| fd5b5b67bf | |||
| 7ba4c2f353 | |||
| 0381c55ce7 | |||
| 88d9e3321c | |||
| 05f479a58f | |||
| d8180604e8 | |||
| e6a8ba84aa | |||
| 39d93a7ace | |||
| 5ddf21f09f | |||
| 7b3ab72105 | |||
| 1f64ae4682 | |||
| 120f4c3096 | |||
| e59d75f4f9 | |||
| e3b2d427a4 | |||
| 22f54394fb | |||
| 57c368f70d | |||
| 14a056f4f4 | |||
| 580de6befe | |||
| 0120dc6ea3 | |||
| 79cd312912 | |||
| 9b36bc4097 | |||
| 9f346e6ee2 | |||
| 3ea9504620 | |||
| 86db972188 | |||
| 6d12eea789 | |||
| 68174bc7df | |||
| 5ca9600c98 | |||
| 87b3fb5539 | |||
| 4be6a48fb2 | |||
| 53731049de | |||
| 7fd6bfa163 | |||
| 4b2ce522fe | |||
| d0eddbb9a2 | |||
| 938abab9d6 | |||
| 5faa71187d | |||
| c069f262dc | |||
| ac79fe7a77 | |||
| 9f42e6a607 | |||
| 3f8fe334b2 | |||
| 096004db13 | |||
| 202f2d2e27 | |||
| aaab14be3e | |||
| 1c87176d80 | |||
| c17dbbe141 | |||
| 1dde60a1d5 | |||
| 04967143d8 | |||
| 70fb48d94a | |||
| 760d1d7daa | |||
| 3135353a1a | |||
| 1565ff1661 | |||
| bc55d96cde | |||
| 3d2379d582 | |||
| 73e907291b | |||
| 49c76c744e | |||
| 8967061758 | |||
| eff8075102 | |||
| 849feb0683 | |||
| a182c9b1ee | |||
| 17675d389e | |||
| f30aefb614 | |||
| a1722f268c | |||
| 864d83f8f7 | |||
| 2f978e96d4 | |||
| dccc6238e0 | |||
| 0687125343 | |||
| de36edfd58 | |||
| 2842a56356 | |||
| 661246b5f5 | |||
| 457474ecf9 | |||
| 5f67b3a9c1 | |||
| a3547a79e8 | |||
| c6467b355d | |||
| e2ef186dd1 | |||
| 0ccc40bf52 | |||
| ebc21a1cc7 | |||
| 30067d92ae | |||
| 342f924e8f | |||
| ba12efd285 | |||
| ed3efe9bee | |||
| 47a7c08686 | |||
| 5191dbf011 | |||
| 8d9ae085aa | |||
| 161d6505eb | |||
| c292f7ff03 | |||
| 17860fb8c7 | |||
| eb642dc611 | |||
| bc99d074a9 | |||
| d536bebdbe | |||
| 3639d952d5 | |||
| 7c79cf318e | |||
| 6ad1607685 | |||
| c1ed2b9f45 | |||
| 2c5eeaeac8 | |||
| a74a0c343e | |||
| 4eb897ccff | |||
| 20dc77c330 | |||
| 4c79863130 | |||
| 9ec95c7aa2 | |||
| 38bfd07883 | |||
| ce15b7c7c4 | |||
| b090de3cde | |||
| dbd74f5273 | |||
| e87f8b14be | |||
| fb14a4987c | |||
| a471e7d25e | |||
| a8e2798add | |||
| 983144c3f9 | |||
| c451498975 | |||
| b366c5da03 | |||
| 24998425fc | |||
| 8579b5a89b | |||
| 1ad4414026 | |||
| 70e4b7d931 | |||
| 49d2a6dbf0 | |||
| d52d0819ab | |||
| 0dedd7b2d4 | |||
| ca25b3199b | |||
| 457427a5f4 | |||
| 5046bc019c | |||
| 187ab9ba46 | |||
| 3a813d2d77 | |||
| 460653d078 | |||
| beb9068805 | |||
| f5a00cc3bd | |||
| 86aef126fd | |||
| 0e9d0a5a10 | |||
| a4f1b433eb | |||
| 08b386e180 | |||
| c6cabf1239 | |||
| f07fcac13d | |||
| e2746604a1 | |||
| e9b5225676 | |||
| ea4f1a0f56 | |||
| c2046ad173 | |||
| f080260396 | |||
| 5d1da3ada1 | |||
| 2b84f96836 | |||
| 28b669d3a3 | |||
| d5e63c0e62 | |||
| 066a860c1d | |||
| 225688facf | |||
| 8bc28a4d81 | |||
| c0f650436b | |||
| e7e74840bc | |||
| d16002eb7c | |||
| 1a54a24150 | |||
| ceb1260509 | |||
| 9706a0f76a | |||
| 12d79f2d08 | |||
| ef15c247c2 | |||
| d255cd115b | |||
| 19e2b1c24e | |||
| c0c9f4dfcc | |||
| 61ba78538a | |||
| cb76914a27 | |||
| 9b0d16f0ad | |||
| 3377888219 | |||
| 0b924f75d4 | |||
| 301b16a036 | |||
| 919fb79db9 | |||
| ba9aa49b91 | |||
| 7fed43cc68 | |||
| a1828fec51 | |||
| 35645672ae | |||
| f952877d04 | |||
| 62a6a4ec92 | |||
| 943e050493 | |||
| e958ca6f89 | |||
| 0a752c8985 | |||
| b6ad19ccad | |||
| bea1d35ebf | |||
| dae8802c50 | |||
| 58cdff1d71 | |||
| d69a978870 | |||
| 93bc2dc95b | |||
| 1bcf40402c | |||
| 7b101f0b9e | |||
| dad3f31f86 | |||
| 7cd31ce970 | |||
| 54a8796d51 | |||
| e091987f0f | |||
| 60a3cdc5ab | |||
| 03006d7698 | |||
| 8344372ae2 | |||
| d52f6b5810 | |||
| 4fa07389dd | |||
| 33b857d2c6 | |||
| 2bdbd86787 | |||
| adc7201e86 | |||
| bb0331e9cc | |||
| 25b8c8a565 | |||
| eb390f8d80 | |||
| be93773399 | |||
| 6f0baa4a8e | |||
| a56f3b23d1 | |||
| 4feb766cc6 | |||
| 55d4457c70 | |||
| 05c85bbce5 | |||
| 2270188668 | |||
| 41e14a62c0 | |||
| a996d46b6f | |||
| e062ea8d31 | |||
| 7cf13cbf94 | |||
| afda7a5661 | |||
| 11ef00c63d | |||
| 2b54cc50ab | |||
| 99319e0b49 | |||
| f99302ac63 | |||
| 890d7d8ce3 | |||
| f039b00a44 | |||
| 34ad8dfb8d | |||
| 2c436d5ae0 | |||
| 6b23a8221d | |||
| 92a0ec2964 | |||
| 760b7ad0ce | |||
| b6918253c0 | |||
| 0f969ecdd4 | |||
| db867c66a3 | |||
| 34a3389c17 | |||
| beb325eacf | |||
| 8e45bcf23f | |||
| 40dc49ed47 | |||
| 4b07305dc5 | |||
| 2514a59e93 | |||
| 6843da790c | |||
| ba1a9c3758 | |||
| 332ad6349d | |||
| 42e48426e4 | |||
| a0cc788f27 | |||
| aecf96d74d | |||
| c75938076e | |||
| cebbcb711a |
@@ -0,0 +1,35 @@
|
||||
# Contributing to Umbraco CMS
|
||||
|
||||
When you’re considering creating a pull request for Umbraco CMS, we will categorize them in two different sizes, small and large.
|
||||
|
||||
The process for both sizes is very similar, as [explained in the contribution document](CONTRIBUTING.md#how-do-i-begin).
|
||||
|
||||
## Small PRs
|
||||
Bug fixes and small improvements - can be recognized by seeing a small number of changes and possibly a small number of new files.
|
||||
|
||||
We’re usually able to handle small PRs pretty quickly. A community volunteer will do the initial review and flag it for Umbraco HQ as “community tested”. If everything looks good, it will be merged pretty quickly [as per the described process](REVIEW_PROCESS.md).
|
||||
|
||||
### Up for grabs
|
||||
|
||||
Umbraco HQ will regularly mark newly created issues on the issue tracker with the `Up for grabs` tag. This means that the proposed changes are wanted in Umbraco but the HQ does not have the time to make them at this time. We encourage anyone to pick them up and help out.
|
||||
|
||||
If you do start working on something, make sure leave a small comment on the issue saying something like: "I'm working on this". That way other people stumbling upon the issue know they don't need to pick it up, someone already has.
|
||||
|
||||
## Large PRs
|
||||
New features and large refactorings - can be recognized by seeing a large number of changes, plenty of new files, updates to package manager files (NuGet’s packages.config, NPM’s packages.json, etc.).
|
||||
|
||||
We would love to follow the same process for larger PRs but this is not always possible due to time limitations and priorities that need to be aligned. We don’t want to put up any barriers, but this document should set the correct expectations.
|
||||
|
||||
Please make sure to describe your idea in an issue, it helps to put in mockup screenshots or videos.
|
||||
|
||||
If the change makes sense for HQ to include in Umbraco CMS we will leave you some feedback on how we’d like to see it being implemented.
|
||||
|
||||
If a larger pull request is encouraged by Umbraco HQ, the process will be similar to what is described in the [small PRs process](#small-prs) above, we strive to feedback within 14 days. Finalizing and merging the PR might take longer though as it will likely need to be picked up by the development team to make sure everything is in order. We’ll keep you posted on the progress.
|
||||
|
||||
It is highly recommended that you speak to the HQ before making large, complex changes.
|
||||
|
||||
### Pull request or package?
|
||||
|
||||
If it doesn’t fit in CMS right now, we will likely encourage you to make it into a package instead. A package is a great way to check out popularity of a feature, learn how people use it, validate good usability and to fix bugs.
|
||||
|
||||
Eventually, a package could "graduate" to be included in the CMS.
|
||||
@@ -12,7 +12,7 @@ thoroughly. Then, proceed by filling out the rest of the details in the issue
|
||||
template below. The more details you can give us, the easier it will be for us
|
||||
to determine the cause of a problem.
|
||||
|
||||
See: https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/.github/CONTRIBUTING.md
|
||||
See: https://github.com/umbraco/Umbraco-CMS/blob/v8/dev/.github/CONTRIBUTING.md
|
||||
|
||||
-->
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# Review process
|
||||
|
||||
You're an awesome person and have sent us your contribution in the form of a pull request! It's now time to relax for a bit and wait for our response.
|
||||
|
||||
In order to set some expectations, here's what happens next.
|
||||
|
||||
## Review process
|
||||
|
||||
You will get an initial reply within 48 hours (workdays) to acknowledge that we’ve seen your PR and we’ll pick it up as soon as we can.
|
||||
|
||||
You will get feedback within at most 14 days after opening the PR. You’ll most likely get feedback sooner though. Then there are a few possible outcomes:
|
||||
|
||||
- Your proposed change is awesome! We merge it in and it will be included in the next minor release of Umbraco
|
||||
- If the change is a high priority bug fix, we will cherry-pick it into the next patch release as well so that we can release it as soon as possible
|
||||
- Your proposed change is awesome but needs a bit more work, we’ll give you feedback on the changes we’d like to see
|
||||
- Your proposed change is awesome but.. not something we’re looking to include at this point. We’ll close your PR and the related issue (we’ll be nice about it!)
|
||||
|
||||
## Are you still available?
|
||||
|
||||
We understand you have other things to do and can't just drop everything to help us out.
|
||||
So if we’re asking for your help to improve the PR we’ll wait for two weeks to give you a fair chance to make changes. We’ll ask for an update if we don’t hear back from you after that time.
|
||||
|
||||
If we don’t hear back from you for 4 weeks, we’ll close the PR so that it doesn’t just hang around forever. You’re very welcome to re-open it once you have some more time to spend on it.
|
||||
|
||||
There will be times that we really like your proposed changes and we’ll finish the final improvements we’d like to see ourselves. You still get the credits and your commits will live on in the git repository.
|
||||
@@ -14,6 +14,7 @@
|
||||
<summary>Contains the core assemblies needed to run Umbraco Cms</summary>
|
||||
<language>en-US</language>
|
||||
<tags>umbraco</tags>
|
||||
<repository type="git" url="https://github.com/umbraco/umbraco-cms" />
|
||||
<dependencies>
|
||||
|
||||
<group targetFramework="net472">
|
||||
@@ -44,7 +45,7 @@
|
||||
<dependency id="Umbraco.SqlServerCE" version="[4.0.0.1,4.999999)" />
|
||||
<dependency id="NPoco" version="[3.9.4,3.999999)" />
|
||||
</group>
|
||||
|
||||
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
@@ -52,9 +53,9 @@
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Core.dll" target="lib\net472\Umbraco.Core.dll" />
|
||||
|
||||
<!-- docs -->
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Core.xml" target="lib\Umbraco.Core.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Core.xml" target="lib\net472\Umbraco.Core.xml" />
|
||||
|
||||
<!-- symbols -->
|
||||
<file src="$BuildTmp$\bin\Umbraco.Core.pdb" target="lib" />
|
||||
<file src="$BuildTmp$\bin\Umbraco.Core.pdb" target="lib\net472\Umbraco.Core.pdb" />
|
||||
</files>
|
||||
</package>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<summary>Contains the core assemblies needed to run Umbraco Cms</summary>
|
||||
<language>en-US</language>
|
||||
<tags>umbraco</tags>
|
||||
<repository type="git" url="https://github.com/umbraco/umbraco-cms" />
|
||||
<dependencies>
|
||||
|
||||
<group targetFramework="net472">
|
||||
@@ -43,7 +44,7 @@
|
||||
<dependency id="System.Threading.Tasks.Dataflow" version="[4.9.0,4.999999)" />
|
||||
|
||||
</group>
|
||||
|
||||
|
||||
</dependencies>
|
||||
</metadata>
|
||||
<files>
|
||||
@@ -53,12 +54,12 @@
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Examine.dll" target="lib\net472\Umbraco.Examine.dll" />
|
||||
|
||||
<!-- docs -->
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Web.xml" target="lib\Umbraco.Web.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Web.UI.xml" target="lib\Umbraco.Web.UI.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Examine.xml" target="lib\Umbraco.Examine.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Web.xml" target="lib\net472\Umbraco.Web.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Web.UI.xml" target="lib\net472\Umbraco.Web.UI.xml" />
|
||||
<file src="$BuildTmp$\WebApp\bin\Umbraco.Examine.xml" target="lib\net472\Umbraco.Examine.xml" />
|
||||
|
||||
<!-- symbols -->
|
||||
<file src="$BuildTmp$\bin\Umbraco.Web.pdb" target="lib" />
|
||||
<file src="$BuildTmp$\bin\Umbraco.Examine.pdb" target="lib" />
|
||||
<file src="$BuildTmp$\bin\Umbraco.Web.pdb" target="lib\net472\Umbraco.Web.pdb" />
|
||||
<file src="$BuildTmp$\bin\Umbraco.Examine.pdb" target="lib\net472\Umbraco.Examine.pdb" />
|
||||
</files>
|
||||
</package>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<summary>Installs Umbraco Cms in your Visual Studio ASP.NET project</summary>
|
||||
<language>en-US</language>
|
||||
<tags>umbraco</tags>
|
||||
<repository type="git" url="https://github.com/umbraco/umbraco-cms" />
|
||||
<dependencies>
|
||||
|
||||
<group targetFramework="net472">
|
||||
@@ -25,7 +26,7 @@
|
||||
not want this to happen as the alpha of the next major is, really, the next major already.
|
||||
-->
|
||||
<dependency id="Microsoft.AspNet.SignalR.Core" version="[2.4.0, 2.999999)" />
|
||||
<dependency id="Umbraco.ModelsBuilder.Ui" version="[8.0.4]" />
|
||||
<dependency id="Umbraco.ModelsBuilder.Ui" version="[8.1.0]" />
|
||||
<dependency id="ImageProcessor.Web" version="[4.10.0.100,4.999999)" />
|
||||
<dependency id="ImageProcessor.Web.Config" version="[2.5.0.100,2.999999)" />
|
||||
<dependency id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="[2.0.1,2.999999)" />
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
|
||||
888
|
||||
888
|
||||
888 888 88888b.d88b. 88888b. 888d888 8888b. .d8888b .d88b.
|
||||
888 888 888 "888 "88b 888 "88b 888P" "88b d88P" d88""88b
|
||||
888 888 888 888 888 888 888 888 .d888888 888 888 888
|
||||
Y88b 888 888 888 888 888 d88P 888 888 888 Y88b. Y88..88P
|
||||
"Y88888 888 888 888 88888P" 888 "Y888888 "Y8888P "Y88P"
|
||||
888
|
||||
888
|
||||
888 888 88888b.d88b. 88888b. 888d888 8888b. .d8888b .d88b.
|
||||
888 888 888 "888 "88b 888 "88b 888P" "88b d88P" d88""88b
|
||||
888 888 888 888 888 888 888 888 .d888888 888 888 888
|
||||
Y88 88Y 888 888 888 888 d88P 888 888 888 Y88b. Y88..88P
|
||||
"Y888P" 888 888 888 88888P" 888 "Y888888 "Y8888P "Y88P"
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
|
||||
_ _ __ __ ____ _____ _____ ____
|
||||
| | | | \/ | _ \| __ \ /\ / ____/ __ \
|
||||
| | | | \ / | |_) | |__) | / \ | | | | | |
|
||||
| | | | |\/| | _ <| _ / / /\ \| | | | | |
|
||||
| |__| | | | | |_) | | \ \ / ____ | |___| |__| |
|
||||
\____/|_| |_|____/|_| \_/_/ \_\_____\____/
|
||||
888
|
||||
888
|
||||
888 888 88888b.d88b. 88888b. 888d888 8888b. .d8888b .d88b.
|
||||
888 888 888 "888 "88b 888 "88b 888P" "88b d88P" d88""88b
|
||||
888 888 888 888 888 888 888 888 .d888888 888 888 888
|
||||
Y88 88Y 888 888 888 888 d88P 888 888 888 Y88b. Y88..88P
|
||||
"Y888P" 888 888 888 88888P" 888 "Y888888 "Y8888P "Y88P"
|
||||
|
||||
----------------------------------------------------
|
||||
------------------------------------------------------------------
|
||||
|
||||
Don't forget to build!
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
</configSections>
|
||||
|
||||
<system.web.webPages.razor>
|
||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" xdt:Locator="Match(factoryType)" xdt:Transform="SetAttributes(factoryType)" />
|
||||
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" xdt:Locator="Match(factoryType)" xdt:Transform="SetAttributes(factoryType)" />
|
||||
<pages pageBaseType="System.Web.Mvc.WebViewPage">
|
||||
<namespaces>
|
||||
<add namespace="Umbraco.Web.PublishedContentModels" xdt:Transform="InsertIfMissing" />
|
||||
@@ -18,13 +18,13 @@
|
||||
|
||||
<system.web>
|
||||
<pages
|
||||
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
|
||||
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
|
||||
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
|
||||
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
|
||||
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
|
||||
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
|
||||
xdt:Locator="Match(pageParserFilterType,pageBaseType,userControlBaseType)"
|
||||
xdt:Transform="SetAttributes(pageParserFilterType,pageBaseType,userControlBaseType)">
|
||||
<controls>
|
||||
<add assembly="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" xdt:Locator="Match(namespace)" xdt:Transform="SetAttributes(assembly)" />
|
||||
<add assembly="System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" xdt:Locator="Match(namespace)" xdt:Transform="SetAttributes(assembly)" />
|
||||
</controls>
|
||||
</pages>
|
||||
</system.web>
|
||||
|
||||
@@ -18,9 +18,20 @@ if ($project) {
|
||||
|
||||
# Copy umbraco and umbraco_files from package to project folder
|
||||
$umbracoFolder = Join-Path $projectPath "Umbraco"
|
||||
New-Item -ItemType Directory -Force -Path $umbracoFolder
|
||||
New-Item -ItemType Directory -Force -Path $umbracoFolder
|
||||
$umbracoFolderSource = Join-Path $installPath "UmbracoFiles\Umbraco"
|
||||
robocopy $umbracoFolderSource $umbracoFolder /is /it /e /xf UI.xml /LOG:$copyLogsPath\UmbracoCopy.log
|
||||
|
||||
Write-Host "copying files to $umbracoFolder ..."
|
||||
# see https://support.microsoft.com/en-us/help/954404/return-codes-that-are-used-by-the-robocopy-utility-in-windows-server-2
|
||||
robocopy $umbracoFolderSource $umbracoFolder /is /it /e
|
||||
if (($lastexitcode -eq 1) -or ($lastexitcode -eq 3) -or ($lastexitcode -eq 5) -or ($lastexitcode -eq 7))
|
||||
{
|
||||
write-host "Copy succeeded!"
|
||||
}
|
||||
else
|
||||
{
|
||||
write-host "Copy failed with exit code:" $lastexitcode
|
||||
}
|
||||
|
||||
$copyWebconfig = $true
|
||||
$destinationWebConfig = Join-Path $projectPath "Web.config"
|
||||
@@ -40,7 +51,11 @@ if ($project) {
|
||||
}
|
||||
}
|
||||
}
|
||||
Catch { }
|
||||
Catch
|
||||
{
|
||||
Write-Host "An error occurred:"
|
||||
Write-Host $_
|
||||
}
|
||||
}
|
||||
|
||||
if($copyWebconfig -eq $true)
|
||||
@@ -74,7 +89,9 @@ if ($project) {
|
||||
}
|
||||
Catch
|
||||
{
|
||||
# Not a big problem if this fails, let it go
|
||||
# Not a big problem if this fails, let it go
|
||||
# Write-Host "An error occurred:"
|
||||
# Write-Host $_
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-10
@@ -15,7 +15,7 @@
|
||||
[Parameter(Mandatory=$false)]
|
||||
[Alias("doc")]
|
||||
[switch] $docfx = $false,
|
||||
|
||||
|
||||
# keep the build directories, don't clear them
|
||||
[Parameter(Mandatory=$false)]
|
||||
[Alias("c")]
|
||||
@@ -392,13 +392,13 @@
|
||||
&$this.BuildEnv.NuGet Pack "$nuspecs\UmbracoCms.Core.nuspec" `
|
||||
-Properties BuildTmp="$($this.BuildTemp)" `
|
||||
-Version "$($this.Version.Semver.ToString())" `
|
||||
-Symbols -SymbolPackageFormat snupkg -Verbosity detailed -outputDirectory "$($this.BuildOutput)" > "$($this.BuildTemp)\nupack.cmscore.log"
|
||||
-Verbosity detailed -outputDirectory "$($this.BuildOutput)" > "$($this.BuildTemp)\nupack.cmscore.log"
|
||||
if (-not $?) { throw "Failed to pack NuGet UmbracoCms.Core." }
|
||||
|
||||
&$this.BuildEnv.NuGet Pack "$nuspecs\UmbracoCms.Web.nuspec" `
|
||||
-Properties BuildTmp="$($this.BuildTemp)" `
|
||||
-Version "$($this.Version.Semver.ToString())" `
|
||||
-Symbols -SymbolPackageFormat snupkg -Verbosity detailed -outputDirectory "$($this.BuildOutput)" > "$($this.BuildTemp)\nupack.cmsweb.log"
|
||||
-Verbosity detailed -outputDirectory "$($this.BuildOutput)" > "$($this.BuildTemp)\nupack.cmsweb.log"
|
||||
if (-not $?) { throw "Failed to pack NuGet UmbracoCms.Web." }
|
||||
|
||||
&$this.BuildEnv.NuGet Pack "$nuspecs\UmbracoCms.nuspec" `
|
||||
@@ -429,37 +429,37 @@
|
||||
Write-Host "Prepare Azure Gallery"
|
||||
$this.CopyFile("$($this.SolutionRoot)\build\Azure\azuregalleryrelease.ps1", $this.BuildOutput)
|
||||
})
|
||||
|
||||
|
||||
$ubuild.DefineMethod("PrepareCSharpDocs",
|
||||
{
|
||||
Write-Host "Prepare C# Documentation"
|
||||
|
||||
|
||||
$src = "$($this.SolutionRoot)\src"
|
||||
$tmp = $this.BuildTemp
|
||||
$out = $this.BuildOutput
|
||||
$DocFxJson = Join-Path -Path $src "\ApiDocs\docfx.json"
|
||||
$DocFxSiteOutput = Join-Path -Path $tmp "\_site\*.*"
|
||||
|
||||
|
||||
|
||||
#restore nuget packages
|
||||
$this.RestoreNuGet()
|
||||
# run DocFx
|
||||
$DocFx = $this.BuildEnv.DocFx
|
||||
|
||||
|
||||
& $DocFx metadata $DocFxJson
|
||||
& $DocFx build $DocFxJson
|
||||
|
||||
# zip it
|
||||
& $this.BuildEnv.Zip a -tzip -r "$out\csharp-docs.zip" $DocFxSiteOutput
|
||||
})
|
||||
|
||||
|
||||
$ubuild.DefineMethod("PrepareAngularDocs",
|
||||
{
|
||||
Write-Host "Prepare Angular Documentation"
|
||||
|
||||
|
||||
$src = "$($this.SolutionRoot)\src"
|
||||
$out = $this.BuildOutput
|
||||
|
||||
|
||||
$this.CompileBelle()
|
||||
|
||||
"Moving to Umbraco.Web.UI.Client folder"
|
||||
|
||||
+2
-2
@@ -18,5 +18,5 @@ using System.Resources;
|
||||
[assembly: AssemblyVersion("8.0.0")]
|
||||
|
||||
// these are FYI and changed automatically
|
||||
[assembly: AssemblyFileVersion("8.1.0")]
|
||||
[assembly: AssemblyInformationalVersion("8.1.0")]
|
||||
[assembly: AssemblyFileVersion("8.2.0")]
|
||||
[assembly: AssemblyInformationalVersion("8.2.0")]
|
||||
|
||||
@@ -67,31 +67,34 @@ namespace Umbraco.Core
|
||||
: new NamedSemaphoreReleaser(_semaphore2);
|
||||
}
|
||||
|
||||
public Task<IDisposable> LockAsync()
|
||||
{
|
||||
var wait = _semaphore != null
|
||||
? _semaphore.WaitAsync()
|
||||
: _semaphore2.WaitOneAsync();
|
||||
//NOTE: We don't use the "Async" part of this lock at all
|
||||
//TODO: Remove this and rename this class something like SystemWideLock, then we can re-instate this logic if we ever need an Async lock again
|
||||
|
||||
return wait.IsCompleted
|
||||
? _releaserTask ?? Task.FromResult(CreateReleaser()) // anonymous vs named
|
||||
: wait.ContinueWith((_, state) => (((AsyncLock) state).CreateReleaser()),
|
||||
this, CancellationToken.None,
|
||||
TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
|
||||
}
|
||||
//public Task<IDisposable> LockAsync()
|
||||
//{
|
||||
// var wait = _semaphore != null
|
||||
// ? _semaphore.WaitAsync()
|
||||
// : _semaphore2.WaitOneAsync();
|
||||
|
||||
public Task<IDisposable> LockAsync(int millisecondsTimeout)
|
||||
{
|
||||
var wait = _semaphore != null
|
||||
? _semaphore.WaitAsync(millisecondsTimeout)
|
||||
: _semaphore2.WaitOneAsync(millisecondsTimeout);
|
||||
// return wait.IsCompleted
|
||||
// ? _releaserTask ?? Task.FromResult(CreateReleaser()) // anonymous vs named
|
||||
// : wait.ContinueWith((_, state) => (((AsyncLock) state).CreateReleaser()),
|
||||
// this, CancellationToken.None,
|
||||
// TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
|
||||
//}
|
||||
|
||||
return wait.IsCompleted
|
||||
? _releaserTask ?? Task.FromResult(CreateReleaser()) // anonymous vs named
|
||||
: wait.ContinueWith((_, state) => (((AsyncLock)state).CreateReleaser()),
|
||||
this, CancellationToken.None,
|
||||
TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
|
||||
}
|
||||
//public Task<IDisposable> LockAsync(int millisecondsTimeout)
|
||||
//{
|
||||
// var wait = _semaphore != null
|
||||
// ? _semaphore.WaitAsync(millisecondsTimeout)
|
||||
// : _semaphore2.WaitOneAsync(millisecondsTimeout);
|
||||
|
||||
// return wait.IsCompleted
|
||||
// ? _releaserTask ?? Task.FromResult(CreateReleaser()) // anonymous vs named
|
||||
// : wait.ContinueWith((_, state) => (((AsyncLock)state).CreateReleaser()),
|
||||
// this, CancellationToken.None,
|
||||
// TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
|
||||
//}
|
||||
|
||||
public IDisposable Lock()
|
||||
{
|
||||
|
||||
@@ -44,21 +44,22 @@ namespace Umbraco.Core.Compose
|
||||
public void Terminate()
|
||||
{ }
|
||||
|
||||
internal static IUser UnknownUser => new User { Id = Constants.Security.UnknownUserId, Name = Constants.Security.UnknownUserName, Email = "" };
|
||||
|
||||
private IUser CurrentPerformingUser
|
||||
{
|
||||
get
|
||||
{
|
||||
var identity = Thread.CurrentPrincipal?.GetUmbracoIdentity();
|
||||
return identity == null
|
||||
? new User { Id = 0, Name = "SYSTEM", Email = "" }
|
||||
: _userService.GetUserById(Convert.ToInt32(identity.Id));
|
||||
var user = identity == null ? null : _userService.GetUserById(Convert.ToInt32(identity.Id));
|
||||
return user ?? UnknownUser;
|
||||
}
|
||||
}
|
||||
|
||||
private IUser GetPerformingUser(int userId)
|
||||
{
|
||||
var found = userId >= 0 ? _userService.GetUserById(userId) : null;
|
||||
return found ?? new User {Id = 0, Name = "SYSTEM", Email = ""};
|
||||
return found ?? UnknownUser;
|
||||
}
|
||||
|
||||
private string PerformingIp
|
||||
|
||||
@@ -90,7 +90,7 @@ namespace Umbraco.Core.Composing.CompositionExtensions
|
||||
// register the IFileSystem supporting the IMediaFileSystem
|
||||
// THIS IS THE ONLY THING THAT NEEDS TO CHANGE, IN ORDER TO REPLACE THE UNDERLYING FILESYSTEM
|
||||
// and, SupportingFileSystem.For<IMediaFileSystem>() returns the underlying filesystem
|
||||
composition.SetMediaFileSystem(() => new PhysicalFileSystem("~/media"));
|
||||
composition.SetMediaFileSystem(() => new PhysicalFileSystem(SystemDirectories.Media));
|
||||
|
||||
return composition;
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace Umbraco.Core.Composing.CompositionExtensions
|
||||
var pluginLangFolders = appPlugins.Exists == false
|
||||
? Enumerable.Empty<LocalizedTextServiceSupplementaryFileSource>()
|
||||
: appPlugins.GetDirectories()
|
||||
.SelectMany(x => x.GetDirectories("Lang"))
|
||||
.SelectMany(x => x.GetDirectories("Lang", SearchOption.AllDirectories))
|
||||
.SelectMany(x => x.GetFiles("*.xml", SearchOption.TopDirectoryOnly))
|
||||
.Select(x => new LocalizedTextServiceSupplementaryFileSource(x, false));
|
||||
|
||||
|
||||
@@ -12,31 +12,62 @@
|
||||
/// or MS.DI, PerDependency in Autofac.</remarks>
|
||||
Transient,
|
||||
|
||||
// TODO: We need to fix this up, currently LightInject is the only one that behaves differently from all other containers.
|
||||
// ... the simple fix would be to map this to PerScopeLifetime in LI but need to wait on a response here https://github.com/seesharper/LightInject/issues/494#issuecomment-518942625
|
||||
//
|
||||
// we use it for controllers, httpContextBase and other request scoped objects: MembershpHelper, TagQuery, UmbracoTreeSearcher and ISearchableTree
|
||||
// - so that they are automatically disposed at the end of the scope (ie request)
|
||||
// - not sure they should not be simply 'scoped'?
|
||||
|
||||
/// <summary>
|
||||
/// One unique instance per request.
|
||||
/// </summary>
|
||||
// TODO: review lifetimes for LightInject vs other containers
|
||||
// currently, corresponds to 'Request' in LightInject which is 'Transient + disposed by Scope'
|
||||
// but NOT (in LightInject) a per-web-request lifetime, more a TransientScoped
|
||||
//
|
||||
// we use it for controllers, httpContextBase and umbracoContext
|
||||
// - so that they are automatically disposed at the end of the scope (ie request)
|
||||
// - not sure they should not be simply 'scoped'?
|
||||
//
|
||||
// Castle has an extra PerWebRequest something, and others use scope
|
||||
// what about Request before first request ie during application startup?
|
||||
// see http://blog.ploeh.dk/2009/11/17/UsingCastleWindsor'sPerWebRequestlifestylewithASP.NETMVConIIS7/
|
||||
// Castle ends up requiring a special scope manager too
|
||||
// see https://groups.google.com/forum/#!topic/castle-project-users/1E2W9LVIYR4
|
||||
//
|
||||
// but maybe also - why are we requiring scoped services at startup?
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Any instance created with this lifetime will be disposed at the end of a request.
|
||||
/// </para>
|
||||
/// Corresponds to
|
||||
/// <para>
|
||||
/// PerRequestLifeTime in LightInject - means transient but disposed at the end of the current web request.
|
||||
/// see: https://github.com/seesharper/LightInject/issues/494#issuecomment-518493262
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Scoped in MS.DI - means one per web request.
|
||||
/// see https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.2#service-lifetimes</para>
|
||||
/// <para>
|
||||
/// InstancePerRequest in Autofac - means one per web request.
|
||||
/// see https://autofaccn.readthedocs.io/en/latest/lifetime/instance-scope.html#instance-per-request
|
||||
/// But "Behind the scenes, though, it’s still just instance per matching lifetime scope."
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// LifestylePerWebRequest in Castle Windsor - means one per web request.
|
||||
/// see https://github.com/castleproject/Windsor/blob/master/docs/mvc-tutorial-part-7-lifestyles.md#the-perwebrequest-lifestyle
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
Request,
|
||||
|
||||
/// <summary>
|
||||
/// One unique instance per container scope.
|
||||
/// One unique instance per scope.
|
||||
/// </summary>
|
||||
/// <remarks>Corresponds to Scope in LightInject, Scoped in MS.DI
|
||||
/// or Castle Windsor, PerLifetimeScope in Autofac.</remarks>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Any instance created with this lifetime will be disposed at the end of the current scope.
|
||||
/// </para>
|
||||
/// Corresponds to
|
||||
/// <para>PerScopeLifetime in LightInject (when in a request, means one per web request)</para>
|
||||
/// <para>
|
||||
/// Scoped in MS.DI (when in a request, means one per web request)
|
||||
/// see https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.2#service-lifetimes</para>
|
||||
/// <para>
|
||||
/// InstancePerLifetimeScope in Autofac (when in a request, means one per web request)
|
||||
/// see https://autofaccn.readthedocs.io/en/latest/lifetime/instance-scope.html#instance-per-lifetime-scope
|
||||
/// Also note that Autofac's InstancePerRequest is the same as this, see https://autofaccn.readthedocs.io/en/latest/lifetime/instance-scope.html#instance-per-request
|
||||
/// it says "Behind the scenes, though, it’s still just instance per matching lifetime scope."
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// LifestyleScoped in Castle Windsor
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
Scope,
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -42,8 +42,8 @@ namespace Umbraco.Core.Composing
|
||||
private string _currentAssembliesHash;
|
||||
private IEnumerable<Assembly> _assemblies;
|
||||
private bool _reportedChange;
|
||||
private static string _localTempPath;
|
||||
private static string _fileBasePath;
|
||||
private readonly string _localTempPath;
|
||||
private string _fileBasePath;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TypeLoader"/> class.
|
||||
|
||||
@@ -4,6 +4,7 @@ using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Dictionary;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging.Viewer;
|
||||
using Umbraco.Core.Manifest;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PackageActions;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
@@ -66,9 +67,16 @@ namespace Umbraco.Core
|
||||
/// Gets the validators collection builder.
|
||||
/// </summary>
|
||||
/// <param name="composition">The composition.</param>
|
||||
internal static ManifestValueValidatorCollectionBuilder Validators(this Composition composition)
|
||||
internal static ManifestValueValidatorCollectionBuilder ManifestValueValidators(this Composition composition)
|
||||
=> composition.WithCollectionBuilder<ManifestValueValidatorCollectionBuilder>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the manifest filter collection builder.
|
||||
/// </summary>
|
||||
/// <param name="composition">The composition.</param>
|
||||
public static ManifestFilterCollectionBuilder ManifestFilters(this Composition composition)
|
||||
=> composition.WithCollectionBuilder<ManifestFilterCollectionBuilder>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the components collection builder.
|
||||
/// </summary>
|
||||
|
||||
@@ -7,6 +7,7 @@ using Umbraco.Core.Configuration.HealthChecks;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Manifest;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
@@ -41,7 +42,12 @@ namespace Umbraco.Core
|
||||
configs.Add(() => new CoreDebug());
|
||||
|
||||
// GridConfig depends on runtime caches, manifest parsers... and cannot be available during composition
|
||||
configs.Add<IGridConfig>(factory => new GridConfig(factory.GetInstance<ILogger>(), factory.GetInstance<AppCaches>(), configDir, factory.GetInstance<IRuntimeState>().Debug));
|
||||
configs.Add<IGridConfig>(factory => new GridConfig(
|
||||
factory.GetInstance<ILogger>(),
|
||||
factory.GetInstance<AppCaches>(),
|
||||
configDir,
|
||||
factory.GetInstance<ManifestParser>(),
|
||||
factory.GetInstance<IRuntimeState>().Debug));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
using System.IO;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Manifest;
|
||||
|
||||
namespace Umbraco.Core.Configuration.Grid
|
||||
{
|
||||
class GridConfig : IGridConfig
|
||||
{
|
||||
public GridConfig(ILogger logger, AppCaches appCaches, DirectoryInfo configFolder, bool isDebug)
|
||||
public GridConfig(ILogger logger, AppCaches appCaches, DirectoryInfo configFolder, ManifestParser manifestParser, bool isDebug)
|
||||
{
|
||||
EditorsConfig = new GridEditorsConfig(logger, appCaches, configFolder, isDebug);
|
||||
EditorsConfig = new GridEditorsConfig(logger, appCaches, configFolder, manifestParser, isDebug);
|
||||
}
|
||||
|
||||
public IGridEditorsConfig EditorsConfig { get; }
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Manifest;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
@@ -15,13 +13,15 @@ namespace Umbraco.Core.Configuration.Grid
|
||||
private readonly ILogger _logger;
|
||||
private readonly AppCaches _appCaches;
|
||||
private readonly DirectoryInfo _configFolder;
|
||||
private readonly ManifestParser _manifestParser;
|
||||
private readonly bool _isDebug;
|
||||
|
||||
public GridEditorsConfig(ILogger logger, AppCaches appCaches, DirectoryInfo configFolder, bool isDebug)
|
||||
public GridEditorsConfig(ILogger logger, AppCaches appCaches, DirectoryInfo configFolder, ManifestParser manifestParser, bool isDebug)
|
||||
{
|
||||
_logger = logger;
|
||||
_appCaches = appCaches;
|
||||
_configFolder = configFolder;
|
||||
_manifestParser = manifestParser;
|
||||
_isDebug = isDebug;
|
||||
}
|
||||
|
||||
@@ -31,9 +31,6 @@ namespace Umbraco.Core.Configuration.Grid
|
||||
{
|
||||
List<GridEditor> GetResult()
|
||||
{
|
||||
// TODO: should use the common one somehow! + ignoring _appPlugins here!
|
||||
var parser = new ManifestParser(_appCaches, Current.ManifestValidators, _logger);
|
||||
|
||||
var editors = new List<GridEditor>();
|
||||
var gridConfig = Path.Combine(_configFolder.FullName, "grid.editors.config.js");
|
||||
if (File.Exists(gridConfig))
|
||||
@@ -42,7 +39,7 @@ namespace Umbraco.Core.Configuration.Grid
|
||||
|
||||
try
|
||||
{
|
||||
editors.AddRange(parser.ParseGridEditors(sourceString));
|
||||
editors.AddRange(_manifestParser.ParseGridEditors(sourceString));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -51,7 +48,7 @@ namespace Umbraco.Core.Configuration.Grid
|
||||
}
|
||||
|
||||
// add manifest editors, skip duplicates
|
||||
foreach (var gridEditor in parser.Manifest.GridEditors)
|
||||
foreach (var gridEditor in _manifestParser.Manifest.GridEditors)
|
||||
{
|
||||
if (editors.Contains(gridEditor) == false) editors.Add(gridEditor);
|
||||
}
|
||||
|
||||
@@ -1,27 +1,375 @@
|
||||
namespace Umbraco.Core
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
public static class DataTypes
|
||||
{
|
||||
public const int LabelString = -92;
|
||||
//NOTE: unfortunately due to backwards compat we can't move/rename these, with the addition of the GUID
|
||||
//constants, it would make more sense to have these suffixed with "ID" or in a Subclass called "INT", for
|
||||
//now all we can do is make a subclass called Guids to put the GUID IDs.
|
||||
|
||||
public const int LabelString = System.DefaultLabelDataTypeId;
|
||||
public const int LabelInt = -91;
|
||||
public const int LabelBigint = -93;
|
||||
public const int LabelDateTime = -94;
|
||||
public const int LabelTime = -98;
|
||||
public const int LabelDecimal = -99;
|
||||
|
||||
public const int Textarea = -89;
|
||||
public const int Textbox = -88;
|
||||
public const int RichtextEditor = -87;
|
||||
public const int Boolean = -49;
|
||||
public const int DateTime = -36;
|
||||
public const int DropDownSingle = -39;
|
||||
public const int DropDownMultiple = -42;
|
||||
public const int Upload = -90;
|
||||
|
||||
public const int DefaultContentListView = -95;
|
||||
public const int DefaultMediaListView = -96;
|
||||
public const int DefaultMembersListView = -97;
|
||||
|
||||
public const int ImageCropper = 1043;
|
||||
public const int Tags = 1041;
|
||||
|
||||
public static class ReservedPreValueKeys
|
||||
{
|
||||
public const string IgnoreUserStartNodes = "ignoreUserStartNodes";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines the identifiers for Umbraco data types as constants for easy centralized access/management.
|
||||
/// </summary>
|
||||
public static class Guids
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Content Picker as string
|
||||
/// </summary>
|
||||
public const string ContentPicker = "FD1E0DA5-5606-4862-B679-5D0CF3A52A59";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Content Picker
|
||||
/// </summary>
|
||||
public static readonly Guid ContentPickerGuid = new Guid(ContentPicker);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Member Picker as string
|
||||
/// </summary>
|
||||
public const string MemberPicker = "1EA2E01F-EBD8-4CE1-8D71-6B1149E63548";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Member Picker
|
||||
/// </summary>
|
||||
public static readonly Guid MemberPickerGuid = new Guid(MemberPicker);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Media Picker as string
|
||||
/// </summary>
|
||||
public const string MediaPicker = "135D60E0-64D9-49ED-AB08-893C9BA44AE5";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Media Picker
|
||||
/// </summary>
|
||||
public static readonly Guid MediaPickerGuid = new Guid(MediaPicker);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Multiple Media Picker as string
|
||||
/// </summary>
|
||||
public const string MultipleMediaPicker = "9DBBCBBB-2327-434A-B355-AF1B84E5010A";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Multiple Media Picker
|
||||
/// </summary>
|
||||
public static readonly Guid MultipleMediaPickerGuid = new Guid(MultipleMediaPicker);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Related Links as string
|
||||
/// </summary>
|
||||
public const string RelatedLinks = "B4E3535A-1753-47E2-8568-602CF8CFEE6F";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Related Links
|
||||
/// </summary>
|
||||
public static readonly Guid RelatedLinksGuid = new Guid(RelatedLinks);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Member as string
|
||||
/// </summary>
|
||||
public const string Member = "d59be02f-1df9-4228-aa1e-01917d806cda";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Member
|
||||
/// </summary>
|
||||
public static readonly Guid MemberGuid = new Guid(Member);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Image Cropper as string
|
||||
/// </summary>
|
||||
public const string ImageCropper = "1df9f033-e6d4-451f-b8d2-e0cbc50a836f";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Image Cropper
|
||||
/// </summary>
|
||||
public static readonly Guid ImageCropperGuid = new Guid(ImageCropper);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Tags as string
|
||||
/// </summary>
|
||||
public const string Tags = "b6b73142-b9c1-4bf8-a16d-e1c23320b549";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Tags
|
||||
/// </summary>
|
||||
public static readonly Guid TagsGuid = new Guid(Tags);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for List View - Content as string
|
||||
/// </summary>
|
||||
public const string ListViewContent = "C0808DD3-8133-4E4B-8CE8-E2BEA84A96A4";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for List View - Content
|
||||
/// </summary>
|
||||
public static readonly Guid ListViewContentGuid = new Guid(ListViewContent);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for List View - Media as string
|
||||
/// </summary>
|
||||
public const string ListViewMedia = "3A0156C4-3B8C-4803-BDC1-6871FAA83FFF";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for List View - Media
|
||||
/// </summary>
|
||||
public static readonly Guid ListViewMediaGuid = new Guid(ListViewMedia);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for List View - Members as string
|
||||
/// </summary>
|
||||
public const string ListViewMembers = "AA2C52A0-CE87-4E65-A47C-7DF09358585D";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for List View - Members
|
||||
/// </summary>
|
||||
public static readonly Guid ListViewMembersGuid = new Guid(ListViewMembers);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Date Picker with time as string
|
||||
/// </summary>
|
||||
public const string DatePickerWithTime = "e4d66c0f-b935-4200-81f0-025f7256b89a";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Date Picker with time
|
||||
/// </summary>
|
||||
public static readonly Guid DatePickerWithTimeGuid = new Guid(DatePickerWithTime);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Approved Color as string
|
||||
/// </summary>
|
||||
public const string ApprovedColor = "0225af17-b302-49cb-9176-b9f35cab9c17";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Approved Color
|
||||
/// </summary>
|
||||
public static readonly Guid ApprovedColorGuid = new Guid(ApprovedColor);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Dropdown multiple as string
|
||||
/// </summary>
|
||||
public const string DropdownMultiple = "f38f0ac7-1d27-439c-9f3f-089cd8825a53";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Dropdown multiple
|
||||
/// </summary>
|
||||
public static readonly Guid DropdownMultipleGuid = new Guid(DropdownMultiple);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Radiobox as string
|
||||
/// </summary>
|
||||
public const string Radiobox = "bb5f57c9-ce2b-4bb9-b697-4caca783a805";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Radiobox
|
||||
/// </summary>
|
||||
public static readonly Guid RadioboxGuid = new Guid(Radiobox);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Date Picker as string
|
||||
/// </summary>
|
||||
public const string DatePicker = "5046194e-4237-453c-a547-15db3a07c4e1";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Date Picker
|
||||
/// </summary>
|
||||
public static readonly Guid DatePickerGuid = new Guid(DatePicker);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Dropdown as string
|
||||
/// </summary>
|
||||
public const string Dropdown = "0b6a45e7-44ba-430d-9da5-4e46060b9e03";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Dropdown
|
||||
/// </summary>
|
||||
public static readonly Guid DropdownGuid = new Guid(Dropdown);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Checkbox list as string
|
||||
/// </summary>
|
||||
public const string CheckboxList = "fbaf13a8-4036-41f2-93a3-974f678c312a";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Checkbox list
|
||||
/// </summary>
|
||||
public static readonly Guid CheckboxListGuid = new Guid(CheckboxList);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Checkbox as string
|
||||
/// </summary>
|
||||
public const string Checkbox = "92897bc6-a5f3-4ffe-ae27-f2e7e33dda49";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Checkbox
|
||||
/// </summary>
|
||||
public static readonly Guid CheckboxGuid = new Guid(Checkbox);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Numeric as string
|
||||
/// </summary>
|
||||
public const string Numeric = "2e6d3631-066e-44b8-aec4-96f09099b2b5";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Dropdown
|
||||
/// </summary>
|
||||
public static readonly Guid NumericGuid = new Guid(Numeric);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Richtext editor as string
|
||||
/// </summary>
|
||||
public const string RichtextEditor = "ca90c950-0aff-4e72-b976-a30b1ac57dad";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Richtext editor
|
||||
/// </summary>
|
||||
public static readonly Guid RichtextEditorGuid = new Guid(RichtextEditor);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Textstring as string
|
||||
/// </summary>
|
||||
public const string Textstring = "0cc0eba1-9960-42c9-bf9b-60e150b429ae";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Textstring
|
||||
/// </summary>
|
||||
public static readonly Guid TextstringGuid = new Guid(Textstring);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Textarea as string
|
||||
/// </summary>
|
||||
public const string Textarea = "c6bac0dd-4ab9-45b1-8e30-e4b619ee5da3";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Dropdown
|
||||
/// </summary>
|
||||
public static readonly Guid TextareaGuid = new Guid(Textarea);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Upload as string
|
||||
/// </summary>
|
||||
public const string Upload = "84c6b441-31df-4ffe-b67e-67d5bc3ae65a";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Upload
|
||||
/// </summary>
|
||||
public static readonly Guid UploadGuid = new Guid(Upload);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label as string
|
||||
/// </summary>
|
||||
public const string LabelString = "f0bc4bfb-b499-40d6-ba86-058885a5178c";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label string
|
||||
/// </summary>
|
||||
public static readonly Guid LabelStringGuid = new Guid(LabelString);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label as int
|
||||
/// </summary>
|
||||
public const string LabelInt = "8e7f995c-bd81-4627-9932-c40e568ec788";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label int
|
||||
/// </summary>
|
||||
public static readonly Guid LabelIntGuid = new Guid(LabelInt);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label as big int
|
||||
/// </summary>
|
||||
public const string LabelBigInt = "930861bf-e262-4ead-a704-f99453565708";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label big int
|
||||
/// </summary>
|
||||
public static readonly Guid LabelBigIntGuid = new Guid(LabelBigInt);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label as date time
|
||||
/// </summary>
|
||||
public const string LabelDateTime = "0e9794eb-f9b5-4f20-a788-93acd233a7e4";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label date time
|
||||
/// </summary>
|
||||
public static readonly Guid LabelDateTimeGuid = new Guid(LabelDateTime);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label as time
|
||||
/// </summary>
|
||||
public const string LabelTime = "a97cec69-9b71-4c30-8b12-ec398860d7e8";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label time
|
||||
/// </summary>
|
||||
public static readonly Guid LabelTimeGuid = new Guid(LabelTime);
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label as decimal
|
||||
/// </summary>
|
||||
public const string LabelDecimal = "8f1ef1e1-9de4-40d3-a072-6673f631ca64";
|
||||
|
||||
/// <summary>
|
||||
/// Guid for Label decimal
|
||||
/// </summary>
|
||||
public static readonly Guid LabelDecimalGuid = new Guid(LabelDecimal);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,39 +5,89 @@
|
||||
public static class Icons
|
||||
{
|
||||
/// <summary>
|
||||
/// System contenttype icon
|
||||
/// System default icon
|
||||
/// </summary>
|
||||
public const string ContentType = "icon-arrangement";
|
||||
public const string DefaultIcon = Content;
|
||||
|
||||
/// <summary>
|
||||
/// System datatype icon
|
||||
/// System content icon
|
||||
/// </summary>
|
||||
public const string Content = "icon-document";
|
||||
|
||||
/// <summary>
|
||||
/// System content type icon
|
||||
/// </summary>
|
||||
public const string ContentType = "icon-item-arrangement";
|
||||
|
||||
/// <summary>
|
||||
/// System data type icon
|
||||
/// </summary>
|
||||
public const string DataType = "icon-autofill";
|
||||
|
||||
/// <summary>
|
||||
/// System property editor icon
|
||||
/// System list view icon
|
||||
/// </summary>
|
||||
public const string PropertyEditor = "icon-autofill";
|
||||
public const string ListView = "icon-thumbnail-list";
|
||||
|
||||
/// <summary>
|
||||
/// System macro icon
|
||||
/// </summary>
|
||||
public const string Macro = "icon-settings-alt";
|
||||
|
||||
/// <summary>
|
||||
/// System media file icon
|
||||
/// </summary>
|
||||
public const string MediaFile = "icon-document";
|
||||
|
||||
/// <summary>
|
||||
/// System media folder icon
|
||||
/// </summary>
|
||||
public const string MediaFolder = "icon-folder";
|
||||
|
||||
/// <summary>
|
||||
/// System media image icon
|
||||
/// </summary>
|
||||
public const string MediaImage = "icon-picture";
|
||||
|
||||
/// <summary>
|
||||
/// System media type icon
|
||||
/// </summary>
|
||||
public const string MediaType = "icon-thumbnails";
|
||||
|
||||
/// <summary>
|
||||
/// System member icon
|
||||
/// </summary>
|
||||
public const string Member = "icon-user";
|
||||
|
||||
/// <summary>
|
||||
/// System member icon
|
||||
/// System member group icon
|
||||
/// </summary>
|
||||
public const string MemberGroup = "icon-users-alt";
|
||||
|
||||
/// <summary>
|
||||
/// System member type icon
|
||||
/// </summary>
|
||||
public const string MemberType = "icon-users";
|
||||
|
||||
/// <summary>
|
||||
/// System property editor icon
|
||||
/// </summary>
|
||||
public const string PropertyEditor = "icon-autofill";
|
||||
|
||||
/// <summary>
|
||||
/// System member icon
|
||||
/// </summary>
|
||||
public const string Template = "icon-layout";
|
||||
|
||||
/// <summary>
|
||||
/// System user icon
|
||||
/// </summary>
|
||||
public const string User = "icon-user";
|
||||
|
||||
/// <summary>
|
||||
/// System user group icon
|
||||
/// </summary>
|
||||
public const string UserGroup = "icon-users";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,23 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string InternalGenericPropertiesPrefix = "_umb_";
|
||||
|
||||
public static class Legacy
|
||||
{
|
||||
public static class Aliases
|
||||
{
|
||||
public const string Textbox = "Umbraco.Textbox";
|
||||
public const string Date = "Umbraco.Date";
|
||||
public const string ContentPicker2 = "Umbraco.ContentPicker2";
|
||||
public const string MediaPicker2 = "Umbraco.MediaPicker2";
|
||||
public const string MemberPicker2 = "Umbraco.MemberPicker2";
|
||||
public const string MultiNodeTreePicker2 = "Umbraco.MultiNodeTreePicker2";
|
||||
public const string TextboxMultiple = "Umbraco.TextboxMultiple";
|
||||
public const string RelatedLinks2 = "Umbraco.RelatedLinks2";
|
||||
public const string RelatedLinks = "Umbraco.RelatedLinks";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines Umbraco built-in property editor aliases.
|
||||
/// </summary>
|
||||
@@ -79,6 +96,11 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string MediaPicker = "Umbraco.MediaPicker";
|
||||
|
||||
/// <summary>
|
||||
/// Multiple Media Picker.
|
||||
/// </summary>
|
||||
public const string MultipleMediaPicker = "Umbraco.MultipleMediaPicker";
|
||||
|
||||
/// <summary>
|
||||
/// Member Picker.
|
||||
/// </summary>
|
||||
@@ -186,6 +208,24 @@ namespace Umbraco.Core
|
||||
/// <remarks>Must be a valid <see cref="ValueTypes"/> value.</remarks>
|
||||
public const string DataValueType = "umbracoDataValueType";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Defines Umbraco's built-in property editor groups.
|
||||
/// </summary>
|
||||
public static class Groups
|
||||
{
|
||||
public const string Common = "Common";
|
||||
|
||||
public const string Lists = "Lists";
|
||||
|
||||
public const string Media = "Media";
|
||||
|
||||
public const string People = "People";
|
||||
|
||||
public const string Pickers = "Pickers";
|
||||
|
||||
public const string RichContent = "Rich Content";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,18 @@ namespace Umbraco.Core
|
||||
public const int SuperUserId = -1;
|
||||
|
||||
/// <summary>
|
||||
/// The id for the 'unknown' user
|
||||
/// The id for the 'unknown' user.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is a user row that exists in the DB only for referential integrity but the user is never returned from any of the services
|
||||
/// </remarks>
|
||||
public const int UnknownUserId = 0;
|
||||
|
||||
/// <summary>
|
||||
/// The name of the 'unknown' user.
|
||||
/// </summary>
|
||||
public const string UnknownUserName = "SYTEM";
|
||||
|
||||
public const string AdminGroupAlias = "admin";
|
||||
public const string SensitiveDataGroupAlias = "sensitiveData";
|
||||
public const string TranslatorGroupAlias = "translator";
|
||||
|
||||
@@ -66,44 +66,44 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// Determines whether the content type is invariant.
|
||||
/// </summary>
|
||||
public static bool VariesByNothing(this PublishedContentType contentType) => contentType.Variations.VariesByNothing();
|
||||
public static bool VariesByNothing(this IPublishedContentType contentType) => contentType.Variations.VariesByNothing();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the content type varies by culture.
|
||||
/// </summary>
|
||||
/// <remarks>And then it could also vary by segment.</remarks>
|
||||
public static bool VariesByCulture(this PublishedContentType contentType) => contentType.Variations.VariesByCulture();
|
||||
public static bool VariesByCulture(this IPublishedContentType contentType) => contentType.Variations.VariesByCulture();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the content type varies by segment.
|
||||
/// </summary>
|
||||
/// <remarks>And then it could also vary by culture.</remarks>
|
||||
public static bool VariesBySegment(this PublishedContentType contentType) => contentType.Variations.VariesBySegment();
|
||||
public static bool VariesBySegment(this IPublishedContentType contentType) => contentType.Variations.VariesBySegment();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the content type varies by culture and segment.
|
||||
/// </summary>
|
||||
public static bool VariesByCultureAndSegment(this PublishedContentType contentType) => contentType.Variations.VariesByCultureAndSegment();
|
||||
public static bool VariesByCultureAndSegment(this IPublishedContentType contentType) => contentType.Variations.VariesByCultureAndSegment();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the property type is invariant.
|
||||
/// </summary>
|
||||
public static bool VariesByNothing(this PublishedPropertyType propertyType) => propertyType.Variations.VariesByNothing();
|
||||
public static bool VariesByNothing(this IPublishedPropertyType propertyType) => propertyType.Variations.VariesByNothing();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the property type varies by culture.
|
||||
/// </summary>
|
||||
public static bool VariesByCulture(this PublishedPropertyType propertyType) => propertyType.Variations.VariesByCulture();
|
||||
public static bool VariesByCulture(this IPublishedPropertyType propertyType) => propertyType.Variations.VariesByCulture();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the property type varies by segment.
|
||||
/// </summary>
|
||||
public static bool VariesBySegment(this PublishedPropertyType propertyType) => propertyType.Variations.VariesBySegment();
|
||||
public static bool VariesBySegment(this IPublishedPropertyType propertyType) => propertyType.Variations.VariesBySegment();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the property type varies by culture and segment.
|
||||
/// </summary>
|
||||
public static bool VariesByCultureAndSegment(this PublishedPropertyType propertyType) => propertyType.Variations.VariesByCultureAndSegment();
|
||||
public static bool VariesByCultureAndSegment(this IPublishedPropertyType propertyType) => propertyType.Variations.VariesByCultureAndSegment();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether a variation is invariant.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
@@ -15,7 +16,7 @@ namespace Umbraco.Core
|
||||
/// <returns></returns>
|
||||
public static string ToIsoString(this DateTime dt)
|
||||
{
|
||||
return dt.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
return dt.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
|
||||
}
|
||||
|
||||
public static DateTime TruncateTo(this DateTime dt, DateTruncate truncateTo)
|
||||
|
||||
@@ -10,6 +10,8 @@ namespace Umbraco.Core
|
||||
///</summary>
|
||||
public static class EnumerableExtensions
|
||||
{
|
||||
internal static bool IsCollectionEmpty<T>(this IReadOnlyCollection<T> list) => list == null || list.Count == 0;
|
||||
|
||||
internal static bool HasDuplicates<T>(this IEnumerable<T> items, bool includeNull)
|
||||
{
|
||||
var hs = new HashSet<T>();
|
||||
@@ -112,7 +114,6 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if all items in the other collection exist in this collection
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Core.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Internal exception that in theory should never ben thrown, it is only thrown in circumstances that should never happen
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
internal class PanicException : Exception
|
||||
{
|
||||
public PanicException()
|
||||
{
|
||||
}
|
||||
|
||||
public PanicException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public PanicException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
protected PanicException(SerializationInfo info, StreamingContext context) : base(info, context)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,26 +26,32 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
/// A count of number of errors
|
||||
/// By counting Warnings with Exceptions, Errors & Fatal messages
|
||||
/// </summary>
|
||||
int GetNumberOfErrors(DateTimeOffset startDate, DateTimeOffset endDate);
|
||||
int GetNumberOfErrors(LogTimePeriod logTimePeriod);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a number of the different log level entries
|
||||
/// </summary>
|
||||
LogLevelCounts GetLogLevelCounts(DateTimeOffset startDate, DateTimeOffset endDate);
|
||||
LogLevelCounts GetLogLevelCounts(LogTimePeriod logTimePeriod);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of all unique message templates and their counts
|
||||
/// </summary>
|
||||
IEnumerable<LogTemplate> GetMessageTemplates(DateTimeOffset startDate, DateTimeOffset endDate);
|
||||
IEnumerable<LogTemplate> GetMessageTemplates(LogTimePeriod logTimePeriod);
|
||||
|
||||
bool CanHandleLargeLogs { get; }
|
||||
|
||||
bool CheckCanOpenLogs(DateTimeOffset startDate, DateTimeOffset endDate);
|
||||
bool CheckCanOpenLogs(LogTimePeriod logTimePeriod);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current Serilog minimum log level
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
string GetLogLevel();
|
||||
|
||||
/// <summary>
|
||||
/// Returns the collection of logs
|
||||
/// </summary>
|
||||
PagedResult<LogMessage> GetLogs(DateTimeOffset startDate, DateTimeOffset endDate,
|
||||
PagedResult<LogMessage> GetLogs(LogTimePeriod logTimePeriod,
|
||||
int pageNumber = 1,
|
||||
int pageSize = 100,
|
||||
Direction orderDirection = Direction.Descending,
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
|
||||
public override bool CanHandleLargeLogs => false;
|
||||
|
||||
public override bool CheckCanOpenLogs(DateTimeOffset startDate, DateTimeOffset endDate)
|
||||
public override bool CheckCanOpenLogs(LogTimePeriod logTimePeriod)
|
||||
{
|
||||
//Log Directory
|
||||
var logDirectory = _logsPath;
|
||||
@@ -36,7 +36,7 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
|
||||
//foreach full day in the range - see if we can find one or more filenames that end with
|
||||
//yyyyMMdd.json - Ends with due to MachineName in filenames - could be 1 or more due to load balancing
|
||||
for (var day = startDate.Date; day.Date <= endDate.Date; day = day.AddDays(1))
|
||||
for (var day = logTimePeriod.StartTime.Date; day.Date <= logTimePeriod.EndTime.Date; day = day.AddDays(1))
|
||||
{
|
||||
//Filename ending to search for (As could be multiple)
|
||||
var filesToFind = GetSearchPattern(day);
|
||||
@@ -57,7 +57,7 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
return $"*{day:yyyyMMdd}*.json";
|
||||
}
|
||||
|
||||
protected override IReadOnlyList<LogEvent> GetLogs(DateTimeOffset startDate, DateTimeOffset endDate, ILogFilter filter, int skip, int take)
|
||||
protected override IReadOnlyList<LogEvent> GetLogs(LogTimePeriod logTimePeriod, ILogFilter filter, int skip, int take)
|
||||
{
|
||||
var logs = new List<LogEvent>();
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
|
||||
//foreach full day in the range - see if we can find one or more filenames that end with
|
||||
//yyyyMMdd.json - Ends with due to MachineName in filenames - could be 1 or more due to load balancing
|
||||
for (var day = startDate.Date; day.Date <= endDate.Date; day = day.AddDays(1))
|
||||
for (var day = logTimePeriod.StartTime.Date; day.Date <= logTimePeriod.EndTime.Date; day = day.AddDays(1))
|
||||
{
|
||||
//Filename ending to search for (As could be multiple)
|
||||
var filesToFind = GetSearchPattern(day);
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Logging.Viewer
|
||||
{
|
||||
public class LogTimePeriod
|
||||
{
|
||||
public LogTimePeriod(DateTime startTime, DateTime endTime)
|
||||
{
|
||||
StartTime = startTime;
|
||||
EndTime = endTime;
|
||||
}
|
||||
|
||||
public DateTime StartTime { get; }
|
||||
public DateTime EndTime { get; }
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using Newtonsoft.Json;
|
||||
using Serilog;
|
||||
using Serilog.Events;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Formatting = Newtonsoft.Json.Formatting;
|
||||
|
||||
namespace Umbraco.Core.Logging.Viewer
|
||||
{
|
||||
@@ -27,9 +30,9 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
/// <summary>
|
||||
/// Get all logs from your chosen data source back as Serilog LogEvents
|
||||
/// </summary>
|
||||
protected abstract IReadOnlyList<LogEvent> GetLogs(DateTimeOffset startDate, DateTimeOffset endDate, ILogFilter filter, int skip, int take);
|
||||
protected abstract IReadOnlyList<LogEvent> GetLogs(LogTimePeriod logTimePeriod, ILogFilter filter, int skip, int take);
|
||||
|
||||
public abstract bool CheckCanOpenLogs(DateTimeOffset startDate, DateTimeOffset endDate);
|
||||
public abstract bool CheckCanOpenLogs(LogTimePeriod logTimePeriod);
|
||||
|
||||
public virtual IReadOnlyList<SavedLogSearch> GetSavedSearches()
|
||||
{
|
||||
@@ -82,24 +85,34 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
return searches;
|
||||
}
|
||||
|
||||
public int GetNumberOfErrors(DateTimeOffset startDate, DateTimeOffset endDate)
|
||||
public int GetNumberOfErrors(LogTimePeriod logTimePeriod)
|
||||
{
|
||||
var errorCounter = new ErrorCounterFilter();
|
||||
GetLogs(startDate, endDate, errorCounter, 0, int.MaxValue);
|
||||
GetLogs(logTimePeriod, errorCounter, 0, int.MaxValue);
|
||||
return errorCounter.Count;
|
||||
}
|
||||
|
||||
public LogLevelCounts GetLogLevelCounts(DateTimeOffset startDate, DateTimeOffset endDate)
|
||||
/// <summary>
|
||||
/// Get the Serilog minimum-level value from the config file.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string GetLogLevel()
|
||||
{
|
||||
var logLevel = Enum.GetValues(typeof(LogEventLevel)).Cast<LogEventLevel>().Where(Log.Logger.IsEnabled)?.Min() ?? null;
|
||||
return logLevel?.ToString() ?? "";
|
||||
}
|
||||
|
||||
public LogLevelCounts GetLogLevelCounts(LogTimePeriod logTimePeriod)
|
||||
{
|
||||
var counter = new CountingFilter();
|
||||
GetLogs(startDate, endDate, counter, 0, int.MaxValue);
|
||||
GetLogs(logTimePeriod, counter, 0, int.MaxValue);
|
||||
return counter.Counts;
|
||||
}
|
||||
|
||||
public IEnumerable<LogTemplate> GetMessageTemplates(DateTimeOffset startDate, DateTimeOffset endDate)
|
||||
public IEnumerable<LogTemplate> GetMessageTemplates(LogTimePeriod logTimePeriod)
|
||||
{
|
||||
var messageTemplates = new MessageTemplateFilter();
|
||||
GetLogs(startDate, endDate, messageTemplates, 0, int.MaxValue);
|
||||
GetLogs(logTimePeriod, messageTemplates, 0, int.MaxValue);
|
||||
|
||||
var templates = messageTemplates.Counts.
|
||||
Select(x => new LogTemplate { MessageTemplate = x.Key, Count = x.Value })
|
||||
@@ -108,14 +121,14 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
return templates;
|
||||
}
|
||||
|
||||
public PagedResult<LogMessage> GetLogs(DateTimeOffset startDate, DateTimeOffset endDate,
|
||||
public PagedResult<LogMessage> GetLogs(LogTimePeriod logTimePeriod,
|
||||
int pageNumber = 1, int pageSize = 100,
|
||||
Direction orderDirection = Direction.Descending,
|
||||
string filterExpression = null,
|
||||
string[] logLevels = null)
|
||||
{
|
||||
var expression = new ExpressionFilter(filterExpression);
|
||||
var filteredLogs = GetLogs(startDate, endDate, expression, 0, int.MaxValue);
|
||||
var filteredLogs = GetLogs(logTimePeriod, expression, 0, int.MaxValue);
|
||||
|
||||
//This is user used the checkbox UI to toggle which log levels they wish to see
|
||||
//If an empty array or null - its implied all levels to be viewed
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Web.Hosting;
|
||||
@@ -113,7 +114,7 @@ namespace Umbraco.Core
|
||||
|
||||
lock (_locko)
|
||||
{
|
||||
_logger.Debug<MainDom>("Signaled {Signaled} ({SignalSource})", _signaled ? "(again)" : string.Empty, source);
|
||||
_logger.Debug<MainDom>("Signaled ({Signaled}) ({SignalSource})", _signaled ? "again" : "first", source);
|
||||
if (_signaled) return;
|
||||
if (_isMainDom == false) return; // probably not needed
|
||||
_signaled = true;
|
||||
@@ -171,6 +172,7 @@ namespace Umbraco.Core
|
||||
// if more than 1 instance reach that point, one will get the lock
|
||||
// and the other one will timeout, which is accepted
|
||||
|
||||
//TODO: This can throw a TimeoutException - in which case should this be in a try/finally to ensure the signal is always reset?
|
||||
_asyncLocker = _asyncLock.Lock(LockTimeoutMilliseconds);
|
||||
_isMainDom = true;
|
||||
|
||||
@@ -181,6 +183,9 @@ namespace Umbraco.Core
|
||||
// which is accepted
|
||||
|
||||
_signal.Reset();
|
||||
|
||||
//WaitOneAsync (ext method) will wait for a signal without blocking the main thread, the waiting is done on a background thread
|
||||
|
||||
_signal.WaitOneAsync()
|
||||
.ContinueWith(_ => OnSignal("signal"));
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Manifest
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides filtering for package manifests.
|
||||
/// </summary>
|
||||
public interface IManifestFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Filters package manifests.
|
||||
/// </summary>
|
||||
/// <param name="manifests">The package manifests.</param>
|
||||
/// <remarks>
|
||||
/// <para>It is possible to remove, change, or add manifests.</para>
|
||||
/// </remarks>
|
||||
void Filter(List<PackageManifest> manifests);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Manifest
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains the manifest filters.
|
||||
/// </summary>
|
||||
public class ManifestFilterCollection : BuilderCollectionBase<IManifestFilter>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ManifestFilterCollection"/> class.
|
||||
/// </summary>
|
||||
public ManifestFilterCollection(IEnumerable<IManifestFilter> items)
|
||||
: base(items)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Filters package manifests.
|
||||
/// </summary>
|
||||
/// <param name="manifests">The package manifests.</param>
|
||||
public void Filter(List<PackageManifest> manifests)
|
||||
{
|
||||
foreach (var filter in this)
|
||||
filter.Filter(manifests);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Manifest
|
||||
{
|
||||
public class ManifestFilterCollectionBuilder : OrderedCollectionBuilderBase<ManifestFilterCollectionBuilder, ManifestFilterCollection, IManifestFilter>
|
||||
{
|
||||
protected override ManifestFilterCollectionBuilder This => this;
|
||||
|
||||
// do NOT cache this, it's only used once
|
||||
protected override Lifetime CollectionLifetime => Lifetime.Transient;
|
||||
}
|
||||
}
|
||||
@@ -22,24 +22,26 @@ namespace Umbraco.Core.Manifest
|
||||
private readonly IAppPolicyCache _cache;
|
||||
private readonly ILogger _logger;
|
||||
private readonly ManifestValueValidatorCollection _validators;
|
||||
private readonly ManifestFilterCollection _filters;
|
||||
|
||||
private string _path;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ManifestParser"/> class.
|
||||
/// </summary>
|
||||
public ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ILogger logger)
|
||||
: this(appCaches, validators, "~/App_Plugins", logger)
|
||||
public ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, ILogger logger)
|
||||
: this(appCaches, validators, filters, "~/App_Plugins", logger)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ManifestParser"/> class.
|
||||
/// </summary>
|
||||
private ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, string path, ILogger logger)
|
||||
private ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, string path, ILogger logger)
|
||||
{
|
||||
if (appCaches == null) throw new ArgumentNullException(nameof(appCaches));
|
||||
_cache = appCaches.RuntimeCache;
|
||||
_validators = validators ?? throw new ArgumentNullException(nameof(validators));
|
||||
_filters = filters ?? throw new ArgumentNullException(nameof(filters));
|
||||
if (string.IsNullOrWhiteSpace(path)) throw new ArgumentNullOrEmptyException(nameof(path));
|
||||
Path = path;
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
@@ -78,6 +80,7 @@ namespace Umbraco.Core.Manifest
|
||||
if (string.IsNullOrWhiteSpace(text))
|
||||
continue;
|
||||
var manifest = ParseManifest(text);
|
||||
manifest.Source = path;
|
||||
manifests.Add(manifest);
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -86,6 +89,8 @@ namespace Umbraco.Core.Manifest
|
||||
}
|
||||
}
|
||||
|
||||
_filters.Filter(manifests);
|
||||
|
||||
return manifests;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,16 @@ namespace Umbraco.Core.Manifest
|
||||
/// </summary>
|
||||
public class PackageManifest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the source path of the manifest.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Gets the full absolute file path of the manifest,
|
||||
/// using system directory separators.</para>
|
||||
/// </remarks>
|
||||
[JsonIgnore]
|
||||
public string Source { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the scripts listed in the manifest.
|
||||
/// </summary>
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Exceptions;
|
||||
|
||||
namespace Umbraco.Core.Mapping
|
||||
{
|
||||
@@ -191,7 +192,7 @@ namespace Umbraco.Core.Mapping
|
||||
private TTarget Map<TTarget>(object source, Type sourceType, MapperContext context)
|
||||
{
|
||||
if (source == null)
|
||||
throw new ArgumentNullException(nameof(source));
|
||||
return default;
|
||||
|
||||
var targetType = typeof(TTarget);
|
||||
|
||||
@@ -259,7 +260,7 @@ namespace Umbraco.Core.Mapping
|
||||
if (typeof(TTarget).IsArray)
|
||||
{
|
||||
var elementType = typeof(TTarget).GetElementType();
|
||||
if (elementType == null) throw new Exception("panic");
|
||||
if (elementType == null) throw new PanicException("elementType == null which should never occur");
|
||||
var targetArray = Array.CreateInstance(elementType, targetList.Count);
|
||||
targetList.CopyTo(targetArray, 0);
|
||||
target = targetArray;
|
||||
@@ -382,7 +383,7 @@ namespace Umbraco.Core.Mapping
|
||||
{
|
||||
if (type.IsArray) return type.GetElementType();
|
||||
if (type.IsGenericType) return type.GenericTypeArguments[0];
|
||||
throw new Exception("panic");
|
||||
throw new PanicException($"Could not get enumerable or array type from {type}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
+14
@@ -25,11 +25,25 @@ namespace Umbraco.Core.Migrations.Expressions.Create.KeysAndIndexes
|
||||
var syntax = _context.SqlContext.SqlSyntax;
|
||||
var tableDefinition = DefinitionFactory.GetTableDefinition(TypeOfDto, syntax);
|
||||
|
||||
// note: of course we are creating the keys and indexes as per the DTO, so
|
||||
// changing the DTO may break old migrations - or, better, these migrations
|
||||
// should capture a copy of the DTO class that will not change
|
||||
|
||||
ExecuteSql(syntax.FormatPrimaryKey(tableDefinition));
|
||||
foreach (var sql in syntax.Format(tableDefinition.Indexes))
|
||||
ExecuteSql(sql);
|
||||
foreach (var sql in syntax.Format(tableDefinition.ForeignKeys))
|
||||
ExecuteSql(sql);
|
||||
|
||||
// note: we do *not* create the DF_ default constraints
|
||||
/*
|
||||
foreach (var column in tableDefinition.Columns)
|
||||
{
|
||||
var sql = syntax.FormatDefaultConstraint(column);
|
||||
if (!sql.IsNullOrWhiteSpace())
|
||||
ExecuteSql(sql);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
private void ExecuteSql(string sql)
|
||||
|
||||
+9
-2
@@ -10,9 +10,13 @@ namespace Umbraco.Core.Migrations.Expressions.Delete.DefaultConstraint
|
||||
IDeleteDefaultConstraintOnTableBuilder,
|
||||
IDeleteDefaultConstraintOnColumnBuilder
|
||||
{
|
||||
public DeleteDefaultConstraintBuilder(DeleteDefaultConstraintExpression expression)
|
||||
private readonly IMigrationContext _context;
|
||||
|
||||
public DeleteDefaultConstraintBuilder(IMigrationContext context, DeleteDefaultConstraintExpression expression)
|
||||
: base(expression)
|
||||
{ }
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IDeleteDefaultConstraintOnColumnBuilder OnTable(string tableName)
|
||||
@@ -25,6 +29,9 @@ namespace Umbraco.Core.Migrations.Expressions.Delete.DefaultConstraint
|
||||
public IExecutableBuilder OnColumn(string columnName)
|
||||
{
|
||||
Expression.ColumnName = columnName;
|
||||
Expression.HasDefaultConstraint = _context.SqlContext.SqlSyntax.TryGetDefaultConstraint(_context.Database, Expression.TableName, columnName, out var constraintName);
|
||||
Expression.ConstraintName = constraintName ?? string.Empty;
|
||||
|
||||
return new ExecutableBuilder(Expression);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using NPoco;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Core.Migrations.Expressions.Common;
|
||||
using Umbraco.Core.Migrations.Expressions.Delete.Column;
|
||||
using Umbraco.Core.Migrations.Expressions.Delete.Constraint;
|
||||
@@ -29,9 +29,19 @@ namespace Umbraco.Core.Migrations.Expressions.Delete
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IExecutableBuilder KeysAndIndexes(string tableName = null)
|
||||
public IExecutableBuilder KeysAndIndexes<TDto>(bool local = true, bool foreign = true)
|
||||
{
|
||||
return new DeleteKeysAndIndexesBuilder(_context) { TableName = tableName };
|
||||
var syntax = _context.SqlContext.SqlSyntax;
|
||||
var tableDefinition = DefinitionFactory.GetTableDefinition(typeof(TDto), syntax);
|
||||
return KeysAndIndexes(tableDefinition.Name, local, foreign);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IExecutableBuilder KeysAndIndexes(string tableName, bool local = true, bool foreign = true)
|
||||
{
|
||||
if (tableName.IsNullOrWhiteSpace())
|
||||
throw new ArgumentNullOrEmptyException(nameof(tableName));
|
||||
return new DeleteKeysAndIndexesBuilder(_context) { TableName = tableName, DeleteLocal = local, DeleteForeign = foreign };
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -100,7 +110,7 @@ namespace Umbraco.Core.Migrations.Expressions.Delete
|
||||
public IDeleteDefaultConstraintOnTableBuilder DefaultConstraint()
|
||||
{
|
||||
var expression = new DeleteDefaultConstraintExpression(_context);
|
||||
return new DeleteDefaultConstraintBuilder(expression);
|
||||
return new DeleteDefaultConstraintBuilder(_context, expression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
-3
@@ -10,12 +10,17 @@ namespace Umbraco.Core.Migrations.Expressions.Delete.Expressions
|
||||
|
||||
public virtual string TableName { get; set; }
|
||||
public virtual string ColumnName { get; set; }
|
||||
public virtual string ConstraintName { get; set; }
|
||||
public virtual bool HasDefaultConstraint { get; set; }
|
||||
|
||||
protected override string GetSql()
|
||||
{
|
||||
return string.Format(SqlSyntax.DeleteDefaultConstraint,
|
||||
SqlSyntax.GetQuotedTableName(TableName),
|
||||
SqlSyntax.GetQuotedColumnName(ColumnName));
|
||||
return HasDefaultConstraint
|
||||
? string.Format(SqlSyntax.DeleteDefaultConstraint,
|
||||
SqlSyntax.GetQuotedTableName(TableName),
|
||||
SqlSyntax.GetQuotedColumnName(ColumnName),
|
||||
SqlSyntax.GetQuotedName(ConstraintName))
|
||||
: string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,9 +19,14 @@ namespace Umbraco.Core.Migrations.Expressions.Delete
|
||||
IExecutableBuilder Table(string tableName);
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the table to delete keys and indexes for.
|
||||
/// Builds a Delete Keys and Indexes expression, and executes.
|
||||
/// </summary>
|
||||
IExecutableBuilder KeysAndIndexes(string tableName = null);
|
||||
IExecutableBuilder KeysAndIndexes<TDto>(bool local = true, bool foreign = true);
|
||||
|
||||
/// <summary>
|
||||
/// Builds a Delete Keys and Indexes expression, and executes.
|
||||
/// </summary>
|
||||
IExecutableBuilder KeysAndIndexes(string tableName, bool local = true, bool foreign = true);
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the column to delete.
|
||||
|
||||
+56
-24
@@ -1,5 +1,7 @@
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NPoco;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Migrations.Expressions.Common;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
@@ -18,36 +20,66 @@ namespace Umbraco.Core.Migrations.Expressions.Delete.KeysAndIndexes
|
||||
|
||||
public string TableName { get; set; }
|
||||
|
||||
public bool DeleteLocal { get; set; }
|
||||
|
||||
public bool DeleteForeign { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Do()
|
||||
{
|
||||
if (TableName == null)
|
||||
{
|
||||
// drop keys
|
||||
var keys = _context.SqlContext.SqlSyntax.GetConstraintsPerTable(_context.Database).DistinctBy(x => x.Item2).ToArray();
|
||||
foreach (var key in keys.Where(x => x.Item2.StartsWith("FK_")))
|
||||
Delete.ForeignKey(key.Item2).OnTable(key.Item1).Do();
|
||||
foreach (var key in keys.Where(x => x.Item2.StartsWith("PK_")))
|
||||
Delete.PrimaryKey(key.Item2).FromTable(key.Item1).Do();
|
||||
_context.BuildingExpression = false;
|
||||
|
||||
// drop indexes
|
||||
var indexes = _context.SqlContext.SqlSyntax.GetDefinedIndexesDefinitions(_context.Database).DistinctBy(x => x.IndexName).ToArray();
|
||||
foreach (var index in indexes)
|
||||
Delete.Index(index.IndexName).OnTable(index.TableName).Do();
|
||||
//get a list of all constraints - this will include all PK, FK and unique constraints
|
||||
var tableConstraints = _context.SqlContext.SqlSyntax.GetConstraintsPerTable(_context.Database).DistinctBy(x => x.Item2).ToList();
|
||||
|
||||
//get a list of defined indexes - this will include all indexes, unique indexes and unique constraint indexes
|
||||
var indexes = _context.SqlContext.SqlSyntax.GetDefinedIndexesDefinitions(_context.Database).DistinctBy(x => x.IndexName).ToList();
|
||||
|
||||
var uniqueConstraintNames = tableConstraints.Where(x => !x.Item2.InvariantStartsWith("PK_") && !x.Item2.InvariantStartsWith("FK_")).Select(x => x.Item2);
|
||||
var indexNames = indexes.Select(x => x.IndexName).ToList();
|
||||
|
||||
// drop keys
|
||||
if (DeleteLocal || DeleteForeign)
|
||||
{
|
||||
// table, constraint
|
||||
|
||||
if (DeleteForeign)
|
||||
{
|
||||
//In some cases not all FK's are prefixed with "FK" :/ mostly with old upgraded databases so we need to check if it's either:
|
||||
// * starts with FK OR
|
||||
// * doesn't start with PK_ and doesn't exist in the list of indexes
|
||||
|
||||
foreach (var key in tableConstraints.Where(x => x.Item1 == TableName
|
||||
&& (x.Item2.InvariantStartsWith("FK_") || (!x.Item2.InvariantStartsWith("PK_") && !indexNames.InvariantContains(x.Item2)))))
|
||||
{
|
||||
Delete.ForeignKey(key.Item2).OnTable(key.Item1).Do();
|
||||
}
|
||||
|
||||
}
|
||||
if (DeleteLocal)
|
||||
{
|
||||
foreach (var key in tableConstraints.Where(x => x.Item1 == TableName && x.Item2.InvariantStartsWith("PK_")))
|
||||
Delete.PrimaryKey(key.Item2).FromTable(key.Item1).Do();
|
||||
|
||||
// note: we do *not* delete the DEFAULT constraints and if we wanted to we'd have to deal with that in interesting ways
|
||||
// since SQL server has a specific way to handle that, see SqlServerSyntaxProvider.GetDefaultConstraintsPerColumn
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// drop keys
|
||||
var keys = _context.SqlContext.SqlSyntax.GetConstraintsPerTable(_context.Database).DistinctBy(x => x.Item2).ToArray();
|
||||
foreach (var key in keys.Where(x => x.Item1 == TableName && x.Item2.StartsWith("FK_")))
|
||||
Delete.ForeignKey(key.Item2).OnTable(key.Item1).Do();
|
||||
foreach (var key in keys.Where(x => x.Item1 == TableName && x.Item2.StartsWith("PK_")))
|
||||
Delete.PrimaryKey(key.Item2).FromTable(key.Item1).Do();
|
||||
|
||||
// drop indexes
|
||||
var indexes = _context.SqlContext.SqlSyntax.GetDefinedIndexesDefinitions(_context.Database).DistinctBy(x => x.IndexName).ToArray();
|
||||
// drop indexes
|
||||
if (DeleteLocal)
|
||||
{
|
||||
foreach (var index in indexes.Where(x => x.TableName == TableName))
|
||||
Delete.Index(index.IndexName).OnTable(index.TableName).Do();
|
||||
{
|
||||
//if this is a unique constraint we need to drop the constraint, else drop the index
|
||||
//to figure this out, the index must be tagged as unique and it must exist in the tableConstraints
|
||||
|
||||
if (index.IsUnique && uniqueConstraintNames.InvariantContains(index.IndexName))
|
||||
Delete.UniqueConstraint(index.IndexName).FromTable(index.TableName).Do();
|
||||
else
|
||||
Delete.Index(index.IndexName).OnTable(index.TableName).Do();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Umbraco.Core.Migrations
|
||||
bool BuildingExpression { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Adds a post-migrations.
|
||||
/// Adds a post-migration.
|
||||
/// </summary>
|
||||
void AddPostMigration<TMigration>()
|
||||
where TMigration : IMigration;
|
||||
|
||||
@@ -389,7 +389,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
|
||||
private DatabaseSchemaResult ValidateSchema(IScope scope)
|
||||
{
|
||||
if (_databaseFactory.Configured == false)
|
||||
if (_databaseFactory.Initialized == false)
|
||||
return new DatabaseSchemaResult(_databaseFactory.SqlContext.SqlSyntax);
|
||||
|
||||
if (_databaseSchemaValidationResult != null)
|
||||
@@ -513,7 +513,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
|
||||
private Attempt<Result> CheckReadyForInstall()
|
||||
{
|
||||
if (_databaseFactory.Configured == false)
|
||||
if (_databaseFactory.CanConnect == false)
|
||||
{
|
||||
return Attempt.Fail(new Result
|
||||
{
|
||||
@@ -539,7 +539,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
{
|
||||
Message =
|
||||
"The database configuration failed with the following message: " + ex.Message +
|
||||
"\n Please check log file for additional information (can be found in '/App_Data/Logs/UmbracoTraceLog.txt')",
|
||||
"\n Please check log file for additional information (can be found in '/App_Data/Logs/')",
|
||||
Success = false,
|
||||
Percentage = "90"
|
||||
};
|
||||
|
||||
@@ -101,33 +101,33 @@ namespace Umbraco.Core.Migrations.Install
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -1, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1", SortOrder = 0, UniqueId = new Guid("916724a5-173d-4619-b97e-b9de133dd6f5"), Text = "SYSTEM DATA: umbraco master root", NodeObjectType = Constants.ObjectTypes.SystemRoot, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -20, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,-20", SortOrder = 0, UniqueId = new Guid("0F582A79-1E41-4CF0-BFA0-76340651891A"), Text = "Recycle Bin", NodeObjectType = Constants.ObjectTypes.ContentRecycleBin, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -21, Trashed = false, ParentId = -1, UserId = -1, Level = 0, Path = "-1,-21", SortOrder = 0, UniqueId = new Guid("BF7C7CBC-952F-4518-97A2-69E9C7B33842"), Text = "Recycle Bin", NodeObjectType = Constants.ObjectTypes.MediaRecycleBin, CreateDate = DateTime.Now });
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelString, 35, "f0bc4bfb-b499-40d6-ba86-058885a5178c", "Label");
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelInt, 36, "8e7f995c-bd81-4627-9932-c40e568ec788", "Label (integer)");
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelBigint, 36, "930861bf-e262-4ead-a704-f99453565708", "Label (bigint)");
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelDateTime, 37, "0e9794eb-f9b5-4f20-a788-93acd233a7e4", "Label (datetime)");
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelTime, 38, "a97cec69-9b71-4c30-8b12-ec398860d7e8", "Label (time)");
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelDecimal, 39, "8f1ef1e1-9de4-40d3-a072-6673f631ca64", "Label (decimal)");
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -90, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-90", SortOrder = 34, UniqueId = new Guid("84c6b441-31df-4ffe-b67e-67d5bc3ae65a"), Text = "Upload", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -89, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-89", SortOrder = 33, UniqueId = new Guid("c6bac0dd-4ab9-45b1-8e30-e4b619ee5da3"), Text = "Textarea", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -88, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-88", SortOrder = 32, UniqueId = new Guid("0cc0eba1-9960-42c9-bf9b-60e150b429ae"), Text = "Textstring", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -87, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-87", SortOrder = 4, UniqueId = new Guid("ca90c950-0aff-4e72-b976-a30b1ac57dad"), Text = "Richtext editor", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -51, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-51", SortOrder = 2, UniqueId = new Guid("2e6d3631-066e-44b8-aec4-96f09099b2b5"), Text = "Numeric", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -49, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-49", SortOrder = 2, UniqueId = new Guid("92897bc6-a5f3-4ffe-ae27-f2e7e33dda49"), Text = "True/false", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -43, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-43", SortOrder = 2, UniqueId = new Guid("fbaf13a8-4036-41f2-93a3-974f678c312a"), Text = "Checkbox list", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DropDownSingle, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DropDownSingle}", SortOrder = 2, UniqueId = new Guid("0b6a45e7-44ba-430d-9da5-4e46060b9e03"), Text = "Dropdown", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -41, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-41", SortOrder = 2, UniqueId = new Guid("5046194e-4237-453c-a547-15db3a07c4e1"), Text = "Date Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -40, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-40", SortOrder = 2, UniqueId = new Guid("bb5f57c9-ce2b-4bb9-b697-4caca783a805"), Text = "Radiobox", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DropDownMultiple, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DropDownMultiple}", SortOrder = 2, UniqueId = new Guid("f38f0ac7-1d27-439c-9f3f-089cd8825a53"), Text = "Dropdown multiple", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -37, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-37", SortOrder = 2, UniqueId = new Guid("0225af17-b302-49cb-9176-b9f35cab9c17"), Text = "Approved Color", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -36, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-36", SortOrder = 2, UniqueId = new Guid("e4d66c0f-b935-4200-81f0-025f7256b89a"), Text = "Date Picker with time", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultContentListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultContentListView}", SortOrder = 2, UniqueId = new Guid("C0808DD3-8133-4E4B-8CE8-E2BEA84A96A4"), Text = Constants.Conventions.DataTypes.ListViewPrefix + "Content", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultMediaListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultMediaListView}", SortOrder = 2, UniqueId = new Guid("3A0156C4-3B8C-4803-BDC1-6871FAA83FFF"), Text = Constants.Conventions.DataTypes.ListViewPrefix + "Media", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultMembersListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultMembersListView}", SortOrder = 2, UniqueId = new Guid("AA2C52A0-CE87-4E65-A47C-7DF09358585D"), Text = Constants.Conventions.DataTypes.ListViewPrefix + "Members", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelString, 35, Constants.DataTypes.Guids.LabelString, "Label (string)");
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelInt, 36, Constants.DataTypes.Guids.LabelInt, "Label (integer)");
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelBigint, 36, Constants.DataTypes.Guids.LabelBigInt, "Label (bigint)");
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelDateTime, 37, Constants.DataTypes.Guids.LabelDateTime, "Label (datetime)");
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelTime, 38, Constants.DataTypes.Guids.LabelTime, "Label (time)");
|
||||
InsertDataTypeNodeDto(Constants.DataTypes.LabelDecimal, 39, Constants.DataTypes.Guids.LabelDecimal, "Label (decimal)");
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Upload, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Upload}", SortOrder = 34, UniqueId = Constants.DataTypes.Guids.UploadGuid, Text = "Upload", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Textarea, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Textarea}", SortOrder = 33, UniqueId = Constants.DataTypes.Guids.TextareaGuid, Text = "Textarea", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Textbox, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Textbox}", SortOrder = 32, UniqueId = Constants.DataTypes.Guids.TextstringGuid, Text = "Textstring", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.RichtextEditor, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.RichtextEditor}", SortOrder = 4, UniqueId = Constants.DataTypes.Guids.RichtextEditorGuid, Text = "Richtext editor", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -51, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-51", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.NumericGuid, Text = "Numeric", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Boolean, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Boolean}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.CheckboxGuid, Text = "True/false", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -43, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-43", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.CheckboxListGuid, Text = "Checkbox list", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DropDownSingle, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DropDownSingle}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.DropdownGuid, Text = "Dropdown", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -41, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-41", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.DatePickerGuid, Text = "Date Picker", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -40, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-40", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.RadioboxGuid, Text = "Radiobox", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DropDownMultiple, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DropDownMultiple}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.DropdownMultipleGuid, Text = "Dropdown multiple", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = -37, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,-37", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.ApprovedColorGuid, Text = "Approved Color", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DateTime, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DateTime}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.DatePickerWithTimeGuid, Text = "Date Picker with time", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultContentListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultContentListView}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.ListViewContentGuid, Text = Constants.Conventions.DataTypes.ListViewPrefix + "Content", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultMediaListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultMediaListView}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.ListViewMediaGuid, Text = Constants.Conventions.DataTypes.ListViewPrefix + "Media", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.DefaultMembersListView, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.DefaultMembersListView}", SortOrder = 2, UniqueId = Constants.DataTypes.Guids.ListViewMembersGuid, Text = Constants.Conventions.DataTypes.ListViewPrefix + "Members", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1031, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1031", SortOrder = 2, UniqueId = new Guid("f38bd2d7-65d0-48e6-95dc-87ce06ec2d3d"), Text = Constants.Conventions.MediaTypes.Folder, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1032, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1032", SortOrder = 2, UniqueId = new Guid("cc07b313-0843-4aa8-bbda-871c8da728c8"), Text = Constants.Conventions.MediaTypes.Image, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1033, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1033", SortOrder = 2, UniqueId = new Guid("4c52d8ab-54e6-40cd-999c-7a5f24903e4d"), Text = Constants.Conventions.MediaTypes.File, NodeObjectType = Constants.ObjectTypes.MediaType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1041, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1041", SortOrder = 2, UniqueId = new Guid("b6b73142-b9c1-4bf8-a16d-e1c23320b549"), Text = "Tags", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1043, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1043", SortOrder = 2, UniqueId = new Guid("1df9f033-e6d4-451f-b8d2-e0cbc50a836f"), Text = "Image Cropper", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.Tags, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.Tags}", SortOrder = 2, UniqueId = new Guid("b6b73142-b9c1-4bf8-a16d-e1c23320b549"), Text = "Tags", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = Constants.DataTypes.ImageCropper, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = $"-1,{Constants.DataTypes.ImageCropper}", SortOrder = 2, UniqueId = new Guid("1df9f033-e6d4-451f-b8d2-e0cbc50a836f"), Text = "Image Cropper", NodeObjectType = Constants.ObjectTypes.DataType, CreateDate = DateTime.Now });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.Node, "id", false, new NodeDto { NodeId = 1044, Trashed = false, ParentId = -1, UserId = -1, Level = 1, Path = "-1,1044", SortOrder = 0, UniqueId = new Guid("d59be02f-1df9-4228-aa1e-01917d806cda"), Text = Constants.Conventions.MemberTypes.DefaultAlias, NodeObjectType = Constants.ObjectTypes.MemberType, CreateDate = DateTime.Now });
|
||||
|
||||
//New UDI pickers with newer Ids
|
||||
@@ -155,10 +155,10 @@ namespace Umbraco.Core.Migrations.Install
|
||||
|
||||
private void CreateContentTypeData()
|
||||
{
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 532, NodeId = 1031, Alias = Constants.Conventions.MediaTypes.Folder, Icon = "icon-folder", Thumbnail = "icon-folder", IsContainer = false, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 533, NodeId = 1032, Alias = Constants.Conventions.MediaTypes.Image, Icon = "icon-picture", Thumbnail = "icon-picture", AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = "icon-document", Thumbnail = "icon-document", AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 531, NodeId = 1044, Alias = Constants.Conventions.MemberTypes.DefaultAlias, Icon = "icon-user", Thumbnail = "icon-user", Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 532, NodeId = 1031, Alias = Constants.Conventions.MediaTypes.Folder, Icon = Constants.Icons.MediaFolder, Thumbnail = Constants.Icons.MediaFolder, IsContainer = false, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 533, NodeId = 1032, Alias = Constants.Conventions.MediaTypes.Image, Icon = Constants.Icons.MediaImage, Thumbnail = Constants.Icons.MediaImage, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 534, NodeId = 1033, Alias = Constants.Conventions.MediaTypes.File, Icon = Constants.Icons.MediaFile, Thumbnail = Constants.Icons.MediaFile, AllowAtRoot = true, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.ContentType, "pk", false, new ContentTypeDto { PrimaryKey = 531, NodeId = 1044, Alias = Constants.Conventions.MemberTypes.DefaultAlias, Icon = Constants.Icons.Member, Thumbnail = Constants.Icons.Member, Variations = (byte) ContentVariation.Nothing });
|
||||
}
|
||||
|
||||
private void CreateUserData()
|
||||
@@ -210,19 +210,19 @@ namespace Umbraco.Core.Migrations.Install
|
||||
|
||||
private void CreatePropertyTypeData()
|
||||
{
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 6, UniqueId = 6.ToGuid(), DataTypeId = 1043, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.File, Name = "Upload image", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 6, UniqueId = 6.ToGuid(), DataTypeId = Constants.DataTypes.ImageCropper, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.File, Name = "Upload image", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 7, UniqueId = 7.ToGuid(), DataTypeId = Constants.DataTypes.LabelInt, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Width, Name = "Width", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in pixels", Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 8, UniqueId = 8.ToGuid(), DataTypeId = Constants.DataTypes.LabelInt, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Height, Name = "Height", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in pixels", Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 9, UniqueId = 9.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 10, UniqueId = 10.ToGuid(), DataTypeId = -92, ContentTypeId = 1032, PropertyTypeGroupId = 3, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 24, UniqueId = 24.ToGuid(), DataTypeId = -90, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.File, Name = "Upload file", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 24, UniqueId = 24.ToGuid(), DataTypeId = Constants.DataTypes.Upload, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.File, Name = "Upload file", SortOrder = 0, Mandatory = true, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 25, UniqueId = 25.ToGuid(), DataTypeId = -92, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.Extension, Name = "Type", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 26, UniqueId = 26.ToGuid(), DataTypeId = Constants.DataTypes.LabelBigint, ContentTypeId = 1033, PropertyTypeGroupId = 4, Alias = Constants.Conventions.Media.Bytes, Name = "Size", SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = "in bytes", Variations = (byte) ContentVariation.Nothing });
|
||||
//membership property types
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 28, UniqueId = 28.ToGuid(), DataTypeId = -89, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.Comments, Name = Constants.Conventions.Member.CommentsLabel, SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 28, UniqueId = 28.ToGuid(), DataTypeId = Constants.DataTypes.Textarea, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.Comments, Name = Constants.Conventions.Member.CommentsLabel, SortOrder = 0, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 29, UniqueId = 29.ToGuid(), DataTypeId = Constants.DataTypes.LabelInt, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.FailedPasswordAttempts, Name = Constants.Conventions.Member.FailedPasswordAttemptsLabel, SortOrder = 1, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 30, UniqueId = 30.ToGuid(), DataTypeId = -49, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.IsApproved, Name = Constants.Conventions.Member.IsApprovedLabel, SortOrder = 2, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 31, UniqueId = 31.ToGuid(), DataTypeId = -49, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.IsLockedOut, Name = Constants.Conventions.Member.IsLockedOutLabel, SortOrder = 3, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 30, UniqueId = 30.ToGuid(), DataTypeId = Constants.DataTypes.Boolean, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.IsApproved, Name = Constants.Conventions.Member.IsApprovedLabel, SortOrder = 2, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 31, UniqueId = 31.ToGuid(), DataTypeId = Constants.DataTypes.Boolean, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.IsLockedOut, Name = Constants.Conventions.Member.IsLockedOutLabel, SortOrder = 3, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 32, UniqueId = 32.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastLockoutDate, Name = Constants.Conventions.Member.LastLockoutDateLabel, SortOrder = 4, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 33, UniqueId = 33.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastLoginDate, Name = Constants.Conventions.Member.LastLoginDateLabel, SortOrder = 5, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 34, UniqueId = 34.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastPasswordChangeDate, Name = Constants.Conventions.Member.LastPasswordChangeDateLabel, SortOrder = 6, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
@@ -266,30 +266,30 @@ namespace Umbraco.Core.Migrations.Install
|
||||
const string layouts = "[" + cardLayout + "," + listLayout + "]";
|
||||
|
||||
// TODO: Check which of the DataTypeIds below doesn't exist in umbracoNode, which results in a foreign key constraint errors.
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -49, EditorAlias = Constants.PropertyEditors.Aliases.Boolean, DbType = "Integer" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.Boolean, EditorAlias = Constants.PropertyEditors.Aliases.Boolean, DbType = "Integer" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -51, EditorAlias = Constants.PropertyEditors.Aliases.Integer, DbType = "Integer" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -87, EditorAlias = Constants.PropertyEditors.Aliases.TinyMce, DbType = "Ntext",
|
||||
Configuration = "{\"value\":\",code,undo,redo,cut,copy,mcepasteword,stylepicker,bold,italic,bullist,numlist,outdent,indent,mcelink,unlink,mceinsertanchor,mceimage,umbracomacro,mceinserttable,umbracoembed,mcecharmap,|1|1,2,3,|0|500,400|1049,|true|\"}" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -88, EditorAlias = Constants.PropertyEditors.Aliases.TextBox, DbType = "Nvarchar" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -89, EditorAlias = Constants.PropertyEditors.Aliases.TextArea, DbType = "Ntext" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -90, EditorAlias = Constants.PropertyEditors.Aliases.UploadField, DbType = "Nvarchar" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.Textbox, EditorAlias = Constants.PropertyEditors.Aliases.TextBox, DbType = "Nvarchar" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.Textarea, EditorAlias = Constants.PropertyEditors.Aliases.TextArea, DbType = "Ntext" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.Upload, EditorAlias = Constants.PropertyEditors.Aliases.UploadField, DbType = "Nvarchar" });
|
||||
InsertDataTypeDto(Constants.DataTypes.LabelString, Constants.PropertyEditors.Aliases.Label, "Nvarchar", "{\"umbracoDataValueType\":\"STRING\"}");
|
||||
InsertDataTypeDto(Constants.DataTypes.LabelInt, Constants.PropertyEditors.Aliases.Label, "Integer", "{\"umbracoDataValueType\":\"INT\"}");
|
||||
InsertDataTypeDto(Constants.DataTypes.LabelBigint, Constants.PropertyEditors.Aliases.Label, "Nvarchar", "{\"umbracoDataValueType\":\"BIGINT\"}");
|
||||
InsertDataTypeDto(Constants.DataTypes.LabelDateTime, Constants.PropertyEditors.Aliases.Label, "Date", "{\"umbracoDataValueType\":\"DATETIME\"}");
|
||||
InsertDataTypeDto(Constants.DataTypes.LabelDecimal, Constants.PropertyEditors.Aliases.Label, "Decimal", "{\"umbracoDataValueType\":\"DECIMAL\"}");
|
||||
InsertDataTypeDto(Constants.DataTypes.LabelTime, Constants.PropertyEditors.Aliases.Label, "Date", "{\"umbracoDataValueType\":\"TIME\"}");
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -36, EditorAlias = Constants.PropertyEditors.Aliases.DateTime, DbType = "Date" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.DateTime, EditorAlias = Constants.PropertyEditors.Aliases.DateTime, DbType = "Date" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -37, EditorAlias = Constants.PropertyEditors.Aliases.ColorPicker, DbType = "Nvarchar" });
|
||||
InsertDataTypeDto(Constants.DataTypes.DropDownSingle, Constants.PropertyEditors.Aliases.DropDownListFlexible, "Nvarchar", "{\"multiple\":false}");
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -40, EditorAlias = Constants.PropertyEditors.Aliases.RadioButtonList, DbType = "Nvarchar" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -41, EditorAlias = "Umbraco.DateTime", DbType = "Date", Configuration = "{\"format\":\"YYYY-MM-DD\"}" });
|
||||
InsertDataTypeDto(Constants.DataTypes.DropDownMultiple, Constants.PropertyEditors.Aliases.DropDownListFlexible, "Nvarchar", "{\"multiple\":true}");
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = -43, EditorAlias = Constants.PropertyEditors.Aliases.CheckBoxList, DbType = "Nvarchar" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1041, EditorAlias = Constants.PropertyEditors.Aliases.Tags, DbType = "Ntext",
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.Tags, EditorAlias = Constants.PropertyEditors.Aliases.Tags, DbType = "Ntext",
|
||||
Configuration = "{\"group\":\"default\", \"storageType\":\"Json\"}"
|
||||
});
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = 1043, EditorAlias = Constants.PropertyEditors.Aliases.ImageCropper, DbType = "Ntext" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.ImageCropper, EditorAlias = Constants.PropertyEditors.Aliases.ImageCropper, DbType = "Ntext" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.DefaultContentListView, EditorAlias = Constants.PropertyEditors.Aliases.ListView, DbType = "Nvarchar",
|
||||
Configuration = "{\"pageSize\":100, \"orderBy\":\"updateDate\", \"orderDirection\":\"desc\", \"layouts\":" + layouts + ", \"includeProperties\":[{\"alias\":\"updateDate\",\"header\":\"Last edited\",\"isSystem\":1},{\"alias\":\"owner\",\"header\":\"Updated by\",\"isSystem\":1}]}" });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.DataType, "pk", false, new DataTypeDto { NodeId = Constants.DataTypes.DefaultMediaListView, EditorAlias = Constants.PropertyEditors.Aliases.ListView, DbType = "Nvarchar",
|
||||
|
||||
@@ -41,6 +41,7 @@ namespace Umbraco.Core.Migrations
|
||||
public void AddPostMigration<TMigration>()
|
||||
where TMigration : IMigration
|
||||
{
|
||||
// just adding - will be de-duplicated when executing
|
||||
PostMigrations.Add(typeof(TMigration));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,7 @@ namespace Umbraco.Core.Migrations
|
||||
if (_executed)
|
||||
throw new InvalidOperationException("This expression has already been executed.");
|
||||
_executed = true;
|
||||
Context.BuildingExpression = false;
|
||||
|
||||
if (sql == null)
|
||||
{
|
||||
|
||||
@@ -240,7 +240,8 @@ namespace Umbraco.Core.Migrations
|
||||
if (finalState == null)
|
||||
finalState = kvp.Key;
|
||||
else
|
||||
throw new Exception("Multiple final states have been detected.");
|
||||
throw new InvalidOperationException($"Multiple final states have been detected in the plan (\"{finalState}\", \"{kvp.Key}\")."
|
||||
+ " Make sure the plan contains only one final state.");
|
||||
}
|
||||
|
||||
// now check for loops
|
||||
@@ -254,7 +255,8 @@ namespace Umbraco.Core.Migrations
|
||||
while (nextTransition != null && !verified.Contains(nextTransition.SourceState))
|
||||
{
|
||||
if (visited.Contains(nextTransition.SourceState))
|
||||
throw new Exception("A loop has been detected.");
|
||||
throw new InvalidOperationException($"A loop has been detected in the plan around state \"{nextTransition.SourceState}\"."
|
||||
+ " Make sure the plan does not contain circular transition paths.");
|
||||
visited.Add(nextTransition.SourceState);
|
||||
nextTransition = _transitions[nextTransition.TargetState];
|
||||
}
|
||||
@@ -264,6 +266,14 @@ namespace Umbraco.Core.Migrations
|
||||
_finalState = finalState;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws an exception when the initial state is unknown.
|
||||
/// </summary>
|
||||
protected virtual void ThrowOnUnknownInitialState(string state)
|
||||
{
|
||||
throw new InvalidOperationException($"The migration plan does not support migrating from state \"{state}\".");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Executes the plan.
|
||||
/// </summary>
|
||||
@@ -287,13 +297,15 @@ namespace Umbraco.Core.Migrations
|
||||
logger.Info<MigrationPlan>("At {OrigState}", string.IsNullOrWhiteSpace(origState) ? "origin": origState);
|
||||
|
||||
if (!_transitions.TryGetValue(origState, out var transition))
|
||||
throw new Exception($"Unknown state \"{origState}\".");
|
||||
ThrowOnUnknownInitialState(origState);
|
||||
|
||||
var context = new MigrationContext(scope.Database, logger);
|
||||
context.PostMigrations.AddRange(_postMigrationTypes);
|
||||
|
||||
while (transition != null)
|
||||
{
|
||||
logger.Info<MigrationPlan>("Execute {MigrationType}", transition.MigrationType.Name);
|
||||
|
||||
var migration = migrationBuilder.Build(transition.MigrationType, context);
|
||||
migration.Migrate();
|
||||
|
||||
@@ -302,6 +314,8 @@ namespace Umbraco.Core.Migrations
|
||||
|
||||
logger.Info<MigrationPlan>("At {OrigState}", origState);
|
||||
|
||||
// throw a raw exception here: this should never happen as the plan has
|
||||
// been validated - this is just a paranoid safety test
|
||||
if (!_transitions.TryGetValue(origState, out transition))
|
||||
throw new Exception($"Unknown state \"{origState}\".");
|
||||
}
|
||||
@@ -322,7 +336,8 @@ namespace Umbraco.Core.Migrations
|
||||
|
||||
logger.Info<MigrationPlan>("Done (pending scope completion).");
|
||||
|
||||
// safety check
|
||||
// safety check - again, this should never happen as the plan has been validated,
|
||||
// and this is just a paranoid safety test
|
||||
if (origState != _finalState)
|
||||
throw new Exception($"Internal error, reached state {origState} which is not final state {_finalState}");
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
using Umbraco.Core.Migrations.Install;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.Common
|
||||
{
|
||||
public class CreateKeysAndIndexes : MigrationBase
|
||||
{
|
||||
public CreateKeysAndIndexes(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
// remove those that may already have keys
|
||||
Delete.KeysAndIndexes(Constants.DatabaseSchema.Tables.KeyValue).Do();
|
||||
|
||||
// re-create *all* keys and indexes
|
||||
foreach (var x in DatabaseSchemaCreator.OrderedTables)
|
||||
Create.KeysAndIndexes(x).Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
namespace Umbraco.Core.Migrations.Upgrade.Common
|
||||
{
|
||||
public class DeleteKeysAndIndexes : MigrationBase
|
||||
{
|
||||
public DeleteKeysAndIndexes(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
// all v7.14 tables
|
||||
var tables = new[]
|
||||
{
|
||||
"cmsContent",
|
||||
"cmsContentType",
|
||||
"cmsContentType2ContentType",
|
||||
"cmsContentTypeAllowedContentType",
|
||||
"cmsContentVersion",
|
||||
"cmsContentXml",
|
||||
"cmsDataType",
|
||||
"cmsDataTypePreValues",
|
||||
"cmsDictionary",
|
||||
"cmsDocument",
|
||||
"cmsDocumentType",
|
||||
"cmsLanguageText",
|
||||
"cmsMacro",
|
||||
"cmsMacroProperty",
|
||||
"cmsMedia",
|
||||
"cmsMember",
|
||||
"cmsMember2MemberGroup",
|
||||
"cmsMemberType",
|
||||
"cmsPreviewXml",
|
||||
"cmsPropertyData",
|
||||
"cmsPropertyType",
|
||||
"cmsPropertyTypeGroup",
|
||||
"cmsTagRelationship",
|
||||
"cmsTags",
|
||||
"cmsTask",
|
||||
"cmsTaskType",
|
||||
"cmsTemplate",
|
||||
"umbracoAccess",
|
||||
"umbracoAccessRule",
|
||||
"umbracoAudit",
|
||||
"umbracoCacheInstruction",
|
||||
"umbracoConsent",
|
||||
"umbracoDomains",
|
||||
"umbracoExternalLogin",
|
||||
"umbracoLanguage",
|
||||
"umbracoLock",
|
||||
"umbracoLog",
|
||||
"umbracoMigration",
|
||||
"umbracoNode",
|
||||
"umbracoRedirectUrl",
|
||||
"umbracoRelation",
|
||||
"umbracoRelationType",
|
||||
"umbracoServer",
|
||||
"umbracoUser",
|
||||
"umbracoUser2NodeNotify",
|
||||
"umbracoUser2UserGroup",
|
||||
"umbracoUserGroup",
|
||||
"umbracoUserGroup2App",
|
||||
"umbracoUserGroup2NodePermission",
|
||||
"umbracoUserLogin",
|
||||
"umbracoUserStartNode",
|
||||
};
|
||||
|
||||
// delete *all* keys and indexes - because of FKs
|
||||
// on known v7 tables only
|
||||
foreach (var table in tables)
|
||||
Delete.KeysAndIndexes(table, false, true).Do();
|
||||
foreach (var table in tables)
|
||||
Delete.KeysAndIndexes(table, true, false).Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,8 +2,7 @@
|
||||
using System.Configuration;
|
||||
using Semver;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_7_12_0;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_7_14_0;
|
||||
using Umbraco.Core.Migrations.Upgrade.Common;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_8_0_0;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_8_0_1;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_8_1_0;
|
||||
@@ -15,6 +14,9 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
/// </summary>
|
||||
public class UmbracoPlan : MigrationPlan
|
||||
{
|
||||
private const string InitPrefix = "{init-";
|
||||
private const string InitSuffix = "}";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoPlan"/> class.
|
||||
/// </summary>
|
||||
@@ -24,6 +26,27 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
DefinePlan();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the initial state corresponding to a version.
|
||||
/// </summary>
|
||||
private static string GetInitState(SemVersion version)
|
||||
=> InitPrefix + version + InitSuffix;
|
||||
|
||||
/// <summary>
|
||||
/// Tries to extract a version from an initial state.
|
||||
/// </summary>
|
||||
private static bool TryGetInitStateVersion(string state, out string version)
|
||||
{
|
||||
if (state.StartsWith(InitPrefix) && state.EndsWith(InitSuffix))
|
||||
{
|
||||
version = state.TrimStart(InitPrefix).TrimEnd(InitSuffix);
|
||||
return true;
|
||||
}
|
||||
|
||||
version = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <remarks>
|
||||
/// <para>The default initial state in plans is string.Empty.</para>
|
||||
@@ -41,23 +64,37 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
if (!SemVersion.TryParse(ConfigurationManager.AppSettings[Constants.AppSettings.ConfigurationStatus], out var currentVersion))
|
||||
throw new InvalidOperationException($"Could not get current version from web.config {Constants.AppSettings.ConfigurationStatus} appSetting.");
|
||||
|
||||
// we currently support upgrading from 7.10.0 and later
|
||||
if (currentVersion < new SemVersion(7, 10))
|
||||
throw new InvalidOperationException($"Version {currentVersion} cannot be migrated to {UmbracoVersion.SemanticVersion}.");
|
||||
|
||||
// cannot go back in time
|
||||
if (currentVersion > UmbracoVersion.SemanticVersion)
|
||||
throw new InvalidOperationException($"Version {currentVersion} cannot be downgraded to {UmbracoVersion.SemanticVersion}.");
|
||||
|
||||
// upgrading from version 7 => initial state is eg "{init-7.10.0}"
|
||||
// anything else is not supported - ie if 8 and above, we should have an initial state already
|
||||
if (currentVersion.Major != 7)
|
||||
throw new InvalidOperationException($"Version {currentVersion} is not supported by the migration plan.");
|
||||
// only from 7.14.0 and above
|
||||
var minVersion = new SemVersion(7, 14);
|
||||
if (currentVersion < minVersion)
|
||||
throw new InvalidOperationException($"Version {currentVersion} cannot be migrated to {UmbracoVersion.SemanticVersion}."
|
||||
+ $" Please upgrade first to at least {minVersion}.");
|
||||
|
||||
return "{init-" + currentVersion + "}";
|
||||
// Force versions between 7.14.*-7.15.* into into 7.14 initial state. Because there is no db-changes,
|
||||
// and we don't want users to workaround my putting in version 7.14.0 them self.
|
||||
if (minVersion <= currentVersion && currentVersion < new SemVersion(7, 16))
|
||||
return GetInitState(minVersion);
|
||||
|
||||
// initial state is eg "{init-7.14.0}"
|
||||
return GetInitState(currentVersion);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ThrowOnUnknownInitialState(string state)
|
||||
{
|
||||
if (TryGetInitStateVersion(state, out var initVersion))
|
||||
{
|
||||
throw new InvalidOperationException($"Version {UmbracoVersion.SemanticVersion} does not support migrating from {initVersion}."
|
||||
+ $" Please verify which versions support migrating from {initVersion}.");
|
||||
}
|
||||
|
||||
base.ThrowOnUnknownInitialState(state);
|
||||
}
|
||||
|
||||
// define the plan
|
||||
protected void DefinePlan()
|
||||
{
|
||||
@@ -70,21 +107,23 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
//
|
||||
// If the new migration causes a merge conflict, because someone else also added another
|
||||
// new migration, you NEED to fix the conflict by providing one default path, and paths
|
||||
// out of the conflict states (see example below).
|
||||
// out of the conflict states (see examples below).
|
||||
//
|
||||
// * Porting from version 7:
|
||||
// Append the ported migration to the main chain, using a new guid (same as above).
|
||||
// Create a new special chain from the {init-...} state to the main chain (see example
|
||||
// below).
|
||||
// Create a new special chain from the {init-...} state to the main chain.
|
||||
|
||||
|
||||
// plan starts at 7.10.0 (anything before 7.10.0 is not supported)
|
||||
// upgrades from 7 to 8, and then takes care of all eventual upgrades
|
||||
// plan starts at 7.14.0 (anything before 7.14.0 is not supported)
|
||||
//
|
||||
From("{init-7.10.0}");
|
||||
From(GetInitState(new SemVersion(7, 14, 0)));
|
||||
|
||||
// begin migrating from v7 - remove all keys and indexes
|
||||
To<DeleteKeysAndIndexes>("{B36B9ABD-374E-465B-9C5F-26AB0D39326F}");
|
||||
|
||||
To<AddLockObjects>("{7C447271-CA3F-4A6A-A913-5D77015655CB}");
|
||||
To<AddContentNuTable>("{CBFF58A2-7B50-4F75-8E98-249920DB0F37}");
|
||||
To<RefactorXmlColumns>("{3D18920C-E84D-405C-A06A-B7CEE52FE5DD}");
|
||||
To<RenameMediaVersionTable>("{5CB66059-45F4-48BA-BCBD-C5035D79206B}");
|
||||
To<VariantsMigration>("{FB0A5429-587E-4BD0-8A67-20F0E7E62FF7}");
|
||||
To<DropMigrationsTable>("{F0C42457-6A3B-4912-A7EA-F27ED85A2092}");
|
||||
To<DataTypeMigration>("{8640C9E4-A1C0-4C59-99BB-609B4E604981}");
|
||||
@@ -95,91 +134,55 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
ToWithReplace<AddVariationTables2, AddVariationTables1A>("{941B2ABA-2D06-4E04-81F5-74224F1DB037}", "{76DF5CD7-A884-41A5-8DC6-7860D95B1DF5}"); // kill AddVariationTable1
|
||||
To<RefactorMacroColumns>("{A7540C58-171D-462A-91C5-7A9AA5CB8BFD}");
|
||||
|
||||
Merge().To<UserForeignKeys>("{3E44F712-E2E3-473A-AE49-5D7F8E67CE3F}") // shannon added that one
|
||||
.With().To<AddTypedLabels>("{65D6B71C-BDD5-4A2E-8D35-8896325E9151}") // stephan added that one
|
||||
Merge()
|
||||
.To<UserForeignKeys>("{3E44F712-E2E3-473A-AE49-5D7F8E67CE3F}")
|
||||
.With()
|
||||
.To<AddTypedLabels>("{65D6B71C-BDD5-4A2E-8D35-8896325E9151}")
|
||||
.As("{4CACE351-C6B9-4F0C-A6BA-85A02BBD39E4}");
|
||||
|
||||
To<ContentVariationMigration>("{1350617A-4930-4D61-852F-E3AA9E692173}");
|
||||
To<UpdateUmbracoConsent>("{39E5B1F7-A50B-437E-B768-1723AEC45B65}"); // from 7.12.0
|
||||
|
||||
Merge()
|
||||
.To<AddRelationTypeForMediaFolderOnDelete>("{0541A62B-EF87-4CA2-8225-F0EB98ECCC9F}") // from 7.12.0
|
||||
.To<IncreaseLanguageIsoCodeColumnLength>("{EB34B5DC-BB87-4005-985E-D983EA496C38}") // from 7.12.0
|
||||
.To<RenameTrueFalseField>("{517CE9EA-36D7-472A-BF4B-A0D6FB1B8F89}") // from 7.12.0
|
||||
.To<SetDefaultTagsStorageType>("{BBD99901-1545-40E4-8A5A-D7A675C7D2F2}") // from 7.12.0
|
||||
.With()
|
||||
.To<FallbackLanguage>("{CF51B39B-9B9A-4740-BB7C-EAF606A7BFBF}") // andy added that one
|
||||
.As("{8B14CEBD-EE47-4AAD-A841-93551D917F11}");
|
||||
|
||||
ToWithReplace<UpdateDefaultMandatoryLanguage>("{2C87AA47-D1BC-4ECB-8A73-2D8D1046C27F}", "{5F4597F4-A4E0-4AFE-90B5-6D2F896830EB}"); // merge
|
||||
ToWithReplace<RefactorVariantsModel>("{B19BF0F2-E1C6-4AEB-A146-BC559D97A2C6}", "{290C18EE-B3DE-4769-84F1-1F467F3F76DA}"); // merge
|
||||
To<FallbackLanguage>("{CF51B39B-9B9A-4740-BB7C-EAF606A7BFBF}");
|
||||
To<UpdateDefaultMandatoryLanguage>("{5F4597F4-A4E0-4AFE-90B5-6D2F896830EB}");
|
||||
To<RefactorVariantsModel>("{290C18EE-B3DE-4769-84F1-1F467F3F76DA}");
|
||||
To<DropTaskTables>("{6A2C7C1B-A9DB-4EA9-B6AB-78E7D5B722A7}");
|
||||
To<FixLockTablePrimaryKey>("{77874C77-93E5-4488-A404-A630907CEEF0}");
|
||||
To<AddLogTableColumns>("{8804D8E8-FE62-4E3A-B8A2-C047C2118C38}");
|
||||
To<DropPreValueTable>("{23275462-446E-44C7-8C2C-3B8C1127B07D}");
|
||||
To<DropDownPropertyEditorsMigration>("{6B251841-3069-4AD5-8AE9-861F9523E8DA}");
|
||||
To<TagsMigrationFix>("{EE429F1B-9B26-43CA-89F8-A86017C809A3}");
|
||||
To<DropTemplateDesignColumn>("{08919C4B-B431-449C-90EC-2B8445B5C6B1}");
|
||||
To<TablesForScheduledPublishing>("{7EB0254C-CB8B-4C75-B15B-D48C55B449EB}");
|
||||
To<DropTaskTables>("{648A2D5F-7467-48F8-B309-E99CEEE00E2A}"); // fixed version
|
||||
To<MakeTagsVariant>("{C39BF2A7-1454-4047-BBFE-89E40F66ED63}");
|
||||
To<MakeRedirectUrlVariant>("{64EBCE53-E1F0-463A-B40B-E98EFCCA8AE2}");
|
||||
To<AddContentTypeIsElementColumn>("{0009109C-A0B8-4F3F-8FEB-C137BBDDA268}");
|
||||
To<UpdateMemberGroupPickerData>("{8A027815-D5CD-4872-8B88-9A51AB5986A6}"); // from 7.14.0
|
||||
To<ConvertRelatedLinksToMultiUrlPicker>("{ED28B66A-E248-4D94-8CDB-9BDF574023F0}");
|
||||
To<UpdatePickerIntegerValuesToUdi>("{38C809D5-6C34-426B-9BEA-EFD39162595C}");
|
||||
To<RenameUmbracoDomainsTable>("{6017F044-8E70-4E10-B2A3-336949692ADD}");
|
||||
To<AddUserLoginDtoDateIndex>("{98339BEF-E4B2-48A8-B9D1-D173DC842BBE}");
|
||||
|
||||
Merge()
|
||||
.To<DropXmlTables>("{CDBEDEE4-9496-4903-9CF2-4104E00FF960}")
|
||||
.With()
|
||||
.To<RadioAndCheckboxAndDropdownPropertyEditorsMigration>("{940FD19A-00A8-4D5C-B8FF-939143585726}")
|
||||
.To<RadioAndCheckboxPropertyEditorsMigration>("{940FD19A-00A8-4D5C-B8FF-939143585726}")
|
||||
.As("{0576E786-5C30-4000-B969-302B61E90CA3}");
|
||||
|
||||
To<FixLanguageIsoCodeLength>("{48AD6CCD-C7A4-4305-A8AB-38728AD23FC5}");
|
||||
|
||||
// finish migrating from v7 - recreate all keys and indexes
|
||||
To<CreateKeysAndIndexes>("{3F9764F5-73D0-4D45-8804-1240A66E43A2}");
|
||||
|
||||
To<RenameLabelAndRichTextPropertyEditorAliases>("{E0CBE54D-A84F-4A8F-9B13-900945FD7ED9}");
|
||||
To<MergeDateAndDateTimePropertyEditor>("{78BAF571-90D0-4D28-8175-EF96316DA789}");
|
||||
// release-8.0.0
|
||||
|
||||
// to 8.0.1...
|
||||
To<ChangeNuCacheJsonFormat>("{80C0A0CB-0DD5-4573-B000-C4B7C313C70D}");
|
||||
// release-8.0.1
|
||||
|
||||
// to 8.1.0...
|
||||
To<ConvertTinyMceAndGridMediaUrlsToLocalLink>("{B69B6E8C-A769-4044-A27E-4A4E18D1645A}");
|
||||
To<RenameUserLoginDtoDateIndex>("{0372A42B-DECF-498D-B4D1-6379E907EB94}");
|
||||
To<FixContentNuCascade>("{5B1E0D93-F5A3-449B-84BA-65366B84E2D4}");
|
||||
|
||||
//FINAL
|
||||
|
||||
|
||||
|
||||
|
||||
// and then, need to support upgrading from more recent 7.x
|
||||
//
|
||||
From("{init-7.10.1}").To("{init-7.10.0}"); // same as 7.10.0
|
||||
From("{init-7.10.2}").To("{init-7.10.0}"); // same as 7.10.0
|
||||
From("{init-7.10.3}").To("{init-7.10.0}"); // same as 7.10.0
|
||||
From("{init-7.10.4}").To("{init-7.10.0}"); // same as 7.10.0
|
||||
From("{init-7.10.5}").To("{init-7.10.0}"); // same as 7.10.0
|
||||
From("{init-7.11.0}").To("{init-7.10.0}"); // same as 7.10.0
|
||||
From("{init-7.11.1}").To("{init-7.10.0}"); // same as 7.10.0
|
||||
From("{init-7.11.2}").To("{init-7.10.0}"); // same as 7.10.0
|
||||
|
||||
// 7.12.0 has migrations, define a custom chain which copies the chain
|
||||
// going from {init-7.10.0} to former final (1350617A) , and then goes straight to
|
||||
// main chain, skipping the migrations
|
||||
//
|
||||
From("{init-7.12.0}");
|
||||
// clone start / clone stop / target
|
||||
ToWithClone("{init-7.10.0}", "{1350617A-4930-4D61-852F-E3AA9E692173}", "{BBD99901-1545-40E4-8A5A-D7A675C7D2F2}");
|
||||
|
||||
From("{init-7.12.1}").To("{init-7.10.0}"); // same as 7.12.0
|
||||
From("{init-7.12.2}").To("{init-7.10.0}"); // same as 7.12.0
|
||||
From("{init-7.12.3}").To("{init-7.10.0}"); // same as 7.12.0
|
||||
From("{init-7.12.4}").To("{init-7.10.0}"); // same as 7.12.0
|
||||
From("{init-7.13.0}").To("{init-7.10.0}"); // same as 7.12.0
|
||||
From("{init-7.13.1}").To("{init-7.10.0}"); // same as 7.12.0
|
||||
|
||||
// 7.14.0 has migrations, handle it...
|
||||
// clone going from 7.10 to 1350617A (the last one before we started to merge 7.12 migrations), then
|
||||
// clone going from CF51B39B (after 7.12 migrations) to 0009109C (the last one before we started to merge 7.12 migrations),
|
||||
// ending in 8A027815 (after 7.14 migrations)
|
||||
From("{init-7.14.0}")
|
||||
.ToWithClone("{init-7.10.0}", "{1350617A-4930-4D61-852F-E3AA9E692173}", "{9109B8AF-6B34-46EE-9484-7434196D0C79}")
|
||||
.ToWithClone("{CF51B39B-9B9A-4740-BB7C-EAF606A7BFBF}", "{0009109C-A0B8-4F3F-8FEB-C137BBDDA268}", "{8A027815-D5CD-4872-8B88-9A51AB5986A6}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.IO;
|
||||
using Umbraco.Core.IO;
|
||||
using File = System.IO.File;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_10_0
|
||||
{
|
||||
/// <summary>
|
||||
/// Renames the preview folder containing static HTML files to ensure it does not interfere with the MVC route
|
||||
/// that is now supposed to render these views dynamically. We don't want to delete as people may have made
|
||||
/// customizations to these files that would need to be migrated to the new .cshtml view files.
|
||||
/// </summary>
|
||||
public class RenamePreviewFolder : MigrationBase
|
||||
{
|
||||
public RenamePreviewFolder(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var previewFolderPath = IOHelper.MapPath(SystemDirectories.Umbraco + "/preview");
|
||||
if (Directory.Exists(previewFolderPath))
|
||||
{
|
||||
var newPath = previewFolderPath.Replace("preview", "preview.old");
|
||||
if (Directory.Exists(newPath) == false)
|
||||
{
|
||||
Directory.Move(previewFolderPath, newPath);
|
||||
var readmeText =
|
||||
$"Static HTML files used for preview and canvas editing functionality no longer live in this directory.\r\n" +
|
||||
$"Instead they have been recreated as MVC views and can now be found in '~/Umbraco/Views/Preview'.\r\n" +
|
||||
$"See issue: http://issues.umbraco.org/issue/U4-11090";
|
||||
File.WriteAllText(Path.Combine(newPath, "readme.txt"), readmeText);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_12_0
|
||||
{
|
||||
public class AddRelationTypeForMediaFolderOnDelete : MigrationBase
|
||||
{
|
||||
|
||||
public AddRelationTypeForMediaFolderOnDelete(IMigrationContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var relationTypeCount = Context.Database.ExecuteScalar<int>("SELECT COUNT(*) FROM umbracoRelationType WHERE alias=@alias",
|
||||
new { alias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias });
|
||||
|
||||
if (relationTypeCount > 0)
|
||||
return;
|
||||
|
||||
var uniqueId = (Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias + "____" + Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteName).ToGuid();
|
||||
Insert.IntoTable("umbracoRelationType").Row(new
|
||||
{
|
||||
typeUniqueId = uniqueId,
|
||||
alias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias,
|
||||
name = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteName,
|
||||
childObjectType = Constants.ObjectTypes.MediaType,
|
||||
parentObjectType = Constants.ObjectTypes.MediaType,
|
||||
dual = false
|
||||
}).Do();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_12_0
|
||||
{
|
||||
public class IncreaseLanguageIsoCodeColumnLength : MigrationBase
|
||||
{
|
||||
public IncreaseLanguageIsoCodeColumnLength(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
// Some people seem to have a constraint in their DB instead of an index, we'd need to drop that one
|
||||
// See: https://our.umbraco.com/forum/using-umbraco-and-getting-started/93282-upgrade-from-711-to-712-fails
|
||||
var constraints = SqlSyntax.GetConstraintsPerTable(Context.Database).Distinct().ToArray();
|
||||
if (constraints.Any(x => x.Item2.InvariantEquals("IX_umbracoLanguage_languageISOCode")))
|
||||
{
|
||||
Delete.UniqueConstraint("IX_umbracoLanguage_languageISOCode").FromTable("umbracoLanguage").Do();
|
||||
}
|
||||
|
||||
//Now check for indexes of that name and drop that if it exists
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(Context.Database);
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoLanguage_languageISOCode")))
|
||||
{
|
||||
Delete.Index("IX_umbracoLanguage_languageISOCode").OnTable("umbracoLanguage").Do();
|
||||
}
|
||||
|
||||
Alter.Table("umbracoLanguage")
|
||||
.AlterColumn("languageISOCode")
|
||||
.AsString(14)
|
||||
.Nullable()
|
||||
.Do();
|
||||
|
||||
Create.Index("IX_umbracoLanguage_languageISOCode")
|
||||
.OnTable("umbracoLanguage")
|
||||
.OnColumn("languageISOCode")
|
||||
.Ascending()
|
||||
.WithOptions()
|
||||
.Unique()
|
||||
.Do();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_12_0
|
||||
{
|
||||
public class RenameTrueFalseField : MigrationBase
|
||||
{
|
||||
public RenameTrueFalseField(IMigrationContext context) : base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
//rename the existing true/false field
|
||||
Update.Table(NodeDto.TableName).Set(new { text = "Checkbox" }).Where(new { id = Constants.DataTypes.Boolean }).Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_12_0
|
||||
{
|
||||
/// <summary>
|
||||
/// Set the default storageType for the tags datatype to "CSV" to ensure backwards compatibility since the default is going to be JSON in new versions.
|
||||
/// </summary>
|
||||
public class SetDefaultTagsStorageType : MigrationBase
|
||||
{
|
||||
public SetDefaultTagsStorageType(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
// dummy editor for deserialization
|
||||
private class TagConfigurationEditor : ConfigurationEditor<TagConfiguration>
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
// get all Umbraco.Tags datatypes
|
||||
var dataTypeDtos = Database.Fetch<DataTypeDto>(Context.SqlContext.Sql()
|
||||
.Select<DataTypeDto>()
|
||||
.From<DataTypeDto>()
|
||||
.Where<DataTypeDto>(x => x.EditorAlias == Constants.PropertyEditors.Aliases.Tags));
|
||||
|
||||
// get a dummy editor for deserialization
|
||||
var editor = new TagConfigurationEditor();
|
||||
|
||||
foreach (var dataTypeDto in dataTypeDtos)
|
||||
{
|
||||
// need to check storageType on raw dictionary, as TagConfiguration would have a default value
|
||||
var dictionary = JsonConvert.DeserializeObject<JObject>(dataTypeDto.Configuration);
|
||||
|
||||
// if missing, use TagConfiguration to properly update the configuration
|
||||
// due to ... reasons ... the key can start with a lower or upper 'S'
|
||||
if (!dictionary.ContainsKey("storageType") && !dictionary.ContainsKey("StorageType"))
|
||||
{
|
||||
var configuration = (TagConfiguration)editor.FromDatabase(dataTypeDto.Configuration);
|
||||
configuration.StorageType = TagsStorageType.Csv;
|
||||
dataTypeDto.Configuration = ConfigurationEditor.ToDatabase(configuration);
|
||||
Database.Update(dataTypeDto);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_12_0
|
||||
{
public class UpdateUmbracoConsent : MigrationBase
{
|
||||
public UpdateUmbracoConsent(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
{
Alter.Table(Constants.DatabaseSchema.Tables.Consent).AlterColumn("comment").AsString().Nullable().Do();
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_14_0
|
||||
{
|
||||
/// <summary>
|
||||
/// Migrates member group picker properties from NVarchar to NText. See https://github.com/umbraco/Umbraco-CMS/issues/3268.
|
||||
/// </summary>
|
||||
public class UpdateMemberGroupPickerData : MigrationBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Migrates member group picker properties from NVarchar to NText. See https://github.com/umbraco/Umbraco-CMS/issues/3268.
|
||||
/// </summary>
|
||||
public UpdateMemberGroupPickerData(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
Database.Execute($@"UPDATE umbracoPropertyData SET textValue = varcharValue, varcharValue = NULL
|
||||
WHERE textValue IS NULL AND id IN (
|
||||
SELECT id FROM umbracoPropertyData WHERE propertyTypeId in (
|
||||
SELECT id from cmsPropertyType where dataTypeId IN (
|
||||
SELECT nodeId FROM umbracoDataType WHERE propertyEditorAlias = '{Constants.PropertyEditors.Aliases.MemberGroupPicker}'
|
||||
)
|
||||
)
|
||||
)");
|
||||
|
||||
Database.Execute($"UPDATE umbracoDataType SET dbType = 'Ntext' WHERE propertyEditorAlias = '{Constants.PropertyEditors.Aliases.MemberGroupPicker}'");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_5_0
|
||||
{
|
||||
public class AddRedirectUrlTable : MigrationBase
|
||||
{
|
||||
public AddRedirectUrlTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var database = Database;
|
||||
var umbracoRedirectUrlTableName = "umbracoRedirectUrl";
|
||||
|
||||
var tables = SqlSyntax.GetTablesInSchema(database).ToArray();
|
||||
|
||||
if (tables.InvariantContains(umbracoRedirectUrlTableName))
|
||||
{
|
||||
var columns = SqlSyntax.GetColumnsInSchema(database).ToArray();
|
||||
if (columns.Any(x => x.TableName.InvariantEquals(umbracoRedirectUrlTableName) && x.ColumnName.InvariantEquals("id") && x.DataType == "uniqueidentifier"))
|
||||
return;
|
||||
Delete.Table(umbracoRedirectUrlTableName).Do();
|
||||
}
|
||||
|
||||
Create.Table(umbracoRedirectUrlTableName)
|
||||
.WithColumn("id").AsGuid().NotNullable().PrimaryKey("PK_" + umbracoRedirectUrlTableName)
|
||||
.WithColumn("createDateUtc").AsDateTime().NotNullable()
|
||||
.WithColumn("url").AsString(2048).NotNullable()
|
||||
.WithColumn("contentKey").AsGuid().NotNullable()
|
||||
.WithColumn("urlHash").AsString(40).NotNullable()
|
||||
.Do();
|
||||
|
||||
Create.Index("IX_" + umbracoRedirectUrlTableName).OnTable(umbracoRedirectUrlTableName)
|
||||
.OnColumn("urlHash")
|
||||
.Ascending()
|
||||
.OnColumn("contentKey")
|
||||
.Ascending()
|
||||
.OnColumn("createDateUtc")
|
||||
.Descending()
|
||||
.WithOptions().NonClustered()
|
||||
.Do();
|
||||
|
||||
Create.ForeignKey("FK_" + umbracoRedirectUrlTableName)
|
||||
.FromTable(umbracoRedirectUrlTableName).ForeignColumn("contentKey")
|
||||
.ToTable("umbracoNode").PrimaryColumn("uniqueID")
|
||||
.Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_5_0
|
||||
{
|
||||
/// <summary>
|
||||
/// This is here to re-remove these tables, we dropped them in 7.3 but new installs created them again so we're going to re-drop them
|
||||
/// </summary>
|
||||
public class RemoveStylesheetDataAndTablesAgain : MigrationBase
|
||||
{
|
||||
public RemoveStylesheetDataAndTablesAgain(IMigrationContext context)
|
||||
: base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
// these have been obsoleted, need to copy the values here
|
||||
var stylesheetPropertyObjectType = new Guid("5555da4f-a123-42b2-4488-dcdfb25e4111");
|
||||
var stylesheetObjectType = new Guid("9F68DA4F-A3A8-44C2-8226-DCBD125E4840");
|
||||
|
||||
//Clear all stylesheet data if the tables exist
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
|
||||
if (tables.InvariantContains("cmsStylesheetProperty"))
|
||||
{
|
||||
Delete.FromTable("cmsStylesheetProperty").AllRows().Do();
|
||||
Delete.FromTable("umbracoNode").Row(new { nodeObjectType = stylesheetPropertyObjectType }).Do();
|
||||
|
||||
Delete.Table("cmsStylesheetProperty").Do();
|
||||
}
|
||||
if (tables.InvariantContains("cmsStylesheet"))
|
||||
{
|
||||
Delete.FromTable("cmsStylesheet").AllRows().Do();
|
||||
Delete.FromTable("umbracoNode").Row(new { nodeObjectType = stylesheetObjectType }).Do();
|
||||
|
||||
Delete.Table("cmsStylesheet").Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_5_0
|
||||
{
|
||||
/// <summary>
|
||||
/// See: http://issues.umbraco.org/issue/U4-8522
|
||||
/// </summary>
|
||||
public class UpdateUniqueIndexOnPropertyData : MigrationBase
|
||||
{
|
||||
public UpdateUniqueIndexOnPropertyData(IMigrationContext context)
|
||||
: base(context)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
//Clear all stylesheet data if the tables exist
|
||||
//tuple = tablename, indexname, columnname, unique
|
||||
var indexes = SqlSyntax.GetDefinedIndexes(Context.Database).ToArray();
|
||||
var found = indexes.FirstOrDefault(
|
||||
x => x.Item1.InvariantEquals("cmsPropertyData")
|
||||
&& x.Item2.InvariantEquals("IX_cmsPropertyData_1")
|
||||
//we're searching for the old index which is not unique
|
||||
&& x.Item4 == false);
|
||||
|
||||
if (found != null)
|
||||
{
|
||||
Database.Execute("DELETE FROM cmsPropertyData WHERE id NOT IN (SELECT MIN(id) FROM cmsPropertyData GROUP BY nodeId, versionId, propertytypeid HAVING MIN(id) IS NOT NULL)");
|
||||
|
||||
//we need to re create this index
|
||||
Delete.Index("IX_cmsPropertyData_1").OnTable("cmsPropertyData").Do();
|
||||
Create.Index("IX_cmsPropertyData_1").OnTable("cmsPropertyData")
|
||||
.OnColumn("nodeId").Ascending()
|
||||
.OnColumn("versionId").Ascending()
|
||||
.OnColumn("propertytypeid").Ascending()
|
||||
.WithOptions().NonClustered()
|
||||
.WithOptions().Unique()
|
||||
.Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_5_5
|
||||
{
|
||||
/// <summary>
|
||||
/// See: http://issues.umbraco.org/issue/U4-4196
|
||||
/// </summary>
|
||||
public class UpdateAllowedMediaTypesAtRoot : MigrationBase
|
||||
{
|
||||
public UpdateAllowedMediaTypesAtRoot(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
Database.Execute("UPDATE cmsContentType SET allowAtRoot = 1 WHERE nodeId = 1032 OR nodeId = 1033");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
|
||||
{
|
||||
public class AddIndexToCmsMemberLoginName : MigrationBase
|
||||
{
|
||||
public AddIndexToCmsMemberLoginName(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var database = Database;
|
||||
|
||||
//Now we need to check if we can actually d6 this because we won't be able to if there's data in there that is too long
|
||||
//http://issues.umbraco.org/issue/U4-9758
|
||||
|
||||
var colLen = database.ExecuteScalar<int?>("select max(datalength(LoginName)) from cmsMember");
|
||||
|
||||
if (colLen < 900 == false && colLen != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(Context.Database);
|
||||
|
||||
//make sure it doesn't already exist
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsMember_LoginName")) == false)
|
||||
{
|
||||
//we can apply the index
|
||||
Create.Index("IX_cmsMember_LoginName").OnTable("cmsMember")
|
||||
.OnColumn("LoginName")
|
||||
.Ascending()
|
||||
.WithOptions()
|
||||
.NonClustered()
|
||||
.Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
|
||||
{
|
||||
public class AddIndexToUmbracoNodePath : MigrationBase
|
||||
{
|
||||
public AddIndexToUmbracoNodePath(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(Context.Database);
|
||||
|
||||
//make sure it doesn't already exist
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoNodePath")) == false)
|
||||
{
|
||||
Create.Index("IX_umbracoNodePath").OnTable("umbracoNode")
|
||||
.OnColumn("path")
|
||||
.Ascending()
|
||||
.WithOptions()
|
||||
.NonClustered()
|
||||
.Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
|
||||
{
|
||||
public class AddIndexToUser2NodePermission : MigrationBase
|
||||
{
|
||||
public AddIndexToUser2NodePermission(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(Context.Database);
|
||||
|
||||
//make sure it doesn't already exist
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoUser2NodePermission_nodeId")) == false)
|
||||
{
|
||||
Create.Index("IX_umbracoUser2NodePermission_nodeId").OnTable("umbracoUser2NodePermission")
|
||||
.OnColumn("nodeId")
|
||||
.Ascending()
|
||||
.WithOptions()
|
||||
.NonClustered()
|
||||
.Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
|
||||
{
|
||||
public class AddIndexesToUmbracoRelationTables : MigrationBase
|
||||
{
|
||||
public AddIndexesToUmbracoRelationTables(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(Context.Database).ToArray();
|
||||
|
||||
//make sure it doesn't already exist
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoRelation_parentChildType")) == false)
|
||||
{
|
||||
//This will remove any corrupt/duplicate data in the relation table before the index is applied
|
||||
//Ensure this executes in a deferred block which will be done inside of the migration transaction
|
||||
var database = Database;
|
||||
|
||||
//We need to check if this index has corrupted data and then clear that data
|
||||
var duplicates = database.Fetch<dynamic>("SELECT parentId,childId,relType FROM umbracoRelation GROUP BY parentId,childId,relType HAVING COUNT(*) > 1");
|
||||
if (duplicates.Count > 0)
|
||||
{
|
||||
//need to fix this there cannot be duplicates so we'll take the latest entries, it's really not going to matter though
|
||||
foreach (var duplicate in duplicates)
|
||||
{
|
||||
var ids = database.Fetch<int>("SELECT id FROM umbracoRelation WHERE parentId=@parentId AND childId=@childId AND relType=@relType ORDER BY datetime DESC",
|
||||
new { parentId = duplicate.parentId, childId = duplicate.childId, relType = duplicate.relType });
|
||||
|
||||
if (ids.Count == 1)
|
||||
{
|
||||
//this is just a safety check, this should absolutely never happen
|
||||
throw new InvalidOperationException("Duplicates were detected but could not be discovered");
|
||||
}
|
||||
|
||||
//delete the others
|
||||
ids = ids.Skip(0).ToList();
|
||||
|
||||
//iterate in groups of 2000 to avoid the max sql parameter limit
|
||||
foreach (var idGroup in ids.InGroupsOf(2000))
|
||||
{
|
||||
database.Execute("DELETE FROM umbracoRelation WHERE id IN (@ids)", new { ids = idGroup });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//unique index to prevent duplicates - and for better perf
|
||||
Create.Index("IX_umbracoRelation_parentChildType").OnTable("umbracoRelation")
|
||||
.OnColumn("parentId").Ascending()
|
||||
.OnColumn("childId").Ascending()
|
||||
.OnColumn("relType").Ascending()
|
||||
.WithOptions()
|
||||
.Unique()
|
||||
.Do();
|
||||
}
|
||||
|
||||
//need indexes on alias and name for relation type since these are queried against
|
||||
|
||||
//make sure it doesn't already exist
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoRelationType_alias")) == false)
|
||||
{
|
||||
Create.Index("IX_umbracoRelationType_alias").OnTable("umbracoRelationType")
|
||||
.OnColumn("alias")
|
||||
.Ascending()
|
||||
.WithOptions()
|
||||
.NonClustered()
|
||||
.Do();
|
||||
}
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_umbracoRelationType_name")) == false)
|
||||
{
|
||||
Create.Index("IX_umbracoRelationType_name").OnTable("umbracoRelationType")
|
||||
.OnColumn("name")
|
||||
.Ascending()
|
||||
.WithOptions()
|
||||
.NonClustered()
|
||||
.Do();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
|
||||
{
|
||||
public class AddLockObjects : MigrationBase
|
||||
{
|
||||
public AddLockObjects(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
EnsureLockObject(Constants.Locks.Servers, "Servers");
|
||||
}
|
||||
|
||||
private void EnsureLockObject(int id, string name)
|
||||
{
|
||||
var db = Database;
|
||||
var exists = db.Exists<LockDto>(id);
|
||||
if (exists) return;
|
||||
// be safe: delete old umbracoNode lock objects if any
|
||||
db.Execute("DELETE FROM umbracoNode WHERE id=@id;", new { id });
|
||||
// then create umbracoLock object
|
||||
db.Execute("INSERT umbracoLock (id, name, value) VALUES (@id, @name, 1);", new { id, name });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
|
||||
{
|
||||
public class AddLockTable : MigrationBase
|
||||
{
|
||||
public AddLockTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
|
||||
if (tables.InvariantContains("umbracoLock") == false)
|
||||
{
|
||||
Create.Table("umbracoLock")
|
||||
.WithColumn("id").AsInt32().PrimaryKey("PK_umbracoLock")
|
||||
.WithColumn("value").AsInt32().NotNullable()
|
||||
.WithColumn("name").AsString(64).NotNullable()
|
||||
.Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
|
||||
{
|
||||
public class AddMacroUniqueIdColumn : MigrationBase
|
||||
{
|
||||
public AddMacroUniqueIdColumn(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("cmsMacro") && x.ColumnName.InvariantEquals("uniqueId")) == false)
|
||||
{
|
||||
Create.Column("uniqueId").OnTable("cmsMacro").AsGuid().Nullable().Do();
|
||||
UpdateMacroGuids();
|
||||
Alter.Table("cmsMacro").AlterColumn("uniqueId").AsGuid().NotNullable().Do();
|
||||
Create.Index("IX_cmsMacro_UniqueId").OnTable("cmsMacro").OnColumn("uniqueId")
|
||||
.Ascending()
|
||||
.WithOptions().NonClustered()
|
||||
.WithOptions().Unique()
|
||||
.Do();
|
||||
|
||||
}
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("cmsMacroProperty") && x.ColumnName.InvariantEquals("uniquePropertyId")) == false)
|
||||
{
|
||||
Create.Column("uniquePropertyId").OnTable("cmsMacroProperty").AsGuid().Nullable().Do();
|
||||
UpdateMacroPropertyGuids();
|
||||
Alter.Table("cmsMacroProperty").AlterColumn("uniquePropertyId").AsGuid().NotNullable().Do();
|
||||
Create.Index("IX_cmsMacroProperty_UniquePropertyId").OnTable("cmsMacroProperty").OnColumn("uniquePropertyId")
|
||||
.Ascending()
|
||||
.WithOptions().NonClustered()
|
||||
.WithOptions().Unique()
|
||||
.Do();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateMacroGuids()
|
||||
{
|
||||
var database = Database;
|
||||
|
||||
var updates = database.Query<dynamic>("SELECT id, macroAlias FROM cmsMacro")
|
||||
.Select(macro => Tuple.Create((int) macro.id, ("macro____" + (string) macro.macroAlias).ToGuid()))
|
||||
.ToList();
|
||||
|
||||
foreach (var update in updates)
|
||||
database.Execute("UPDATE cmsMacro set uniqueId=@guid WHERE id=@id", new { guid = update.Item2, id = update.Item1 });
|
||||
}
|
||||
|
||||
private void UpdateMacroPropertyGuids()
|
||||
{
|
||||
var database = Database;
|
||||
|
||||
var updates = database.Query<dynamic>(@"SELECT cmsMacroProperty.id id, macroPropertyAlias propertyAlias, cmsMacro.macroAlias macroAlias
|
||||
FROM cmsMacroProperty
|
||||
JOIN cmsMacro ON cmsMacroProperty.macro=cmsMacro.id")
|
||||
.Select(prop => Tuple.Create((int) prop.id, ("macro____" + (string) prop.macroAlias + "____" + (string) prop.propertyAlias).ToGuid()))
|
||||
.ToList();
|
||||
|
||||
foreach (var update in updates)
|
||||
database.Execute("UPDATE cmsMacroProperty set uniquePropertyId=@guid WHERE id=@id", new { guid = update.Item2, id = update.Item1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
|
||||
{
|
||||
public class AddRelationTypeUniqueIdColumn : MigrationBase
|
||||
{
|
||||
public AddRelationTypeUniqueIdColumn(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("umbracoRelationType") && x.ColumnName.InvariantEquals("typeUniqueId")) == false)
|
||||
{
|
||||
Create.Column("typeUniqueId").OnTable("umbracoRelationType").AsGuid().Nullable().Do();
|
||||
UpdateRelationTypeGuids();
|
||||
Alter.Table("umbracoRelationType").AlterColumn("typeUniqueId").AsGuid().NotNullable().Do();
|
||||
Create.Index("IX_umbracoRelationType_UniqueId").OnTable("umbracoRelationType").OnColumn("typeUniqueId")
|
||||
.Ascending()
|
||||
.WithOptions().NonClustered()
|
||||
.WithOptions().Unique()
|
||||
.Do();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateRelationTypeGuids()
|
||||
{
|
||||
var database = Database;
|
||||
var updates = database.Query<dynamic>("SELECT id, alias, name FROM umbracoRelationType")
|
||||
.Select(relationType => Tuple.Create((int) relationType.id, ("relationType____" + (string) relationType.alias + "____" + (string) relationType.name).ToGuid()))
|
||||
.ToList();
|
||||
|
||||
foreach (var update in updates)
|
||||
database.Execute("UPDATE umbracoRelationType set typeUniqueId=@guid WHERE id=@id", new { guid = update.Item2, id = update.Item1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
|
||||
{
|
||||
public class NormalizeTemplateGuids : MigrationBase
|
||||
{
|
||||
public NormalizeTemplateGuids(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var database = Database;
|
||||
|
||||
// we need this migration because ppl running pre-7.6 on Cloud and Courier have templates in different
|
||||
// environments having different GUIDs (Courier does not sync template GUIDs) and we need to normalize
|
||||
// these GUIDs so templates with the same alias on different environments have the same GUID.
|
||||
// however, if already running a prerelease version of 7.6, we do NOT want to normalize the GUIDs as quite
|
||||
// probably, we are already running Deploy and the GUIDs are OK. assuming noone is running a prerelease
|
||||
// of 7.6 on Courier.
|
||||
// so... testing if we already have a 7.6.0 version installed. not pretty but...?
|
||||
//
|
||||
var version = database.FirstOrDefault<string>("SELECT version FROM umbracoMigration WHERE name=@name ORDER BY version DESC", new { name = Constants.System.UmbracoUpgradePlanName });
|
||||
if (version != null && version.StartsWith("7.6.0")) return;
|
||||
|
||||
var updates = database.Query<dynamic>(@"SELECT umbracoNode.id, cmsTemplate.alias FROM umbracoNode
|
||||
JOIN cmsTemplate ON umbracoNode.id=cmsTemplate.nodeId
|
||||
WHERE nodeObjectType = @guid", new { guid = Constants.ObjectTypes.TemplateType })
|
||||
.Select(template => Tuple.Create((int) template.id, ("template____" + (string) template.alias).ToGuid()))
|
||||
.ToList();
|
||||
|
||||
foreach (var update in updates)
|
||||
database.Execute("UPDATE umbracoNode set uniqueId=@guid WHERE id=@id", new { guid = update.Item2, id = update.Item1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
|
||||
{
|
||||
public class ReduceLoginNameColumnsSize : MigrationBase
|
||||
{
|
||||
public ReduceLoginNameColumnsSize(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
//Now we need to check if we can actually d6 this because we won't be able to if there's data in there that is too long
|
||||
//http://issues.umbraco.org/issue/U4-9758
|
||||
|
||||
var database = Database;
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(database);
|
||||
|
||||
var colLen = database.ExecuteScalar<int?>("select max(datalength(LoginName)) from cmsMember");
|
||||
|
||||
if (colLen < 900 == false) return;
|
||||
|
||||
//if an index exists on this table we need to drop it. Normally we'd check via index name but in some odd cases (i.e. Our)
|
||||
//the index name is something odd (starts with "mi_"). In any case, the index cannot exist if we want to alter the column
|
||||
//so we'll drop whatever index is there and add one with the correct name after.
|
||||
var loginNameIndex = dbIndexes.FirstOrDefault(x => x.TableName.InvariantEquals("cmsMember") && x.ColumnName.InvariantEquals("LoginName"));
|
||||
if (loginNameIndex != null)
|
||||
{
|
||||
Delete.Index(loginNameIndex.IndexName).OnTable("cmsMember").Do();
|
||||
}
|
||||
|
||||
//we can apply the col length change
|
||||
Alter.Table("cmsMember")
|
||||
.AlterColumn("LoginName")
|
||||
.AsString(225)
|
||||
.NotNullable()
|
||||
.Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
|
||||
{
|
||||
/// <summary>
|
||||
/// See: http://issues.umbraco.org/issue/U4-9188
|
||||
/// </summary>
|
||||
public class UpdateUniqueIndexOnPropertyData : MigrationBase
|
||||
{
|
||||
public UpdateUniqueIndexOnPropertyData(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
//tuple = tablename, indexname, columnname, unique
|
||||
var indexes = SqlSyntax.GetDefinedIndexes(Context.Database).ToArray();
|
||||
var found = indexes.FirstOrDefault(
|
||||
x => x.Item1.InvariantEquals("cmsPropertyData")
|
||||
&& x.Item2.InvariantEquals("IX_cmsPropertyData"));
|
||||
|
||||
if (found != null)
|
||||
{
|
||||
//drop the index
|
||||
Delete.Index("IX_cmsPropertyData").OnTable("cmsPropertyData").Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_6_0
|
||||
{
|
||||
public class RemoveUmbracoDeployTables : MigrationBase
|
||||
{
|
||||
public RemoveUmbracoDeployTables(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
|
||||
|
||||
// there are two versions of umbracoDeployDependency,
|
||||
// 1. one created by 7.4 and never used, we need to remove it (has a sourceId column)
|
||||
// 2. one created by Deploy itself, we need to keep it (has a sourceUdi column)
|
||||
if (tables.InvariantContains("umbracoDeployDependency"))
|
||||
{
|
||||
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("umbracoDeployDependency") && x.ColumnName.InvariantEquals("sourceId")))
|
||||
Delete.Table("umbracoDeployDependency").Do();
|
||||
}
|
||||
|
||||
// always remove umbracoDeployChecksum
|
||||
if (tables.InvariantContains("umbracoDeployChecksum"))
|
||||
Delete.Table("umbracoDeployChecksum").Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0
|
||||
{
|
||||
public class AddIndexToDictionaryKeyColumn : MigrationBase
|
||||
{
|
||||
public AddIndexToDictionaryKeyColumn(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var database = Database;
|
||||
//Now we need to check if we can actually do this because we won't be able to if there's data in there that is too long
|
||||
var colLen = database.ExecuteScalar<int?>(string.Format("select max(datalength({0})) from cmsDictionary", SqlSyntax.GetQuotedColumnName("key")));
|
||||
|
||||
if (colLen < 900 == false && colLen != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(Context.Database);
|
||||
|
||||
//make sure it doesn't already exist
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsDictionary_key")) == false)
|
||||
{
|
||||
//we can apply the index
|
||||
Create.Index("IX_cmsDictionary_key").OnTable("cmsDictionary")
|
||||
.OnColumn("key")
|
||||
.Ascending()
|
||||
.WithOptions()
|
||||
.NonClustered()
|
||||
.Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,357 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using ColumnInfo = Umbraco.Core.Persistence.SqlSyntax.ColumnInfo;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0
|
||||
{
|
||||
public class AddUserGroupTables : MigrationBase
|
||||
{
|
||||
private readonly string _collateSyntax;
|
||||
|
||||
public AddUserGroupTables(IMigrationContext context)
|
||||
: base(context)
|
||||
{
|
||||
//For some of the migration data inserts we require to use a special MSSQL collate expression since
|
||||
//some databases may have a custom collation specified and if that is the case, when we compare strings
|
||||
//in dynamic SQL it will try to compare strings in different collations and this will yield errors.
|
||||
_collateSyntax = "COLLATE DATABASE_DEFAULT";
|
||||
}
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToList();
|
||||
var constraints = SqlSyntax.GetConstraintsPerColumn(Context.Database).Distinct().ToArray();
|
||||
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
|
||||
|
||||
//In some very rare cases, there might already be user group tables that we'll need to remove first
|
||||
//but of course we don't want to remove the tables we will be creating below if they already exist so
|
||||
//need to do some checks first since these old rare tables have a different schema
|
||||
RemoveOldTablesIfExist(tables, columns);
|
||||
|
||||
if (AddNewTables(tables))
|
||||
{
|
||||
MigrateUserPermissions();
|
||||
MigrateUserTypesToGroups();
|
||||
DeleteOldTables(tables, constraints);
|
||||
SetDefaultIcons();
|
||||
}
|
||||
else
|
||||
{
|
||||
//if we aren't adding the tables, make sure that the umbracoUserGroup table has the correct FKs - these
|
||||
//were added after the beta release so we need to do some cleanup
|
||||
//if the FK doesn't exist
|
||||
if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUserGroup")
|
||||
&& x.Item2.InvariantEquals("startContentId")
|
||||
&& x.Item3.InvariantEquals("FK_startContentId_umbracoNode_id")) == false)
|
||||
{
|
||||
//before we add any foreign key we need to make sure there's no stale data in there which would have happened in the beta
|
||||
//release if a start node was assigned and then that start node was deleted.
|
||||
Database.Execute(@"UPDATE umbracoUserGroup SET startContentId = NULL WHERE startContentId NOT IN (SELECT id FROM umbracoNode)");
|
||||
|
||||
Create.ForeignKey("FK_startContentId_umbracoNode_id")
|
||||
.FromTable("umbracoUserGroup")
|
||||
.ForeignColumn("startContentId")
|
||||
.ToTable("umbracoNode")
|
||||
.PrimaryColumn("id")
|
||||
.OnDelete(Rule.None)
|
||||
.OnUpdate(Rule.None)
|
||||
.Do();
|
||||
}
|
||||
|
||||
if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUserGroup")
|
||||
&& x.Item2.InvariantEquals("startMediaId")
|
||||
&& x.Item3.InvariantEquals("FK_startMediaId_umbracoNode_id")) == false)
|
||||
{
|
||||
//before we add any foreign key we need to make sure there's no stale data in there which would have happened in the beta
|
||||
//release if a start node was assigned and then that start node was deleted.
|
||||
Database.Execute(@"UPDATE umbracoUserGroup SET startMediaId = NULL WHERE startMediaId NOT IN (SELECT id FROM umbracoNode)");
|
||||
|
||||
Create.ForeignKey("FK_startMediaId_umbracoNode_id")
|
||||
.FromTable("umbracoUserGroup")
|
||||
.ForeignColumn("startMediaId")
|
||||
.ToTable("umbracoNode")
|
||||
.PrimaryColumn("id")
|
||||
.OnDelete(Rule.None)
|
||||
.OnUpdate(Rule.None)
|
||||
.Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// In some very rare cases, there might already be user group tables that we'll need to remove first
|
||||
/// but of course we don't want to remove the tables we will be creating below if they already exist so
|
||||
/// need to do some checks first since these old rare tables have a different schema
|
||||
/// </summary>
|
||||
/// <param name="tables"></param>
|
||||
/// <param name="columns"></param>
|
||||
private void RemoveOldTablesIfExist(List<string> tables, ColumnInfo[] columns)
|
||||
{
|
||||
if (tables.Contains("umbracoUser2userGroup", StringComparer.InvariantCultureIgnoreCase))
|
||||
{
|
||||
//this column doesn't exist in the 7.7 schema, so if it's there, then this is a super old table
|
||||
var foundOldColumn = columns
|
||||
.FirstOrDefault(x =>
|
||||
x.ColumnName.Equals("user", StringComparison.InvariantCultureIgnoreCase)
|
||||
&& x.TableName.Equals("umbracoUser2userGroup", StringComparison.InvariantCultureIgnoreCase));
|
||||
if (foundOldColumn != null)
|
||||
{
|
||||
Delete.Table("umbracoUser2userGroup").Do();
|
||||
//remove from the tables list since this will be re-checked in further logic
|
||||
tables.Remove("umbracoUser2userGroup");
|
||||
}
|
||||
}
|
||||
|
||||
if (tables.Contains("umbracoUserGroup", StringComparer.InvariantCultureIgnoreCase))
|
||||
{
|
||||
//The new schema has several columns, the super old one for this table only had 2 so if it's 2 get rid of it
|
||||
var countOfCols = columns
|
||||
.Count(x => x.TableName.Equals("umbracoUserGroup", StringComparison.InvariantCultureIgnoreCase));
|
||||
if (countOfCols == 2)
|
||||
{
|
||||
Delete.Table("umbracoUserGroup").Do();
|
||||
//remove from the tables list since this will be re-checked in further logic
|
||||
tables.Remove("umbracoUserGroup");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void SetDefaultIcons()
|
||||
{
|
||||
Database.Execute($"UPDATE umbracoUserGroup SET icon = \'\' WHERE userGroupAlias = \'{Constants.Security.AdminGroupAlias}\'");
|
||||
Database.Execute("UPDATE umbracoUserGroup SET icon = \'icon-edit\' WHERE userGroupAlias = \'writer\'");
|
||||
Database.Execute("UPDATE umbracoUserGroup SET icon = \'icon-tools\' WHERE userGroupAlias = \'editor\'");
|
||||
Database.Execute("UPDATE umbracoUserGroup SET icon = \'icon-globe\' WHERE userGroupAlias = \'translator\'");
|
||||
}
|
||||
|
||||
private bool AddNewTables(List<string> tables)
|
||||
{
|
||||
var updated = false;
|
||||
if (tables.InvariantContains("umbracoUserGroup") == false)
|
||||
{
|
||||
Create.Table<UserGroupDto>().Do();
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (tables.InvariantContains("umbracoUser2UserGroup") == false)
|
||||
{
|
||||
Create.Table<User2UserGroupDto>().Do();
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (tables.InvariantContains("umbracoUserGroup2App") == false)
|
||||
{
|
||||
Create.Table<UserGroup2AppDto>().Do();
|
||||
updated = true;
|
||||
}
|
||||
|
||||
if (tables.InvariantContains("umbracoUserGroup2NodePermission") == false)
|
||||
{
|
||||
Create.Table<UserGroup2NodePermissionDto>().Do();
|
||||
updated = true;
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
|
||||
private void MigrateUserTypesToGroups()
|
||||
{
|
||||
// Create a user group for each user type
|
||||
Database.Execute(@"INSERT INTO umbracoUserGroup (userGroupAlias, userGroupName, userGroupDefaultPermissions)
|
||||
SELECT userTypeAlias, userTypeName, userTypeDefaultPermissions
|
||||
FROM umbracoUserType");
|
||||
|
||||
// Add each user to the group created from their type
|
||||
Database.Execute(string.Format(@"INSERT INTO umbracoUser2UserGroup (userId, userGroupId)
|
||||
SELECT u.id, ug.id
|
||||
FROM umbracoUser u
|
||||
INNER JOIN umbracoUserType ut ON ut.id = u.userType
|
||||
INNER JOIN umbracoUserGroup ug ON ug.userGroupAlias {0} = ut.userTypeAlias {0}", _collateSyntax));
|
||||
|
||||
// Add the built-in administrator account to all apps
|
||||
// this will lookup all of the apps that the admin currently has access to in order to assign the sections
|
||||
// instead of use statically assigning since there could be extra sections we don't know about.
|
||||
Database.Execute(@"INSERT INTO umbracoUserGroup2app (userGroupId,app)
|
||||
SELECT ug.id, app
|
||||
FROM umbracoUserGroup ug
|
||||
INNER JOIN umbracoUser2UserGroup u2ug ON u2ug.userGroupId = ug.id
|
||||
INNER JOIN umbracoUser u ON u.id = u2ug.userId
|
||||
INNER JOIN umbracoUser2app u2a ON u2a." + SqlSyntax.GetQuotedColumnName("user") + @" = u.id
|
||||
WHERE u.id = 0");
|
||||
|
||||
// Add the default section access to the other built-in accounts
|
||||
// writer:
|
||||
Database.Execute(string.Format(@"INSERT INTO umbracoUserGroup2app (userGroupId, app)
|
||||
SELECT ug.id, 'content' as app
|
||||
FROM umbracoUserGroup ug
|
||||
WHERE ug.userGroupAlias {0} = 'writer' {0}", _collateSyntax));
|
||||
// editor
|
||||
Database.Execute(string.Format(@"INSERT INTO umbracoUserGroup2app (userGroupId, app)
|
||||
SELECT ug.id, 'content' as app
|
||||
FROM umbracoUserGroup ug
|
||||
WHERE ug.userGroupAlias {0} = 'editor' {0}", _collateSyntax));
|
||||
Database.Execute(string.Format(@"INSERT INTO umbracoUserGroup2app (userGroupId, app)
|
||||
SELECT ug.id, 'media' as app
|
||||
FROM umbracoUserGroup ug
|
||||
WHERE ug.userGroupAlias {0} = 'editor' {0}", _collateSyntax));
|
||||
// translator
|
||||
Database.Execute(string.Format(@"INSERT INTO umbracoUserGroup2app (userGroupId, app)
|
||||
SELECT ug.id, 'translation' as app
|
||||
FROM umbracoUserGroup ug
|
||||
WHERE ug.userGroupAlias {0} = 'translator' {0}", _collateSyntax));
|
||||
|
||||
//We need to lookup all distinct combinations of section access and create a group for each distinct collection
|
||||
//and assign groups accordingly. We'll perform the lookup 'now' to then create the queued SQL migrations.
|
||||
var userAppsData = Context.Database.Query<dynamic>(@"SELECT u.id, u2a.app FROM umbracoUser u
|
||||
INNER JOIN umbracoUser2app u2a ON u2a." + SqlSyntax.GetQuotedColumnName("user") + @" = u.id
|
||||
ORDER BY u.id, u2a.app");
|
||||
var usersWithApps = new Dictionary<int, List<string>>();
|
||||
foreach (var userApps in userAppsData)
|
||||
{
|
||||
if (usersWithApps.TryGetValue(userApps.id, out List<string> apps) == false)
|
||||
{
|
||||
apps = new List<string> {userApps.app};
|
||||
usersWithApps.Add(userApps.id, apps);
|
||||
}
|
||||
else
|
||||
{
|
||||
apps.Add(userApps.app);
|
||||
}
|
||||
}
|
||||
//At this stage we have a dictionary of users with a collection of their apps which are sorted
|
||||
//and we need to determine the unique/distinct app collections for each user to create groups with.
|
||||
//We can do this by creating a hash value of all of the app values and since they are already sorted we can get a distinct
|
||||
//collection by this hash.
|
||||
var distinctApps = usersWithApps
|
||||
.Select(x => new {appCollection = x.Value, appsHash = string.Join("", x.Value).GenerateHash()})
|
||||
.DistinctBy(x => x.appsHash)
|
||||
.ToArray();
|
||||
//Now we need to create user groups for each of these distinct app collections, and then assign the corresponding users to those groups
|
||||
for (var i = 0; i < distinctApps.Length; i++)
|
||||
{
|
||||
//create the group
|
||||
var alias = "MigratedSectionAccessGroup_" + (i + 1);
|
||||
Insert.IntoTable("umbracoUserGroup").Row(new
|
||||
{
|
||||
userGroupAlias = "MigratedSectionAccessGroup_" + (i + 1),
|
||||
userGroupName = "Migrated Section Access Group " + (i + 1)
|
||||
}).Do();
|
||||
//now assign the apps
|
||||
var distinctApp = distinctApps[i];
|
||||
foreach (var app in distinctApp.appCollection)
|
||||
{
|
||||
Database.Execute(string.Format(@"INSERT INTO umbracoUserGroup2app (userGroupId, app)
|
||||
SELECT ug.id, '" + app + @"' as app
|
||||
FROM umbracoUserGroup ug
|
||||
WHERE ug.userGroupAlias {0} = '" + alias + "' {0}", _collateSyntax));
|
||||
}
|
||||
//now assign the corresponding users to this group
|
||||
foreach (var userWithApps in usersWithApps)
|
||||
{
|
||||
//check if this user's groups hash matches the current groups hash
|
||||
var hash = string.Join("", userWithApps.Value).GenerateHash();
|
||||
if (hash == distinctApp.appsHash)
|
||||
{
|
||||
//it matches so assign the user to this group
|
||||
Database.Execute(string.Format(@"INSERT INTO umbracoUser2UserGroup (userId, userGroupId)
|
||||
SELECT " + userWithApps.Key + @", ug.id
|
||||
FROM umbracoUserGroup ug
|
||||
WHERE ug.userGroupAlias {0} = '" + alias + "' {0}", _collateSyntax));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Rename some groups for consistency (plural form)
|
||||
Database.Execute("UPDATE umbracoUserGroup SET userGroupName = 'Writers' WHERE userGroupAlias = 'writer'");
|
||||
Database.Execute("UPDATE umbracoUserGroup SET userGroupName = 'Translators' WHERE userGroupAlias = 'translator'");
|
||||
|
||||
//Ensure all built in groups have a start node of -1
|
||||
Database.Execute("UPDATE umbracoUserGroup SET startContentId = -1 WHERE userGroupAlias = 'editor'");
|
||||
Database.Execute("UPDATE umbracoUserGroup SET startMediaId = -1 WHERE userGroupAlias = 'editor'");
|
||||
Database.Execute("UPDATE umbracoUserGroup SET startContentId = -1 WHERE userGroupAlias = 'writer'");
|
||||
Database.Execute("UPDATE umbracoUserGroup SET startMediaId = -1 WHERE userGroupAlias = 'writer'");
|
||||
Database.Execute("UPDATE umbracoUserGroup SET startContentId = -1 WHERE userGroupAlias = 'translator'");
|
||||
Database.Execute("UPDATE umbracoUserGroup SET startMediaId = -1 WHERE userGroupAlias = 'translator'");
|
||||
Database.Execute("UPDATE umbracoUserGroup SET startContentId = -1 WHERE userGroupAlias = 'admin'");
|
||||
Database.Execute("UPDATE umbracoUserGroup SET startMediaId = -1 WHERE userGroupAlias = 'admin'");
|
||||
}
|
||||
|
||||
private void MigrateUserPermissions()
|
||||
{
|
||||
// Create user group records for all non-admin users that have specific permissions set
|
||||
Database.Execute(@"INSERT INTO umbracoUserGroup(userGroupAlias, userGroupName)
|
||||
SELECT 'permissionGroupFor' + userLogin, 'Migrated Permission Group for ' + userLogin
|
||||
FROM umbracoUser
|
||||
WHERE (id IN (
|
||||
SELECT userid
|
||||
FROM umbracoUser2NodePermission
|
||||
))
|
||||
AND id > 0");
|
||||
|
||||
// Associate those groups with the users
|
||||
Database.Execute(string.Format(@"INSERT INTO umbracoUser2UserGroup (userId, userGroupId)
|
||||
SELECT u.id, ug.id
|
||||
FROM umbracoUser u
|
||||
INNER JOIN umbracoUserGroup ug ON ug.userGroupAlias {0} = 'permissionGroupFor' + userLogin {0}", _collateSyntax));
|
||||
|
||||
// Create node permissions on the groups
|
||||
Database.Execute(string.Format(@"INSERT INTO umbracoUserGroup2NodePermission (userGroupId,nodeId,permission)
|
||||
SELECT ug.id, nodeId, permission
|
||||
FROM umbracoUserGroup ug
|
||||
INNER JOIN umbracoUser2UserGroup u2ug ON u2ug.userGroupId = ug.id
|
||||
INNER JOIN umbracoUser u ON u.id = u2ug.userId
|
||||
INNER JOIN umbracoUser2NodePermission u2np ON u2np.userId = u.id
|
||||
WHERE ug.userGroupAlias {0} NOT IN (
|
||||
SELECT userTypeAlias {0}
|
||||
FROM umbracoUserType
|
||||
)", _collateSyntax));
|
||||
|
||||
// Create app permissions on the groups
|
||||
Database.Execute(string.Format(@"INSERT INTO umbracoUserGroup2app (userGroupId,app)
|
||||
SELECT ug.id, app
|
||||
FROM umbracoUserGroup ug
|
||||
INNER JOIN umbracoUser2UserGroup u2ug ON u2ug.userGroupId = ug.id
|
||||
INNER JOIN umbracoUser u ON u.id = u2ug.userId
|
||||
INNER JOIN umbracoUser2app u2a ON u2a." + SqlSyntax.GetQuotedColumnName("user") + @" = u.id
|
||||
WHERE ug.userGroupAlias {0} NOT IN (
|
||||
SELECT userTypeAlias {0}
|
||||
FROM umbracoUserType
|
||||
)", _collateSyntax));
|
||||
}
|
||||
|
||||
private void DeleteOldTables(List<string> tables, Tuple<string, string, string>[] constraints)
|
||||
{
|
||||
if (tables.InvariantContains("umbracoUser2App"))
|
||||
{
|
||||
Delete.Table("umbracoUser2App").Do();
|
||||
}
|
||||
|
||||
if (tables.InvariantContains("umbracoUser2NodePermission"))
|
||||
{
|
||||
Delete.Table("umbracoUser2NodePermission").Do();
|
||||
}
|
||||
|
||||
if (tables.InvariantContains("umbracoUserType") && tables.InvariantContains("umbracoUser"))
|
||||
{
|
||||
//Delete the FK if it exists before dropping the column
|
||||
if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser") && x.Item3.InvariantEquals("FK_umbracoUser_umbracoUserType_id")))
|
||||
{
|
||||
Delete.ForeignKey("FK_umbracoUser_umbracoUserType_id").OnTable("umbracoUser").Do();
|
||||
}
|
||||
|
||||
//This is the super old constraint name of the FK for user type so check this one too
|
||||
if (constraints.Any(x => x.Item1.InvariantEquals("umbracoUser") && x.Item3.InvariantEquals("FK_user_userType")))
|
||||
{
|
||||
Delete.ForeignKey("FK_user_userType").OnTable("umbracoUser").Do();
|
||||
}
|
||||
|
||||
Delete.Column("userType").FromTable("umbracoUser").Do();
|
||||
Delete.Table("umbracoUserType").Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0
|
||||
{
|
||||
public class AddUserStartNodeTable : MigrationBase
|
||||
{
|
||||
public AddUserStartNodeTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
|
||||
|
||||
if (tables.InvariantContains("umbracoUserStartNode")) return;
|
||||
|
||||
Create.Table<UserStartNodeDto>().Do();
|
||||
|
||||
MigrateUserStartNodes();
|
||||
|
||||
//now remove the old columns
|
||||
|
||||
Delete.Column("startStructureID").FromTable("umbracoUser").Do();
|
||||
Delete.Column("startMediaID").FromTable("umbracoUser").Do();
|
||||
}
|
||||
|
||||
private void MigrateUserStartNodes()
|
||||
{
|
||||
Database.Execute(@"INSERT INTO umbracoUserStartNode (userId, startNode, startNodeType)
|
||||
SELECT id, startStructureID, 1
|
||||
FROM umbracoUser
|
||||
WHERE startStructureID IS NOT NULL AND startStructureID > 0 AND startStructureID IN (SELECT id FROM umbracoNode WHERE nodeObjectType='" + Constants.ObjectTypes.Document + "')");
|
||||
|
||||
Database.Execute(@"INSERT INTO umbracoUserStartNode (userId, startNode, startNodeType)
|
||||
SELECT id, startMediaID, 2
|
||||
FROM umbracoUser
|
||||
WHERE startMediaID IS NOT NULL AND startMediaID > 0 AND startMediaID IN (SELECT id FROM umbracoNode WHERE nodeObjectType='" + Constants.ObjectTypes.Media + "')");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0
|
||||
{
|
||||
/// <summary>
|
||||
/// Ensures the built-in user groups have the blueprint permission by default on upgrade
|
||||
/// </summary>
|
||||
public class EnsureContentTemplatePermissions : MigrationBase
|
||||
{
|
||||
public EnsureContentTemplatePermissions(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var database = Database;
|
||||
var userGroups = database.Fetch<UserGroupDto>(
|
||||
Context.SqlContext.Sql().Select("*")
|
||||
.From<UserGroupDto>()
|
||||
.Where<UserGroupDto>(x => x.Alias == "admin" || x.Alias == "editor"));
|
||||
|
||||
foreach (var userGroup in userGroups)
|
||||
{
|
||||
if (userGroup.DefaultPermissions.Contains('�') == false)
|
||||
{
|
||||
userGroup.DefaultPermissions += "�";
|
||||
Update.Table("umbracoUserGroup")
|
||||
.Set(new { userGroupDefaultPermissions = userGroup.DefaultPermissions })
|
||||
.Where(new { id = userGroup.Id })
|
||||
.Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0
|
||||
{
|
||||
public class ReduceDictionaryKeyColumnsSize : MigrationBase
|
||||
{
|
||||
public ReduceDictionaryKeyColumnsSize(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
//Now we need to check if we can actually do this because we won't be able to if there's data in there that is too long
|
||||
|
||||
var database = Database;
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(database);
|
||||
|
||||
var colLen = database.ExecuteScalar<int?>(string.Format("select max(datalength({0})) from cmsDictionary", SqlSyntax.GetQuotedColumnName("key")));
|
||||
|
||||
if (colLen < 900 == false) return;
|
||||
|
||||
//if it exists we need to drop it first
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsDictionary_key")))
|
||||
{
|
||||
Delete.Index("IX_cmsDictionary_key").OnTable("cmsDictionary").Do();
|
||||
}
|
||||
|
||||
//we can apply the col length change
|
||||
Alter.Table("cmsDictionary")
|
||||
.AlterColumn("key")
|
||||
.AsString(450)
|
||||
.NotNullable()
|
||||
.Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
using System.Linq;
|
||||
using System.Web.Security;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Security;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_7_0
|
||||
{
|
||||
public class UpdateUserTables : MigrationBase
|
||||
{
|
||||
public UpdateUserTables(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
//Don't execute if the column is already there
|
||||
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("umbracoUser") && x.ColumnName.InvariantEquals("createDate")) == false)
|
||||
Create.Column("createDate").OnTable("umbracoUser").AsDateTime().NotNullable().WithDefault(SystemMethods.CurrentDateTime).Do();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("umbracoUser") && x.ColumnName.InvariantEquals("updateDate")) == false)
|
||||
Create.Column("updateDate").OnTable("umbracoUser").AsDateTime().NotNullable().WithDefault(SystemMethods.CurrentDateTime).Do();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("umbracoUser") && x.ColumnName.InvariantEquals("emailConfirmedDate")) == false)
|
||||
Create.Column("emailConfirmedDate").OnTable("umbracoUser").AsDateTime().Nullable().Do();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("umbracoUser") && x.ColumnName.InvariantEquals("invitedDate")) == false)
|
||||
Create.Column("invitedDate").OnTable("umbracoUser").AsDateTime().Nullable().Do();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("umbracoUser") && x.ColumnName.InvariantEquals("avatar")) == false)
|
||||
Create.Column("avatar").OnTable("umbracoUser").AsString(500).Nullable().Do();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals("umbracoUser") && x.ColumnName.InvariantEquals("passwordConfig")) == false)
|
||||
{
|
||||
Create.Column("passwordConfig").OnTable("umbracoUser").AsString(500).Nullable().Do();
|
||||
//Check if we have a known config, we only want to store config for hashing
|
||||
var membershipProvider = MembershipProviderExtensions.GetUsersMembershipProvider();
|
||||
if (membershipProvider.PasswordFormat == MembershipPasswordFormat.Hashed)
|
||||
{
|
||||
var json = JsonConvert.SerializeObject(new { hashAlgorithm = Membership.HashAlgorithmType });
|
||||
Database.Execute("UPDATE umbracoUser SET passwordConfig = '" + json + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_8_0
|
||||
{
|
||||
internal class AddIndexToPropertyTypeAliasColumn : MigrationBase
|
||||
{
|
||||
public AddIndexToPropertyTypeAliasColumn(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var dbIndexes = SqlSyntax.GetDefinedIndexesDefinitions(Context.Database);
|
||||
|
||||
//make sure it doesn't already exist
|
||||
if (dbIndexes.Any(x => x.IndexName.InvariantEquals("IX_cmsPropertyTypeAlias")) == false)
|
||||
{
|
||||
//we can apply the index
|
||||
Create.Index("IX_cmsPropertyTypeAlias").OnTable(Constants.DatabaseSchema.Tables.PropertyType)
|
||||
.OnColumn("Alias")
|
||||
.Ascending().WithOptions().NonClustered()
|
||||
.Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_8_0
|
||||
{
|
||||
internal class AddInstructionCountColumn : MigrationBase
|
||||
{
|
||||
public AddInstructionCountColumn(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals(Constants.DatabaseSchema.Tables.CacheInstruction) && x.ColumnName.InvariantEquals("instructionCount")) == false)
|
||||
AddColumn<CacheInstructionDto>("instructionCount");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Persistence.Factories;
|
||||
using static Umbraco.Core.Persistence.NPocoSqlExtensions.Statics;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_8_0
|
||||
{
|
||||
internal class AddMediaVersionTable : MigrationBase
|
||||
{
|
||||
public AddMediaVersionTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
|
||||
|
||||
if (tables.InvariantContains(Constants.DatabaseSchema.Tables.MediaVersion)) return;
|
||||
|
||||
Create.Table<MediaVersionDto>().Do();
|
||||
MigrateMediaPaths();
|
||||
}
|
||||
|
||||
private void MigrateMediaPaths()
|
||||
{
|
||||
// this may not be the most efficient way to do it, compared to how it's done in v7, but this
|
||||
// migration should only run for v8 sites that are being developed, before v8 is released, so
|
||||
// no big sites and performances don't matter here - keep it simple
|
||||
|
||||
var sql = Sql()
|
||||
.Select<PropertyDataDto>(x => x.VarcharValue, x => x.TextValue)
|
||||
.AndSelect<ContentVersionDto>(x => Alias(x.Id, "versionId"))
|
||||
.From<PropertyDataDto>()
|
||||
.InnerJoin<PropertyTypeDto>().On<PropertyDataDto, PropertyTypeDto>((left, right) => left.PropertyTypeId == right.Id)
|
||||
.InnerJoin<ContentVersionDto>().On<PropertyDataDto, ContentVersionDto>((left, right) => left.VersionId == right.Id)
|
||||
.InnerJoin<NodeDto>().On<ContentVersionDto, NodeDto>((left, right) => left.NodeId == right.NodeId)
|
||||
.Where<PropertyTypeDto>(x => x.Alias == "umbracoFile")
|
||||
.Where<NodeDto>(x => x.NodeObjectType == Constants.ObjectTypes.Media);
|
||||
|
||||
var paths = new List<MediaVersionDto>();
|
||||
|
||||
//using QUERY = a db cursor, we won't load this all into memory first, just row by row
|
||||
foreach (var row in Database.Query<dynamic>(sql))
|
||||
{
|
||||
// if there's values then ensure there's a media path match and extract it
|
||||
string mediaPath = null;
|
||||
if (
|
||||
(row.varcharValue != null && ContentBaseFactory.TryMatch((string) row.varcharValue, out mediaPath))
|
||||
|| (row.textValue != null && ContentBaseFactory.TryMatch((string) row.textValue, out mediaPath)))
|
||||
{
|
||||
paths.Add(new MediaVersionDto
|
||||
{
|
||||
Id = (int) row.versionId,
|
||||
Path = mediaPath
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// bulk insert
|
||||
Database.BulkInsertRecords(paths);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_8_0
|
||||
{
|
||||
internal class AddTourDataUserColumn : MigrationBase
|
||||
{
|
||||
public AddTourDataUserColumn(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals(Constants.DatabaseSchema.Tables.User) && x.ColumnName.InvariantEquals("tourData")) == false)
|
||||
AddColumn<UserDto>("tourData");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_8_0
|
||||
{
|
||||
internal class AddUserLoginTable : MigrationBase
|
||||
{
|
||||
public AddUserLoginTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
|
||||
|
||||
if (tables.InvariantContains(Constants.DatabaseSchema.Tables.UserLogin) == false)
|
||||
{
|
||||
Create.Table<UserLoginDto>().Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_9_0
|
||||
{
|
||||
internal class AddIsSensitiveMemberTypeColumn : MigrationBase
|
||||
{
|
||||
public AddIsSensitiveMemberTypeColumn(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals(Constants.DatabaseSchema.Tables.MemberPropertyType) && x.ColumnName.InvariantEquals("isSensitive")) == false)
|
||||
AddColumn<MemberPropertyTypeDto>("isSensitive");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_9_0
|
||||
{
|
||||
internal class AddUmbracoAuditTable : MigrationBase
|
||||
{
|
||||
public AddUmbracoAuditTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
|
||||
|
||||
if (tables.InvariantContains(Constants.DatabaseSchema.Tables.AuditEntry))
|
||||
return;
|
||||
|
||||
Create.Table<AuditEntryDto>().Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_9_0
|
||||
{
|
||||
internal class AddUmbracoConsentTable : MigrationBase
|
||||
{
|
||||
public AddUmbracoConsentTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
|
||||
|
||||
if (tables.InvariantContains(Constants.DatabaseSchema.Tables.Consent))
|
||||
return;
|
||||
|
||||
Create.Table<ConsentDto>().Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
using System;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_7_9_0
|
||||
{
|
||||
internal class CreateSensitiveDataUserGroup : MigrationBase
|
||||
{
|
||||
public CreateSensitiveDataUserGroup(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var sql = Sql()
|
||||
.SelectCount()
|
||||
.From<UserGroupDto>()
|
||||
.Where<UserGroupDto>(x => x.Alias == Constants.Security.SensitiveDataGroupAlias);
|
||||
|
||||
var exists = Database.ExecuteScalar<int>(sql) > 0;
|
||||
if (exists) return;
|
||||
|
||||
var groupId = Database.Insert(Constants.DatabaseSchema.Tables.UserGroup, "id", new UserGroupDto { StartMediaId = -1, StartContentId = -1, Alias = Constants.Security.SensitiveDataGroupAlias, Name = "Sensitive data", DefaultPermissions = "", CreateDate = DateTime.Now, UpdateDate = DateTime.Now, Icon = "icon-lock" });
|
||||
Database.Insert(new User2UserGroupDto { UserGroupId = Convert.ToInt32(groupId), UserId = Constants.Security.SuperUserId }); // add super to sensitive data
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
{
|
||||
@@ -12,31 +13,10 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database);
|
||||
if (tables.InvariantContains("cmsContentNu")) return;
|
||||
|
||||
var textType = SqlSyntax.GetSpecialDbType(SpecialDbTypes.NTEXT);
|
||||
|
||||
Create.Table("cmsContentNu")
|
||||
.WithColumn("nodeId").AsInt32().NotNullable()
|
||||
.WithColumn("published").AsBoolean().NotNullable()
|
||||
.WithColumn("data").AsCustom(textType).NotNullable()
|
||||
.WithColumn("rv").AsInt64().NotNullable().WithDefaultValue(0)
|
||||
.Do();
|
||||
|
||||
Create.PrimaryKey("PK_cmsContentNu")
|
||||
.OnTable("cmsContentNu")
|
||||
.Columns(new[] { "nodeId", "published" })
|
||||
.Do();
|
||||
|
||||
Create.ForeignKey("FK_cmsContentNu_umbracoNode_id")
|
||||
.FromTable("cmsContentNu")
|
||||
.ForeignColumn("nodeId")
|
||||
.ToTable("umbracoNode")
|
||||
.PrimaryColumn("id")
|
||||
.OnDelete(Rule.Cascade)
|
||||
.OnUpdate(Rule.None)
|
||||
.Do();
|
||||
Create.Table<ContentNuDto>(true).Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
{
|
||||
public class AddLockTable : MigrationBase
|
||||
{
|
||||
public AddLockTable(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
var tables = SqlSyntax.GetTablesInSchema(Context.Database).ToArray();
|
||||
if (tables.InvariantContains("umbracoLock") == false)
|
||||
{
|
||||
Create.Table("umbracoLock")
|
||||
.WithColumn("id").AsInt32().PrimaryKey("PK_umbracoLock")
|
||||
.WithColumn("value").AsInt32().NotNullable()
|
||||
.WithColumn("name").AsString(64).NotNullable()
|
||||
.Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
{
|
||||
public class AddUserLoginDtoDateIndex : MigrationBase
|
||||
{
|
||||
public AddUserLoginDtoDateIndex(IMigrationContext context)
|
||||
: base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
if (!IndexExists("IX_umbracoUserLogin_lastValidatedUtc"))
|
||||
Create.Index("IX_umbracoUserLogin_lastValidatedUtc")
|
||||
.OnTable(UserLoginDto.TableName)
|
||||
.OnColumn("lastValidatedUtc")
|
||||
.Ascending()
|
||||
.WithOptions().NonClustered()
|
||||
.Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,8 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
Create.Table<ContentVersionCultureVariationDto>().Do();
|
||||
Create.Table<DocumentCultureVariationDto>().Do();
|
||||
Create.Table<ContentVersionCultureVariationDto>(true).Do();
|
||||
Create.Table<DocumentCultureVariationDto>(true).Do();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
var sqlDataTypes = Sql()
|
||||
.Select<DataTypeDto>()
|
||||
.From<DataTypeDto>()
|
||||
.Where<DataTypeDto>(x => x.EditorAlias == "Umbraco.RelatedLinks"
|
||||
|| x.EditorAlias == "Umbraco.RelatedLinks2");
|
||||
.Where<DataTypeDto>(x => x.EditorAlias == Constants.PropertyEditors.Legacy.Aliases.RelatedLinks
|
||||
|| x.EditorAlias == Constants.PropertyEditors.Legacy.Aliases.RelatedLinks2);
|
||||
|
||||
var dataTypes = Database.Fetch<DataTypeDto>(sqlDataTypes);
|
||||
var dataTypeIds = dataTypes.Select(x => x.NodeId).ToList();
|
||||
@@ -50,10 +50,10 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
var properties = Database.Fetch<PropertyDataDto>(sqlPropertyData);
|
||||
|
||||
// Create a Multi URL Picker datatype for the converted RelatedLinks data
|
||||
|
||||
|
||||
foreach (var property in properties)
|
||||
{
|
||||
var value = property.Value.ToString();
|
||||
var value = property.Value?.ToString();
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
continue;
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
Name = relatedLink.Caption,
|
||||
Target = relatedLink.NewWindow ? "_blank" : null,
|
||||
Udi = udi,
|
||||
// Should only have a URL if it's an external link otherwise it wil be a UDI
|
||||
// Should only have a URL if it's an external link otherwise it wil be a UDI
|
||||
Url = relatedLink.IsInternal == false ? relatedLink.Link : null
|
||||
};
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
Database.Update(property);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,28 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Newtonsoft.Json;
|
||||
using NPoco;
|
||||
using Umbraco.Core.Migrations.Install;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_8_0_0.DataTypes;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
{
|
||||
|
||||
public class DataTypeMigration : MigrationBase
|
||||
{
|
||||
public DataTypeMigration(IMigrationContext context)
|
||||
private readonly PreValueMigratorCollection _preValueMigrators;
|
||||
private readonly PropertyEditorCollection _propertyEditors;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private static readonly ISet<string> LegacyAliases = new HashSet<string>()
|
||||
{
|
||||
Constants.PropertyEditors.Legacy.Aliases.Date,
|
||||
Constants.PropertyEditors.Legacy.Aliases.Textbox,
|
||||
Constants.PropertyEditors.Legacy.Aliases.ContentPicker2,
|
||||
Constants.PropertyEditors.Legacy.Aliases.MediaPicker2,
|
||||
Constants.PropertyEditors.Legacy.Aliases.MemberPicker2,
|
||||
Constants.PropertyEditors.Legacy.Aliases.RelatedLinks2,
|
||||
Constants.PropertyEditors.Legacy.Aliases.TextboxMultiple,
|
||||
Constants.PropertyEditors.Legacy.Aliases.MultiNodeTreePicker2,
|
||||
};
|
||||
|
||||
public DataTypeMigration(IMigrationContext context, PreValueMigratorCollection preValueMigrators, PropertyEditorCollection propertyEditors, ILogger logger)
|
||||
: base(context)
|
||||
{ }
|
||||
{
|
||||
_preValueMigrators = preValueMigrators;
|
||||
_propertyEditors = propertyEditors;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
// delete *all* keys and indexes - because of FKs
|
||||
Delete.KeysAndIndexes().Do();
|
||||
|
||||
// drop and create columns
|
||||
Delete.Column("pk").FromTable("cmsDataType").Do();
|
||||
|
||||
@@ -31,21 +49,17 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
|
||||
// create column
|
||||
AddColumn<DataTypeDto>(Constants.DatabaseSchema.Tables.DataType, "config");
|
||||
Execute.Sql(Sql().Update<DataTypeDto>(u => u.Set(x => x.Configuration, string.Empty)).SQL).Do();
|
||||
|
||||
// re-create *all* keys and indexes
|
||||
foreach (var x in DatabaseSchemaCreator.OrderedTables)
|
||||
Create.KeysAndIndexes(x).Do();
|
||||
Execute.Sql(Sql().Update<DataTypeDto>(u => u.Set(x => x.Configuration, string.Empty))).Do();
|
||||
|
||||
// renames
|
||||
Execute.Sql(Sql()
|
||||
.Update<DataTypeDto>(u => u.Set(x => x.EditorAlias, "Umbraco.ColorPicker"))
|
||||
.Where<DataTypeDto>(x => x.EditorAlias == "Umbraco.ColorPickerAlias").SQL).Do();
|
||||
.Where<DataTypeDto>(x => x.EditorAlias == "Umbraco.ColorPickerAlias")).Do();
|
||||
|
||||
// from preValues to configuration...
|
||||
var sql = Sql()
|
||||
.Select<DataTypeDto>()
|
||||
.AndSelect<PreValueDto>(x => x.Alias, x => x.SortOrder, x => x.Value)
|
||||
.AndSelect<PreValueDto>(x => x.Id, x => x.Alias, x => x.SortOrder, x => x.Value)
|
||||
.From<DataTypeDto>()
|
||||
.InnerJoin<PreValueDto>().On<DataTypeDto, PreValueDto>((left, right) => left.NodeId == right.NodeId)
|
||||
.OrderBy<DataTypeDto>(x => x.NodeId)
|
||||
@@ -60,43 +74,52 @@ namespace Umbraco.Core.Migrations.Upgrade.V_8_0_0
|
||||
.From<DataTypeDto>()
|
||||
.Where<DataTypeDto>(x => x.NodeId == group.Key)).First();
|
||||
|
||||
var aliases = group.Select(x => x.Alias).Distinct().ToArray();
|
||||
if (aliases.Length == 1 && string.IsNullOrWhiteSpace(aliases[0]))
|
||||
// migrate the preValues to configuration
|
||||
var migrator = _preValueMigrators.GetMigrator(dataType.EditorAlias) ?? new DefaultPreValueMigrator();
|
||||
var config = migrator.GetConfiguration(dataType.NodeId, dataType.EditorAlias, group.ToDictionary(x => x.Alias, x => x));
|
||||
var json = JsonConvert.SerializeObject(config);
|
||||
|
||||
// validate - and kill the migration if it fails
|
||||
var newAlias = migrator.GetNewAlias(dataType.EditorAlias);
|
||||
if (newAlias == null)
|
||||
{
|
||||
// array-based prevalues
|
||||
var values = new Dictionary<string, object> { ["values"] = group.OrderBy(x => x.SortOrder).Select(x => x.Value).ToArray() };
|
||||
dataType.Configuration = JsonConvert.SerializeObject(values);
|
||||
if (!LegacyAliases.Contains(dataType.EditorAlias))
|
||||
{
|
||||
_logger.Warn<DataTypeMigration>(
|
||||
"Skipping validation of configuration for data type {NodeId} : {EditorAlias}."
|
||||
+ " Please ensure that the configuration is valid. The site may fail to start and / or load data types and run.",
|
||||
dataType.NodeId, dataType.EditorAlias);
|
||||
}
|
||||
}
|
||||
else if (!_propertyEditors.TryGet(newAlias, out var propertyEditor))
|
||||
{
|
||||
if (!LegacyAliases.Contains(newAlias))
|
||||
{
|
||||
_logger.Warn<DataTypeMigration>("Skipping validation of configuration for data type {NodeId} : {NewEditorAlias} (was: {EditorAlias})"
|
||||
+ " because no property editor with that alias was found."
|
||||
+ " Please ensure that the configuration is valid. The site may fail to start and / or load data types and run.",
|
||||
dataType.NodeId, newAlias, dataType.EditorAlias);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// assuming we don't want to fall back to array
|
||||
if (aliases.Length != group.Count() || aliases.Any(string.IsNullOrWhiteSpace))
|
||||
throw new InvalidOperationException($"Cannot migrate datatype w/ id={dataType.NodeId} preValues: duplicate or null/empty alias.");
|
||||
|
||||
// dictionary-base prevalues
|
||||
var values = group.ToDictionary(x => x.Alias, x => x.Value);
|
||||
dataType.Configuration = JsonConvert.SerializeObject(values);
|
||||
var configEditor = propertyEditor.GetConfigurationEditor();
|
||||
try
|
||||
{
|
||||
var _ = configEditor.FromDatabase(json);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.Warn<DataTypeMigration>(e, "Failed to validate configuration for data type {NodeId} : {NewEditorAlias} (was: {EditorAlias})."
|
||||
+ " Please fix the configuration and ensure it is valid. The site may fail to start and / or load data types and run.",
|
||||
dataType.NodeId, newAlias, dataType.EditorAlias);
|
||||
}
|
||||
}
|
||||
|
||||
// update
|
||||
dataType.Configuration = JsonConvert.SerializeObject(config);
|
||||
Database.Update(dataType);
|
||||
}
|
||||
}
|
||||
|
||||
[TableName("cmsDataTypePreValues")]
|
||||
[ExplicitColumns]
|
||||
public class PreValueDto
|
||||
{
|
||||
[Column("datatypeNodeId")]
|
||||
public int NodeId { get; set; }
|
||||
|
||||
[Column("alias")]
|
||||
public string Alias { get; set; }
|
||||
|
||||
[Column("sortorder")]
|
||||
public int SortOrder { get; set; }
|
||||
|
||||
[Column("value")]
|
||||
public string Value { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user