diff --git a/Makefile b/Makefile index f1b6790dc507..4ca346c63e6c 100644 --- a/Makefile +++ b/Makefile @@ -100,7 +100,8 @@ LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(G LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64 -GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/models/migrations code.gitea.io/gitea/tests/integration/migration-test code.gitea.io/gitea/tests code.gitea.io/gitea/tests/integration code.gitea.io/gitea/tests/e2e,$(shell $(GO) list ./... | grep -v /vendor/)) +GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/tests/integration/migration-test code.gitea.io/gitea/tests code.gitea.io/gitea/tests/integration code.gitea.io/gitea/tests/e2e,$(shell $(GO) list ./... | grep -v /vendor/)) +GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list code.gitea.io/gitea/models/migrations/...) code.gitea.io/gitea/tests/integration/migration-test code.gitea.io/gitea/tests code.gitea.io/gitea/tests/integration code.gitea.io/gitea/tests/e2e,$(shell $(GO) list ./... | grep -v /vendor/)) FOMANTIC_WORK_DIR := web_src/fomantic @@ -366,7 +367,7 @@ test: test-frontend test-backend .PHONY: test-backend test-backend: @echo "Running go test with $(GOTESTFLAGS) -tags '$(TEST_TAGS)'..." - @$(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' $(GO_PACKAGES) + @$(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' $(GO_TEST_PACKAGES) .PHONY: test-frontend test-frontend: node_modules @@ -387,7 +388,7 @@ test-check: .PHONY: test\#% test\#%: @echo "Running go test with -tags '$(TEST_TAGS)'..." - @$(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -run $(subst .,/,$*) $(GO_PACKAGES) + @$(GO) test $(GOTESTFLAGS) -tags='$(TEST_TAGS)' -run $(subst .,/,$*) $(GO_TEST_PACKAGES) .PHONY: coverage coverage: @@ -398,7 +399,7 @@ coverage: .PHONY: unit-test-coverage unit-test-coverage: @echo "Running unit-test-coverage $(GOTESTFLAGS) -tags '$(TEST_TAGS)'..." - @$(GO) test $(GOTESTFLAGS) -timeout=20m -tags='$(TEST_TAGS)' -cover -coverprofile coverage.out $(GO_PACKAGES) && echo "\n==>\033[32m Ok\033[m\n" || exit 1 + @$(GO) test $(GOTESTFLAGS) -timeout=20m -tags='$(TEST_TAGS)' -cover -coverprofile coverage.out $(GO_TEST_PACKAGES) && echo "\n==>\033[32m Ok\033[m\n" || exit 1 .PHONY: tidy tidy: @@ -442,14 +443,7 @@ test-sqlite\#%: integrations.sqlite.test generate-ini-sqlite GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./integrations.sqlite.test -test.run $(subst .,/,$*) .PHONY: test-sqlite-migration -test-sqlite-migration: migrations.sqlite.test migrations.individual.sqlite.test generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./migrations.sqlite.test - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./migrations.individual.sqlite.test - -.PHONY: test-sqlite-migration\#% -test-sqlite-migration\#%: migrations.sqlite.test migrations.individual.sqlite.test generate-ini-sqlite - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./migrations.individual.sqlite.test -test.run $(subst .,/,$*) - +test-sqlite-migration: migrations.sqlite.test migrations.individual.sqlite.test generate-ini-mysql: sed -e 's|{{TEST_MYSQL_HOST}}|${TEST_MYSQL_HOST}|g' \ @@ -470,9 +464,7 @@ test-mysql\#%: integrations.mysql.test generate-ini-mysql GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./integrations.mysql.test -test.run $(subst .,/,$*) .PHONY: test-mysql-migration -test-mysql-migration: migrations.mysql.test migrations.individual.mysql.test generate-ini-mysql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./migrations.mysql.test - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./migrations.individual.mysql.test +test-mysql-migration: migrations.mysql.test migrations.individual.mysql.test generate-ini-mysql8: sed -e 's|{{TEST_MYSQL8_HOST}}|${TEST_MYSQL8_HOST}|g' \ @@ -493,9 +485,7 @@ test-mysql8\#%: integrations.mysql8.test generate-ini-mysql8 GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini ./integrations.mysql8.test -test.run $(subst .,/,$*) .PHONY: test-mysql8-migration -test-mysql8-migration: migrations.mysql8.test migrations.individual.mysql8.test generate-ini-mysql8 - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini ./migrations.mysql8.test - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini ./migrations.individual.mysql8.test +test-mysql8-migration: migrations.mysql8.test migrations.individual.mysql8.test generate-ini-pgsql: sed -e 's|{{TEST_PGSQL_HOST}}|${TEST_PGSQL_HOST}|g' \ @@ -517,9 +507,7 @@ test-pgsql\#%: integrations.pgsql.test generate-ini-pgsql GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./integrations.pgsql.test -test.run $(subst .,/,$*) .PHONY: test-pgsql-migration -test-pgsql-migration: migrations.pgsql.test migrations.individual.pgsql.test generate-ini-pgsql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./migrations.pgsql.test - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./migrations.individual.pgsql.test +test-pgsql-migration: migrations.pgsql.test migrations.individual.pgsql.test generate-ini-mssql: sed -e 's|{{TEST_MSSQL_HOST}}|${TEST_MSSQL_HOST}|g' \ @@ -540,9 +528,7 @@ test-mssql\#%: integrations.mssql.test generate-ini-mssql GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./integrations.mssql.test -test.run $(subst .,/,$*) .PHONY: test-mssql-migration -test-mssql-migration: migrations.mssql.test migrations.individual.mssql.test generate-ini-mssql - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./migrations.mssql.test -test.failfast - GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./migrations.individual.mssql.test -test.failfast +test-mssql-migration: migrations.mssql.test migrations.individual.mssql.test .PHONY: playwright playwright: $(PLAYWRIGHT_DIR) @@ -637,50 +623,82 @@ integrations.sqlite.test: git-check $(GO_SOURCES) $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -o integrations.sqlite.test -tags '$(TEST_TAGS)' integrations.cover.test: git-check $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -coverpkg $(shell echo $(GO_PACKAGES) | tr ' ' ',') -o integrations.cover.test + $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -coverpkg $(shell echo $(GO_TEST_PACKAGES) | tr ' ' ',') -o integrations.cover.test integrations.cover.sqlite.test: git-check $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -coverpkg $(shell echo $(GO_PACKAGES) | tr ' ' ',') -o integrations.cover.sqlite.test -tags '$(TEST_TAGS)' + $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration -coverpkg $(shell echo $(GO_TEST_PACKAGES) | tr ' ' ',') -o integrations.cover.sqlite.test -tags '$(TEST_TAGS)' .PHONY: migrations.mysql.test -migrations.mysql.test: $(GO_SOURCES) +migrations.mysql.test: $(GO_SOURCES) generate-ini-mysql $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.mysql.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini ./migrations.mysql.test .PHONY: migrations.mysql8.test -migrations.mysql8.test: $(GO_SOURCES) +migrations.mysql8.test: $(GO_SOURCES) generate-ini-mysql8 $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.mysql8.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini ./migrations.mysql8.test .PHONY: migrations.pgsql.test -migrations.pgsql.test: $(GO_SOURCES) +migrations.pgsql.test: $(GO_SOURCES) generate-ini-pgsql $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.pgsql.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini ./migrations.pgsql.test .PHONY: migrations.mssql.test -migrations.mssql.test: $(GO_SOURCES) +migrations.mssql.test: $(GO_SOURCES) generate-ini-mssql $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.mssql.test + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini ./migrations.mssql.test .PHONY: migrations.sqlite.test -migrations.sqlite.test: $(GO_SOURCES) +migrations.sqlite.test: $(GO_SOURCES) generate-ini-sqlite $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/integration/migration-test -o migrations.sqlite.test -tags '$(TEST_TAGS)' + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini ./migrations.sqlite.test .PHONY: migrations.individual.mysql.test migrations.individual.mysql.test: $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/models/migrations -o migrations.individual.mysql.test + for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/...); do \ + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg; \ + done .PHONY: migrations.individual.mysql8.test migrations.individual.mysql8.test: $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/models/migrations -o migrations.individual.mysql8.test + for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/...); do \ + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mysql8.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg; \ + done + +.PHONY: migrations.individual.mysql8.test\#% +migrations.individual.sqlite.test\#%: $(GO_SOURCES) generate-ini-sqlite + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$* .PHONY: migrations.individual.pgsql.test migrations.individual.pgsql.test: $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/models/migrations -o migrations.individual.pgsql.test + for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/...); do \ + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg; \ + done + +.PHONY: migrations.individual.pgsql.test\#% +migrations.individual.pgsql.test\#%: $(GO_SOURCES) generate-ini-pgsql + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/pgsql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$* + .PHONY: migrations.individual.mssql.test -migrations.individual.mssql.test: $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/models/migrations -o migrations.individual.mssql.test +migrations.individual.mssql.test: $(GO_SOURCES) generate-ini-mssql + for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/...); do \ + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg -test.failfast; \ + done + +.PHONY: migrations.individual.mssql.test\#% +migrations.individual.mssql.test\#%: $(GO_SOURCES) generate-ini-mssql + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/mssql.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$* .PHONY: migrations.individual.sqlite.test -migrations.individual.sqlite.test: $(GO_SOURCES) - $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/models/migrations -o migrations.individual.sqlite.test -tags '$(TEST_TAGS)' +migrations.individual.sqlite.test: $(GO_SOURCES) generate-ini-sqlite + for pkg in $(shell $(GO) list code.gitea.io/gitea/models/migrations/...); do \ + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' $$pkg; \ + done + +.PHONY: migrations.individual.sqlite.test\#% +migrations.individual.sqlite.test\#%: $(GO_SOURCES) generate-ini-sqlite + GITEA_ROOT="$(CURDIR)" GITEA_CONF=tests/sqlite.ini $(GO) test $(GOTESTFLAGS) -tags '$(TEST_TAGS)' code.gitea.io/gitea/models/migrations/$* e2e.mysql.test: $(GO_SOURCES) $(GO) test $(GOTESTFLAGS) -c code.gitea.io/gitea/tests/e2e -o e2e.mysql.test diff --git a/assets/go-licenses.json b/assets/go-licenses.json index db0b00865edb..c4b62475fd4b 100644 --- a/assets/go-licenses.json +++ b/assets/go-licenses.json @@ -244,6 +244,11 @@ "path": "github.com/cpuguy83/go-md2man/v2/md2man/LICENSE.md", "licenseText": "The MIT License (MIT)\n\nCopyright (c) 2014 Brian Goff\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" }, + { + "name": "github.com/davecgh/go-spew/spew", + "path": "github.com/davecgh/go-spew/spew/LICENSE", + "licenseText": "ISC License\n\nCopyright (c) 2012-2016 Dave Collins \u003cdave@davec.name\u003e\n\nPermission to use, copy, modify, and/or distribute this software for any\npurpose with or without fee is hereby granted, provided that the above\ncopyright notice and this permission notice appear in all copies.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES\nWITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR\nANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\nWHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN\nACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF\nOR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.\n" + }, { "name": "github.com/denisenkom/go-mssqldb", "path": "github.com/denisenkom/go-mssqldb/LICENSE.txt", @@ -369,6 +374,11 @@ "path": "github.com/go-sql-driver/mysql/LICENSE", "licenseText": "Mozilla Public License Version 2.0\n==================================\n\n1. Definitions\n--------------\n\n1.1. \"Contributor\"\n means each individual or legal entity that creates, contributes to\n the creation of, or owns Covered Software.\n\n1.2. \"Contributor Version\"\n means the combination of the Contributions of others (if any) used\n by a Contributor and that particular Contributor's Contribution.\n\n1.3. \"Contribution\"\n means Covered Software of a particular Contributor.\n\n1.4. \"Covered Software\"\n means Source Code Form to which the initial Contributor has attached\n the notice in Exhibit A, the Executable Form of such Source Code\n Form, and Modifications of such Source Code Form, in each case\n including portions thereof.\n\n1.5. \"Incompatible With Secondary Licenses\"\n means\n\n (a) that the initial Contributor has attached the notice described\n in Exhibit B to the Covered Software; or\n\n (b) that the Covered Software was made available under the terms of\n version 1.1 or earlier of the License, but not also under the\n terms of a Secondary License.\n\n1.6. \"Executable Form\"\n means any form of the work other than Source Code Form.\n\n1.7. \"Larger Work\"\n means a work that combines Covered Software with other material, in \n a separate file or files, that is not Covered Software.\n\n1.8. \"License\"\n means this document.\n\n1.9. \"Licensable\"\n means having the right to grant, to the maximum extent possible,\n whether at the time of the initial grant or subsequently, any and\n all of the rights conveyed by this License.\n\n1.10. \"Modifications\"\n means any of the following:\n\n (a) any file in Source Code Form that results from an addition to,\n deletion from, or modification of the contents of Covered\n Software; or\n\n (b) any new file in Source Code Form that contains any Covered\n Software.\n\n1.11. \"Patent Claims\" of a Contributor\n means any patent claim(s), including without limitation, method,\n process, and apparatus claims, in any patent Licensable by such\n Contributor that would be infringed, but for the grant of the\n License, by the making, using, selling, offering for sale, having\n made, import, or transfer of either its Contributions or its\n Contributor Version.\n\n1.12. \"Secondary License\"\n means either the GNU General Public License, Version 2.0, the GNU\n Lesser General Public License, Version 2.1, the GNU Affero General\n Public License, Version 3.0, or any later versions of those\n licenses.\n\n1.13. \"Source Code Form\"\n means the form of the work preferred for making modifications.\n\n1.14. \"You\" (or \"Your\")\n means an individual or a legal entity exercising rights under this\n License. For legal entities, \"You\" includes any entity that\n controls, is controlled by, or is under common control with You. For\n purposes of this definition, \"control\" means (a) the power, direct\n or indirect, to cause the direction or management of such entity,\n whether by contract or otherwise, or (b) ownership of more than\n fifty percent (50%) of the outstanding shares or beneficial\n ownership of such entity.\n\n2. License Grants and Conditions\n--------------------------------\n\n2.1. Grants\n\nEach Contributor hereby grants You a world-wide, royalty-free,\nnon-exclusive license:\n\n(a) under intellectual property rights (other than patent or trademark)\n Licensable by such Contributor to use, reproduce, make available,\n modify, display, perform, distribute, and otherwise exploit its\n Contributions, either on an unmodified basis, with Modifications, or\n as part of a Larger Work; and\n\n(b) under Patent Claims of such Contributor to make, use, sell, offer\n for sale, have made, import, and otherwise transfer either its\n Contributions or its Contributor Version.\n\n2.2. Effective Date\n\nThe licenses granted in Section 2.1 with respect to any Contribution\nbecome effective for each Contribution on the date the Contributor first\ndistributes such Contribution.\n\n2.3. Limitations on Grant Scope\n\nThe licenses granted in this Section 2 are the only rights granted under\nthis License. No additional rights or licenses will be implied from the\ndistribution or licensing of Covered Software under this License.\nNotwithstanding Section 2.1(b) above, no patent license is granted by a\nContributor:\n\n(a) for any code that a Contributor has removed from Covered Software;\n or\n\n(b) for infringements caused by: (i) Your and any other third party's\n modifications of Covered Software, or (ii) the combination of its\n Contributions with other software (except as part of its Contributor\n Version); or\n\n(c) under Patent Claims infringed by Covered Software in the absence of\n its Contributions.\n\nThis License does not grant any rights in the trademarks, service marks,\nor logos of any Contributor (except as may be necessary to comply with\nthe notice requirements in Section 3.4).\n\n2.4. Subsequent Licenses\n\nNo Contributor makes additional grants as a result of Your choice to\ndistribute the Covered Software under a subsequent version of this\nLicense (see Section 10.2) or under the terms of a Secondary License (if\npermitted under the terms of Section 3.3).\n\n2.5. Representation\n\nEach Contributor represents that the Contributor believes its\nContributions are its original creation(s) or it has sufficient rights\nto grant the rights to its Contributions conveyed by this License.\n\n2.6. Fair Use\n\nThis License is not intended to limit any rights You have under\napplicable copyright doctrines of fair use, fair dealing, or other\nequivalents.\n\n2.7. Conditions\n\nSections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted\nin Section 2.1.\n\n3. Responsibilities\n-------------------\n\n3.1. Distribution of Source Form\n\nAll distribution of Covered Software in Source Code Form, including any\nModifications that You create or to which You contribute, must be under\nthe terms of this License. You must inform recipients that the Source\nCode Form of the Covered Software is governed by the terms of this\nLicense, and how they can obtain a copy of this License. You may not\nattempt to alter or restrict the recipients' rights in the Source Code\nForm.\n\n3.2. Distribution of Executable Form\n\nIf You distribute Covered Software in Executable Form then:\n\n(a) such Covered Software must also be made available in Source Code\n Form, as described in Section 3.1, and You must inform recipients of\n the Executable Form how they can obtain a copy of such Source Code\n Form by reasonable means in a timely manner, at a charge no more\n than the cost of distribution to the recipient; and\n\n(b) You may distribute such Executable Form under the terms of this\n License, or sublicense it under different terms, provided that the\n license for the Executable Form does not attempt to limit or alter\n the recipients' rights in the Source Code Form under this License.\n\n3.3. Distribution of a Larger Work\n\nYou may create and distribute a Larger Work under terms of Your choice,\nprovided that You also comply with the requirements of this License for\nthe Covered Software. If the Larger Work is a combination of Covered\nSoftware with a work governed by one or more Secondary Licenses, and the\nCovered Software is not Incompatible With Secondary Licenses, this\nLicense permits You to additionally distribute such Covered Software\nunder the terms of such Secondary License(s), so that the recipient of\nthe Larger Work may, at their option, further distribute the Covered\nSoftware under the terms of either this License or such Secondary\nLicense(s).\n\n3.4. Notices\n\nYou may not remove or alter the substance of any license notices\n(including copyright notices, patent notices, disclaimers of warranty,\nor limitations of liability) contained within the Source Code Form of\nthe Covered Software, except that You may alter any license notices to\nthe extent required to remedy known factual inaccuracies.\n\n3.5. Application of Additional Terms\n\nYou may choose to offer, and to charge a fee for, warranty, support,\nindemnity or liability obligations to one or more recipients of Covered\nSoftware. However, You may do so only on Your own behalf, and not on\nbehalf of any Contributor. You must make it absolutely clear that any\nsuch warranty, support, indemnity, or liability obligation is offered by\nYou alone, and You hereby agree to indemnify every Contributor for any\nliability incurred by such Contributor as a result of warranty, support,\nindemnity or liability terms You offer. You may include additional\ndisclaimers of warranty and limitations of liability specific to any\njurisdiction.\n\n4. Inability to Comply Due to Statute or Regulation\n---------------------------------------------------\n\nIf it is impossible for You to comply with any of the terms of this\nLicense with respect to some or all of the Covered Software due to\nstatute, judicial order, or regulation then You must: (a) comply with\nthe terms of this License to the maximum extent possible; and (b)\ndescribe the limitations and the code they affect. Such description must\nbe placed in a text file included with all distributions of the Covered\nSoftware under this License. Except to the extent prohibited by statute\nor regulation, such description must be sufficiently detailed for a\nrecipient of ordinary skill to be able to understand it.\n\n5. Termination\n--------------\n\n5.1. The rights granted under this License will terminate automatically\nif You fail to comply with any of its terms. However, if You become\ncompliant, then the rights granted under this License from a particular\nContributor are reinstated (a) provisionally, unless and until such\nContributor explicitly and finally terminates Your grants, and (b) on an\nongoing basis, if such Contributor fails to notify You of the\nnon-compliance by some reasonable means prior to 60 days after You have\ncome back into compliance. Moreover, Your grants from a particular\nContributor are reinstated on an ongoing basis if such Contributor\nnotifies You of the non-compliance by some reasonable means, this is the\nfirst time You have received notice of non-compliance with this License\nfrom such Contributor, and You become compliant prior to 30 days after\nYour receipt of the notice.\n\n5.2. If You initiate litigation against any entity by asserting a patent\ninfringement claim (excluding declaratory judgment actions,\ncounter-claims, and cross-claims) alleging that a Contributor Version\ndirectly or indirectly infringes any patent, then the rights granted to\nYou by any and all Contributors for the Covered Software under Section\n2.1 of this License shall terminate.\n\n5.3. In the event of termination under Sections 5.1 or 5.2 above, all\nend user license agreements (excluding distributors and resellers) which\nhave been validly granted by You or Your distributors under this License\nprior to termination shall survive termination.\n\n************************************************************************\n* *\n* 6. Disclaimer of Warranty *\n* ------------------------- *\n* *\n* Covered Software is provided under this License on an \"as is\" *\n* basis, without warranty of any kind, either expressed, implied, or *\n* statutory, including, without limitation, warranties that the *\n* Covered Software is free of defects, merchantable, fit for a *\n* particular purpose or non-infringing. The entire risk as to the *\n* quality and performance of the Covered Software is with You. *\n* Should any Covered Software prove defective in any respect, You *\n* (not any Contributor) assume the cost of any necessary servicing, *\n* repair, or correction. This disclaimer of warranty constitutes an *\n* essential part of this License. No use of any Covered Software is *\n* authorized under this License except under this disclaimer. *\n* *\n************************************************************************\n\n************************************************************************\n* *\n* 7. Limitation of Liability *\n* -------------------------- *\n* *\n* Under no circumstances and under no legal theory, whether tort *\n* (including negligence), contract, or otherwise, shall any *\n* Contributor, or anyone who distributes Covered Software as *\n* permitted above, be liable to You for any direct, indirect, *\n* special, incidental, or consequential damages of any character *\n* including, without limitation, damages for lost profits, loss of *\n* goodwill, work stoppage, computer failure or malfunction, or any *\n* and all other commercial damages or losses, even if such party *\n* shall have been informed of the possibility of such damages. This *\n* limitation of liability shall not apply to liability for death or *\n* personal injury resulting from such party's negligence to the *\n* extent applicable law prohibits such limitation. Some *\n* jurisdictions do not allow the exclusion or limitation of *\n* incidental or consequential damages, so this exclusion and *\n* limitation may not apply to You. *\n* *\n************************************************************************\n\n8. Litigation\n-------------\n\nAny litigation relating to this License may be brought only in the\ncourts of a jurisdiction where the defendant maintains its principal\nplace of business and such litigation shall be governed by laws of that\njurisdiction, without reference to its conflict-of-law provisions.\nNothing in this Section shall prevent a party's ability to bring\ncross-claims or counter-claims.\n\n9. Miscellaneous\n----------------\n\nThis License represents the complete agreement concerning the subject\nmatter hereof. If any provision of this License is held to be\nunenforceable, such provision shall be reformed only to the extent\nnecessary to make it enforceable. Any law or regulation which provides\nthat the language of a contract shall be construed against the drafter\nshall not be used to construe this License against a Contributor.\n\n10. Versions of the License\n---------------------------\n\n10.1. New Versions\n\nMozilla Foundation is the license steward. Except as provided in Section\n10.3, no one other than the license steward has the right to modify or\npublish new versions of this License. Each version will be given a\ndistinguishing version number.\n\n10.2. Effect of New Versions\n\nYou may distribute the Covered Software under the terms of the version\nof the License under which You originally received the Covered Software,\nor under the terms of any subsequent version published by the license\nsteward.\n\n10.3. Modified Versions\n\nIf you create software not governed by this License, and you want to\ncreate a new license for such software, you may create and use a\nmodified version of this License if you rename the license and remove\nany references to the name of the license steward (except to note that\nsuch modified license differs from this License).\n\n10.4. Distributing Source Code Form that is Incompatible With Secondary\nLicenses\n\nIf You choose to distribute Source Code Form that is Incompatible With\nSecondary Licenses under the terms of this version of the License, the\nnotice described in Exhibit B of this License must be attached.\n\nExhibit A - Source Code Form License Notice\n-------------------------------------------\n\n This Source Code Form is subject to the terms of the Mozilla Public\n License, v. 2.0. If a copy of the MPL was not distributed with this\n file, You can obtain one at http://mozilla.org/MPL/2.0/.\n\nIf it is not possible or desirable to put the notice in a particular\nfile, then You may include the notice in a location (such as a LICENSE\nfile in a relevant directory) where a recipient would be likely to look\nfor such a notice.\n\nYou may add additional accurate notices of copyright ownership.\n\nExhibit B - \"Incompatible With Secondary Licenses\" Notice\n---------------------------------------------------------\n\n This Source Code Form is \"Incompatible With Secondary Licenses\", as\n defined by the Mozilla Public License, v. 2.0.\n" }, + { + "name": "github.com/go-testfixtures/testfixtures/v3", + "path": "github.com/go-testfixtures/testfixtures/v3/LICENSE", + "licenseText": "The MIT License (MIT)\n\nCopyright (c) 2016 Andrey Nering\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, { "name": "github.com/gobwas/glob", "path": "github.com/gobwas/glob/LICENSE", @@ -689,6 +699,11 @@ "path": "github.com/pkg/errors/LICENSE", "licenseText": "Copyright (c) 2015, Dave Cheney \u003cdave@cheney.net\u003e\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" }, + { + "name": "github.com/pmezard/go-difflib/difflib", + "path": "github.com/pmezard/go-difflib/difflib/LICENSE", + "licenseText": "Copyright (c) 2013, Patrick Mezard\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n Redistributions in binary form must reproduce the above copyright\nnotice, this list of conditions and the following disclaimer in the\ndocumentation and/or other materials provided with the distribution.\n The names of its contributors may not be used to endorse or promote\nproducts derived from this software without specific prior written\npermission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\nIS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED\nTO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A\nPARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nHOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\nTO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\nNEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, { "name": "github.com/pquerna/otp", "path": "github.com/pquerna/otp/LICENSE", @@ -744,6 +759,11 @@ "path": "github.com/ssor/bom/LICENSE", "licenseText": "MIT License\n\nCopyright (c) 2017 Asher\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" }, + { + "name": "github.com/stretchr/testify/assert", + "path": "github.com/stretchr/testify/assert/LICENSE", + "licenseText": "MIT License\n\nCopyright (c) 2012-2020 Mat Ryer, Tyler Bunnell and contributors.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n" + }, { "name": "github.com/syndtr/goleveldb/leveldb", "path": "github.com/syndtr/goleveldb/leveldb/LICENSE", diff --git a/cmd/doctor.go b/cmd/doctor.go index a1184840522f..d05a0a98d7ae 100644 --- a/cmd/doctor.go +++ b/cmd/doctor.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/migrations" + migrate_base "code.gitea.io/gitea/models/migrations/base" "code.gitea.io/gitea/modules/doctor" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -114,7 +115,7 @@ func runRecreateTable(ctx *cli.Context) error { if err != nil { return err } - recreateTables := migrations.RecreateTables(beans...) + recreateTables := migrate_base.RecreateTables(beans...) return db.InitEngineWithMigration(stdCtx, func(x *xorm.Engine) error { if err := migrations.EnsureUpToDate(x); err != nil { diff --git a/models/migrations/base/db.go b/models/migrations/base/db.go new file mode 100644 index 000000000000..5466b76220a3 --- /dev/null +++ b/models/migrations/base/db.go @@ -0,0 +1,634 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package base + +import ( + "context" + "database/sql" + "errors" + "fmt" + "os" + "path" + "reflect" + "regexp" + "strings" + "time" + + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/unittest" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" + + "xorm.io/xorm" + "xorm.io/xorm/schemas" +) + +// RecreateTables will recreate the tables for the provided beans using the newly provided bean definition and move all data to that new table +// WARNING: YOU MUST PROVIDE THE FULL BEAN DEFINITION +func RecreateTables(beans ...interface{}) func(*xorm.Engine) error { + return func(x *xorm.Engine) error { + sess := x.NewSession() + defer sess.Close() + if err := sess.Begin(); err != nil { + return err + } + sess = sess.StoreEngine("InnoDB") + for _, bean := range beans { + log.Info("Recreating Table: %s for Bean: %s", x.TableName(bean), reflect.Indirect(reflect.ValueOf(bean)).Type().Name()) + if err := RecreateTable(sess, bean); err != nil { + return err + } + } + return sess.Commit() + } +} + +// RecreateTable will recreate the table using the newly provided bean definition and move all data to that new table +// WARNING: YOU MUST PROVIDE THE FULL BEAN DEFINITION +// WARNING: YOU MUST COMMIT THE SESSION AT THE END +func RecreateTable(sess *xorm.Session, bean interface{}) error { + // TODO: This will not work if there are foreign keys + + tableName := sess.Engine().TableName(bean) + tempTableName := fmt.Sprintf("tmp_recreate__%s", tableName) + + // We need to move the old table away and create a new one with the correct columns + // We will need to do this in stages to prevent data loss + // + // First create the temporary table + if err := sess.Table(tempTableName).CreateTable(bean); err != nil { + log.Error("Unable to create table %s. Error: %v", tempTableName, err) + return err + } + + if err := sess.Table(tempTableName).CreateUniques(bean); err != nil { + log.Error("Unable to create uniques for table %s. Error: %v", tempTableName, err) + return err + } + + if err := sess.Table(tempTableName).CreateIndexes(bean); err != nil { + log.Error("Unable to create indexes for table %s. Error: %v", tempTableName, err) + return err + } + + // Work out the column names from the bean - these are the columns to select from the old table and install into the new table + table, err := sess.Engine().TableInfo(bean) + if err != nil { + log.Error("Unable to get table info. Error: %v", err) + + return err + } + newTableColumns := table.Columns() + if len(newTableColumns) == 0 { + return fmt.Errorf("no columns in new table") + } + hasID := false + for _, column := range newTableColumns { + hasID = hasID || (column.IsPrimaryKey && column.IsAutoIncrement) + } + + if hasID && setting.Database.UseMSSQL { + if _, err := sess.Exec(fmt.Sprintf("SET IDENTITY_INSERT `%s` ON", tempTableName)); err != nil { + log.Error("Unable to set identity insert for table %s. Error: %v", tempTableName, err) + return err + } + } + + sqlStringBuilder := &strings.Builder{} + _, _ = sqlStringBuilder.WriteString("INSERT INTO `") + _, _ = sqlStringBuilder.WriteString(tempTableName) + _, _ = sqlStringBuilder.WriteString("` (`") + _, _ = sqlStringBuilder.WriteString(newTableColumns[0].Name) + _, _ = sqlStringBuilder.WriteString("`") + for _, column := range newTableColumns[1:] { + _, _ = sqlStringBuilder.WriteString(", `") + _, _ = sqlStringBuilder.WriteString(column.Name) + _, _ = sqlStringBuilder.WriteString("`") + } + _, _ = sqlStringBuilder.WriteString(")") + _, _ = sqlStringBuilder.WriteString(" SELECT ") + if newTableColumns[0].Default != "" { + _, _ = sqlStringBuilder.WriteString("COALESCE(`") + _, _ = sqlStringBuilder.WriteString(newTableColumns[0].Name) + _, _ = sqlStringBuilder.WriteString("`, ") + _, _ = sqlStringBuilder.WriteString(newTableColumns[0].Default) + _, _ = sqlStringBuilder.WriteString(")") + } else { + _, _ = sqlStringBuilder.WriteString("`") + _, _ = sqlStringBuilder.WriteString(newTableColumns[0].Name) + _, _ = sqlStringBuilder.WriteString("`") + } + + for _, column := range newTableColumns[1:] { + if column.Default != "" { + _, _ = sqlStringBuilder.WriteString(", COALESCE(`") + _, _ = sqlStringBuilder.WriteString(column.Name) + _, _ = sqlStringBuilder.WriteString("`, ") + _, _ = sqlStringBuilder.WriteString(column.Default) + _, _ = sqlStringBuilder.WriteString(")") + } else { + _, _ = sqlStringBuilder.WriteString(", `") + _, _ = sqlStringBuilder.WriteString(column.Name) + _, _ = sqlStringBuilder.WriteString("`") + } + } + _, _ = sqlStringBuilder.WriteString(" FROM `") + _, _ = sqlStringBuilder.WriteString(tableName) + _, _ = sqlStringBuilder.WriteString("`") + + if _, err := sess.Exec(sqlStringBuilder.String()); err != nil { + log.Error("Unable to set copy data in to temp table %s. Error: %v", tempTableName, err) + return err + } + + if hasID && setting.Database.UseMSSQL { + if _, err := sess.Exec(fmt.Sprintf("SET IDENTITY_INSERT `%s` OFF", tempTableName)); err != nil { + log.Error("Unable to switch off identity insert for table %s. Error: %v", tempTableName, err) + return err + } + } + + switch { + case setting.Database.UseSQLite3: + // SQLite will drop all the constraints on the old table + if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil { + log.Error("Unable to drop old table %s. Error: %v", tableName, err) + return err + } + + if err := sess.Table(tempTableName).DropIndexes(bean); err != nil { + log.Error("Unable to drop indexes on temporary table %s. Error: %v", tempTableName, err) + return err + } + + if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` RENAME TO `%s`", tempTableName, tableName)); err != nil { + log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err) + return err + } + + if err := sess.Table(tableName).CreateIndexes(bean); err != nil { + log.Error("Unable to recreate indexes on table %s. Error: %v", tableName, err) + return err + } + + if err := sess.Table(tableName).CreateUniques(bean); err != nil { + log.Error("Unable to recreate uniques on table %s. Error: %v", tableName, err) + return err + } + + case setting.Database.UseMySQL: + // MySQL will drop all the constraints on the old table + if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil { + log.Error("Unable to drop old table %s. Error: %v", tableName, err) + return err + } + + if err := sess.Table(tempTableName).DropIndexes(bean); err != nil { + log.Error("Unable to drop indexes on temporary table %s. Error: %v", tempTableName, err) + return err + } + + // SQLite and MySQL will move all the constraints from the temporary table to the new table + if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` RENAME TO `%s`", tempTableName, tableName)); err != nil { + log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err) + return err + } + + if err := sess.Table(tableName).CreateIndexes(bean); err != nil { + log.Error("Unable to recreate indexes on table %s. Error: %v", tableName, err) + return err + } + + if err := sess.Table(tableName).CreateUniques(bean); err != nil { + log.Error("Unable to recreate uniques on table %s. Error: %v", tableName, err) + return err + } + case setting.Database.UsePostgreSQL: + var originalSequences []string + type sequenceData struct { + LastValue int `xorm:"'last_value'"` + IsCalled bool `xorm:"'is_called'"` + } + sequenceMap := map[string]sequenceData{} + + schema := sess.Engine().Dialect().URI().Schema + sess.Engine().SetSchema("") + if err := sess.Table("information_schema.sequences").Cols("sequence_name").Where("sequence_name LIKE ? || '_%' AND sequence_catalog = ?", tableName, setting.Database.Name).Find(&originalSequences); err != nil { + log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err) + return err + } + sess.Engine().SetSchema(schema) + + for _, sequence := range originalSequences { + sequenceData := sequenceData{} + if _, err := sess.Table(sequence).Cols("last_value", "is_called").Get(&sequenceData); err != nil { + log.Error("Unable to get last_value and is_called from %s. Error: %v", sequence, err) + return err + } + sequenceMap[sequence] = sequenceData + + } + + // CASCADE causes postgres to drop all the constraints on the old table + if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s` CASCADE", tableName)); err != nil { + log.Error("Unable to drop old table %s. Error: %v", tableName, err) + return err + } + + // CASCADE causes postgres to move all the constraints from the temporary table to the new table + if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` RENAME TO `%s`", tempTableName, tableName)); err != nil { + log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err) + return err + } + + var indices []string + sess.Engine().SetSchema("") + if err := sess.Table("pg_indexes").Cols("indexname").Where("tablename = ? ", tableName).Find(&indices); err != nil { + log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err) + return err + } + sess.Engine().SetSchema(schema) + + for _, index := range indices { + newIndexName := strings.Replace(index, "tmp_recreate__", "", 1) + if _, err := sess.Exec(fmt.Sprintf("ALTER INDEX `%s` RENAME TO `%s`", index, newIndexName)); err != nil { + log.Error("Unable to rename %s to %s. Error: %v", index, newIndexName, err) + return err + } + } + + var sequences []string + sess.Engine().SetSchema("") + if err := sess.Table("information_schema.sequences").Cols("sequence_name").Where("sequence_name LIKE 'tmp_recreate__' || ? || '_%' AND sequence_catalog = ?", tableName, setting.Database.Name).Find(&sequences); err != nil { + log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err) + return err + } + sess.Engine().SetSchema(schema) + + for _, sequence := range sequences { + newSequenceName := strings.Replace(sequence, "tmp_recreate__", "", 1) + if _, err := sess.Exec(fmt.Sprintf("ALTER SEQUENCE `%s` RENAME TO `%s`", sequence, newSequenceName)); err != nil { + log.Error("Unable to rename %s sequence to %s. Error: %v", sequence, newSequenceName, err) + return err + } + val, ok := sequenceMap[newSequenceName] + if newSequenceName == tableName+"_id_seq" { + if ok && val.LastValue != 0 { + if _, err := sess.Exec(fmt.Sprintf("SELECT setval('%s', %d, %t)", newSequenceName, val.LastValue, val.IsCalled)); err != nil { + log.Error("Unable to reset %s to %d. Error: %v", newSequenceName, val, err) + return err + } + } else { + // We're going to try to guess this + if _, err := sess.Exec(fmt.Sprintf("SELECT setval('%s', COALESCE((SELECT MAX(id)+1 FROM `%s`), 1), false)", newSequenceName, tableName)); err != nil { + log.Error("Unable to reset %s. Error: %v", newSequenceName, err) + return err + } + } + } else if ok { + if _, err := sess.Exec(fmt.Sprintf("SELECT setval('%s', %d, %t)", newSequenceName, val.LastValue, val.IsCalled)); err != nil { + log.Error("Unable to reset %s to %d. Error: %v", newSequenceName, val, err) + return err + } + } + + } + + case setting.Database.UseMSSQL: + // MSSQL will drop all the constraints on the old table + if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil { + log.Error("Unable to drop old table %s. Error: %v", tableName, err) + return err + } + + // MSSQL sp_rename will move all the constraints from the temporary table to the new table + if _, err := sess.Exec(fmt.Sprintf("sp_rename `%s`,`%s`", tempTableName, tableName)); err != nil { + log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err) + return err + } + + default: + log.Fatal("Unrecognized DB") + } + return nil +} + +// WARNING: YOU MUST COMMIT THE SESSION AT THE END +func DropTableColumns(sess *xorm.Session, tableName string, columnNames ...string) (err error) { + if tableName == "" || len(columnNames) == 0 { + return nil + } + // TODO: This will not work if there are foreign keys + + switch { + case setting.Database.UseSQLite3: + // First drop the indexes on the columns + res, errIndex := sess.Query(fmt.Sprintf("PRAGMA index_list(`%s`)", tableName)) + if errIndex != nil { + return errIndex + } + for _, row := range res { + indexName := row["name"] + indexRes, err := sess.Query(fmt.Sprintf("PRAGMA index_info(`%s`)", indexName)) + if err != nil { + return err + } + if len(indexRes) != 1 { + continue + } + indexColumn := string(indexRes[0]["name"]) + for _, name := range columnNames { + if name == indexColumn { + _, err := sess.Exec(fmt.Sprintf("DROP INDEX `%s`", indexName)) + if err != nil { + return err + } + } + } + } + + // Here we need to get the columns from the original table + sql := fmt.Sprintf("SELECT sql FROM sqlite_master WHERE tbl_name='%s' and type='table'", tableName) + res, err := sess.Query(sql) + if err != nil { + return err + } + tableSQL := string(res[0]["sql"]) + + // Get the string offset for column definitions: `CREATE TABLE ( column-definitions... )` + columnDefinitionsIndex := strings.Index(tableSQL, "(") + if columnDefinitionsIndex < 0 { + return errors.New("couldn't find column definitions") + } + + // Separate out the column definitions + tableSQL = tableSQL[columnDefinitionsIndex:] + + // Remove the required columnNames + for _, name := range columnNames { + tableSQL = regexp.MustCompile(regexp.QuoteMeta("`"+name+"`")+"[^`,)]*?[,)]").ReplaceAllString(tableSQL, "") + } + + // Ensure the query is ended properly + tableSQL = strings.TrimSpace(tableSQL) + if tableSQL[len(tableSQL)-1] != ')' { + if tableSQL[len(tableSQL)-1] == ',' { + tableSQL = tableSQL[:len(tableSQL)-1] + } + tableSQL += ")" + } + + // Find all the columns in the table + columns := regexp.MustCompile("`([^`]*)`").FindAllString(tableSQL, -1) + + tableSQL = fmt.Sprintf("CREATE TABLE `new_%s_new` ", tableName) + tableSQL + if _, err := sess.Exec(tableSQL); err != nil { + return err + } + + // Now restore the data + columnsSeparated := strings.Join(columns, ",") + insertSQL := fmt.Sprintf("INSERT INTO `new_%s_new` (%s) SELECT %s FROM %s", tableName, columnsSeparated, columnsSeparated, tableName) + if _, err := sess.Exec(insertSQL); err != nil { + return err + } + + // Now drop the old table + if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil { + return err + } + + // Rename the table + if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `new_%s_new` RENAME TO `%s`", tableName, tableName)); err != nil { + return err + } + + case setting.Database.UsePostgreSQL: + cols := "" + for _, col := range columnNames { + if cols != "" { + cols += ", " + } + cols += "DROP COLUMN `" + col + "` CASCADE" + } + if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` %s", tableName, cols)); err != nil { + return fmt.Errorf("Drop table `%s` columns %v: %v", tableName, columnNames, err) + } + case setting.Database.UseMySQL: + // Drop indexes on columns first + sql := fmt.Sprintf("SHOW INDEX FROM %s WHERE column_name IN ('%s')", tableName, strings.Join(columnNames, "','")) + res, err := sess.Query(sql) + if err != nil { + return err + } + for _, index := range res { + indexName := index["column_name"] + if len(indexName) > 0 { + _, err := sess.Exec(fmt.Sprintf("DROP INDEX `%s` ON `%s`", indexName, tableName)) + if err != nil { + return err + } + } + } + + // Now drop the columns + cols := "" + for _, col := range columnNames { + if cols != "" { + cols += ", " + } + cols += "DROP COLUMN `" + col + "`" + } + if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` %s", tableName, cols)); err != nil { + return fmt.Errorf("Drop table `%s` columns %v: %v", tableName, columnNames, err) + } + case setting.Database.UseMSSQL: + cols := "" + for _, col := range columnNames { + if cols != "" { + cols += ", " + } + cols += "`" + strings.ToLower(col) + "`" + } + sql := fmt.Sprintf("SELECT Name FROM sys.default_constraints WHERE parent_object_id = OBJECT_ID('%[1]s') AND parent_column_id IN (SELECT column_id FROM sys.columns WHERE LOWER(name) IN (%[2]s) AND object_id = OBJECT_ID('%[1]s'))", + tableName, strings.ReplaceAll(cols, "`", "'")) + constraints := make([]string, 0) + if err := sess.SQL(sql).Find(&constraints); err != nil { + return fmt.Errorf("Find constraints: %v", err) + } + for _, constraint := range constraints { + if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` DROP CONSTRAINT `%s`", tableName, constraint)); err != nil { + return fmt.Errorf("Drop table `%s` default constraint `%s`: %v", tableName, constraint, err) + } + } + sql = fmt.Sprintf("SELECT DISTINCT Name FROM sys.indexes INNER JOIN sys.index_columns ON indexes.index_id = index_columns.index_id AND indexes.object_id = index_columns.object_id WHERE indexes.object_id = OBJECT_ID('%[1]s') AND index_columns.column_id IN (SELECT column_id FROM sys.columns WHERE LOWER(name) IN (%[2]s) AND object_id = OBJECT_ID('%[1]s'))", + tableName, strings.ReplaceAll(cols, "`", "'")) + constraints = make([]string, 0) + if err := sess.SQL(sql).Find(&constraints); err != nil { + return fmt.Errorf("Find constraints: %v", err) + } + for _, constraint := range constraints { + if _, err := sess.Exec(fmt.Sprintf("DROP INDEX `%[2]s` ON `%[1]s`", tableName, constraint)); err != nil { + return fmt.Errorf("Drop index `%[2]s` on `%[1]s`: %v", tableName, constraint, err) + } + } + + if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` DROP COLUMN %s", tableName, cols)); err != nil { + return fmt.Errorf("Drop table `%s` columns %v: %v", tableName, columnNames, err) + } + default: + log.Fatal("Unrecognized DB") + } + + return nil +} + +// ModifyColumn will modify column's type or other property. SQLITE is not supported +func ModifyColumn(x *xorm.Engine, tableName string, col *schemas.Column) error { + var indexes map[string]*schemas.Index + var err error + // MSSQL have to remove index at first, otherwise alter column will fail + // ref. https://sqlzealots.com/2018/05/09/error-message-the-index-is-dependent-on-column-alter-table-alter-column-failed-because-one-or-more-objects-access-this-column/ + if x.Dialect().URI().DBType == schemas.MSSQL { + indexes, err = x.Dialect().GetIndexes(x.DB(), context.Background(), tableName) + if err != nil { + return err + } + + for _, index := range indexes { + _, err = x.Exec(x.Dialect().DropIndexSQL(tableName, index)) + if err != nil { + return err + } + } + } + + defer func() { + for _, index := range indexes { + _, err = x.Exec(x.Dialect().CreateIndexSQL(tableName, index)) + if err != nil { + log.Error("Create index %s on table %s failed: %v", index.Name, tableName, err) + } + } + }() + + alterSQL := x.Dialect().ModifyColumnSQL(tableName, col) + if _, err := x.Exec(alterSQL); err != nil { + return err + } + return nil +} + +func removeAllWithRetry(dir string) error { + var err error + for i := 0; i < 20; i++ { + err = os.RemoveAll(dir) + if err == nil { + break + } + time.Sleep(100 * time.Millisecond) + } + return err +} + +func newXORMEngine() (*xorm.Engine, error) { + if err := db.InitEngine(context.Background()); err != nil { + return nil, err + } + x := unittest.GetXORMEngine() + return x, nil +} + +func deleteDB() error { + switch { + case setting.Database.UseSQLite3: + if err := util.Remove(setting.Database.Path); err != nil { + return err + } + return os.MkdirAll(path.Dir(setting.Database.Path), os.ModePerm) + + case setting.Database.UseMySQL: + db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/", + setting.Database.User, setting.Database.Passwd, setting.Database.Host)) + if err != nil { + return err + } + defer db.Close() + + if _, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS %s", setting.Database.Name)); err != nil { + return err + } + + if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", setting.Database.Name)); err != nil { + return err + } + return nil + case setting.Database.UsePostgreSQL: + db, err := sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/?sslmode=%s", + setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.SSLMode)) + if err != nil { + return err + } + defer db.Close() + + if _, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS %s", setting.Database.Name)); err != nil { + return err + } + + if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s", setting.Database.Name)); err != nil { + return err + } + db.Close() + + // Check if we need to setup a specific schema + if len(setting.Database.Schema) != 0 { + db, err = sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=%s", + setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.Name, setting.Database.SSLMode)) + if err != nil { + return err + } + defer db.Close() + + schrows, err := db.Query(fmt.Sprintf("SELECT 1 FROM information_schema.schemata WHERE schema_name = '%s'", setting.Database.Schema)) + if err != nil { + return err + } + defer schrows.Close() + + if !schrows.Next() { + // Create and setup a DB schema + _, err = db.Exec(fmt.Sprintf("CREATE SCHEMA %s", setting.Database.Schema)) + if err != nil { + return err + } + } + + // Make the user's default search path the created schema; this will affect new connections + _, err = db.Exec(fmt.Sprintf(`ALTER USER "%s" SET search_path = %s`, setting.Database.User, setting.Database.Schema)) + if err != nil { + return err + } + return nil + } + case setting.Database.UseMSSQL: + host, port := setting.ParseMSSQLHostPort(setting.Database.Host) + db, err := sql.Open("mssql", fmt.Sprintf("server=%s; port=%s; database=%s; user id=%s; password=%s;", + host, port, "master", setting.Database.User, setting.Database.Passwd)) + if err != nil { + return err + } + defer db.Close() + + if _, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS [%s]", setting.Database.Name)); err != nil { + return err + } + if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE [%s]", setting.Database.Name)); err != nil { + return err + } + } + + return nil +} diff --git a/models/migrations/base/db_test.go b/models/migrations/base/db_test.go new file mode 100644 index 000000000000..ee227b79783f --- /dev/null +++ b/models/migrations/base/db_test.go @@ -0,0 +1,97 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package base + +import ( + "testing" + + "code.gitea.io/gitea/modules/timeutil" + + "xorm.io/xorm/names" +) + +func Test_DropTableColumns(t *testing.T) { + x, deferable := PrepareTestEnv(t, 0) + if x == nil || t.Failed() { + defer deferable() + return + } + defer deferable() + + type DropTest struct { + ID int64 `xorm:"pk autoincr"` + FirstColumn string + ToDropColumn string `xorm:"unique"` + AnotherColumn int64 + CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` + UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` + } + + columns := []string{ + "first_column", + "to_drop_column", + "another_column", + "created_unix", + "updated_unix", + } + + for i := range columns { + x.SetMapper(names.GonicMapper{}) + if err := x.Sync2(new(DropTest)); err != nil { + t.Errorf("unable to create DropTest table: %v", err) + return + } + sess := x.NewSession() + if err := sess.Begin(); err != nil { + sess.Close() + t.Errorf("unable to begin transaction: %v", err) + return + } + if err := DropTableColumns(sess, "drop_test", columns[i:]...); err != nil { + sess.Close() + t.Errorf("Unable to drop columns[%d:]: %s from drop_test: %v", i, columns[i:], err) + return + } + if err := sess.Commit(); err != nil { + sess.Close() + t.Errorf("unable to commit transaction: %v", err) + return + } + sess.Close() + if err := x.DropTables(new(DropTest)); err != nil { + t.Errorf("unable to drop table: %v", err) + return + } + for j := range columns[i+1:] { + x.SetMapper(names.GonicMapper{}) + if err := x.Sync2(new(DropTest)); err != nil { + t.Errorf("unable to create DropTest table: %v", err) + return + } + dropcols := append([]string{columns[i]}, columns[j+i+1:]...) + sess := x.NewSession() + if err := sess.Begin(); err != nil { + sess.Close() + t.Errorf("unable to begin transaction: %v", err) + return + } + if err := DropTableColumns(sess, "drop_test", dropcols...); err != nil { + sess.Close() + t.Errorf("Unable to drop columns: %s from drop_test: %v", dropcols, err) + return + } + if err := sess.Commit(); err != nil { + sess.Close() + t.Errorf("unable to commit transaction: %v", err) + return + } + sess.Close() + if err := x.DropTables(new(DropTest)); err != nil { + t.Errorf("unable to drop table: %v", err) + return + } + } + } +} diff --git a/models/migrations/base/hash.go b/models/migrations/base/hash.go new file mode 100644 index 000000000000..0f078dd70fdb --- /dev/null +++ b/models/migrations/base/hash.go @@ -0,0 +1,17 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package base + +import ( + "crypto/sha256" + "fmt" + + "golang.org/x/crypto/pbkdf2" +) + +func HashToken(token, salt string) string { + tempHash := pbkdf2.Key([]byte(token), []byte(salt), 10000, 50, sha256.New) + return fmt.Sprintf("%x", tempHash) +} diff --git a/models/migrations/base/main_test.go b/models/migrations/base/main_test.go new file mode 100644 index 000000000000..290d87214adb --- /dev/null +++ b/models/migrations/base/main_test.go @@ -0,0 +1,13 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package base + +import ( + "testing" +) + +func TestMain(m *testing.M) { + MainTest(m) +} diff --git a/models/migrations/testlogger_test.go b/models/migrations/base/testlogger.go similarity index 96% rename from models/migrations/testlogger_test.go rename to models/migrations/base/testlogger.go index 0455d9c9a6c5..0f35a078eca0 100644 --- a/models/migrations/testlogger_test.go +++ b/models/migrations/base/testlogger.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package base import ( "context" @@ -184,9 +184,3 @@ func (log *TestLogger) ReleaseReopen() error { func (log *TestLogger) GetName() string { return "test" } - -func init() { - log.Register("test", NewTestLogger) - _, filename, _, _ := runtime.Caller(0) - prefix = strings.TrimSuffix(filename, "tests/testlogger.go") -} diff --git a/models/migrations/base/tests.go b/models/migrations/base/tests.go new file mode 100644 index 000000000000..dafc0df2f27d --- /dev/null +++ b/models/migrations/base/tests.go @@ -0,0 +1,170 @@ +// Copyright 2022 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package base + +import ( + "context" + "fmt" + "os" + "path" + "path/filepath" + "runtime" + "strings" + "testing" + + "code.gitea.io/gitea/models/unittest" + "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + + "github.com/stretchr/testify/assert" + "xorm.io/xorm" +) + +// PrepareTestEnv prepares the test environment and reset the database. The skip parameter should usually be 0. +// Provide models to be sync'd with the database - in particular any models you expect fixtures to be loaded from. +// +// fixtures in `models/migrations/fixtures/` will be loaded automatically +func PrepareTestEnv(t *testing.T, skip int, syncModels ...interface{}) (*xorm.Engine, func()) { + t.Helper() + ourSkip := 2 + ourSkip += skip + deferFn := PrintCurrentTest(t, ourSkip) + assert.NoError(t, os.RemoveAll(setting.RepoRootPath)) + assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "tests/gitea-repositories-meta"), setting.RepoRootPath)) + ownerDirs, err := os.ReadDir(setting.RepoRootPath) + if err != nil { + assert.NoError(t, err, "unable to read the new repo root: %v\n", err) + } + for _, ownerDir := range ownerDirs { + if !ownerDir.Type().IsDir() { + continue + } + repoDirs, err := os.ReadDir(filepath.Join(setting.RepoRootPath, ownerDir.Name())) + if err != nil { + assert.NoError(t, err, "unable to read the new repo root: %v\n", err) + } + for _, repoDir := range repoDirs { + _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "pack"), 0o755) + _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "info"), 0o755) + _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "refs", "heads"), 0o755) + _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "refs", "tag"), 0o755) + } + } + + if err := deleteDB(); err != nil { + t.Errorf("unable to reset database: %v", err) + return nil, deferFn + } + + x, err := newXORMEngine() + assert.NoError(t, err) + if x != nil { + oldDefer := deferFn + deferFn = func() { + oldDefer() + if err := x.Close(); err != nil { + t.Errorf("error during close: %v", err) + } + if err := deleteDB(); err != nil { + t.Errorf("unable to reset database: %v", err) + } + } + } + if err != nil { + return x, deferFn + } + + if len(syncModels) > 0 { + if err := x.Sync2(syncModels...); err != nil { + t.Errorf("error during sync: %v", err) + return x, deferFn + } + } + + fixturesDir := filepath.Join(filepath.Dir(setting.AppPath), "models", "migrations", "fixtures", t.Name()) + + if _, err := os.Stat(fixturesDir); err == nil { + t.Logf("initializing fixtures from: %s", fixturesDir) + if err := unittest.InitFixtures( + unittest.FixturesOptions{ + Dir: fixturesDir, + }, x); err != nil { + t.Errorf("error whilst initializing fixtures from %s: %v", fixturesDir, err) + return x, deferFn + } + if err := unittest.LoadFixtures(x); err != nil { + t.Errorf("error whilst loading fixtures from %s: %v", fixturesDir, err) + return x, deferFn + } + } else if !os.IsNotExist(err) { + t.Errorf("unexpected error whilst checking for existence of fixtures: %v", err) + } else { + t.Logf("no fixtures found in: %s", fixturesDir) + } + + return x, deferFn +} + +func MainTest(m *testing.M) { + log.Register("test", NewTestLogger) + _, filename, _, _ := runtime.Caller(0) + prefix = strings.TrimSuffix(filename, "tests/testlogger.go") + + giteaRoot := base.SetupGiteaRoot() + if giteaRoot == "" { + fmt.Println("Environment variable $GITEA_ROOT not set") + os.Exit(1) + } + giteaBinary := "gitea" + if runtime.GOOS == "windows" { + giteaBinary += ".exe" + } + setting.AppPath = path.Join(giteaRoot, giteaBinary) + if _, err := os.Stat(setting.AppPath); err != nil { + fmt.Printf("Could not find gitea binary at %s\n", setting.AppPath) + os.Exit(1) + } + + giteaConf := os.Getenv("GITEA_CONF") + if giteaConf == "" { + giteaConf = path.Join(filepath.Dir(setting.AppPath), "tests/sqlite.ini") + fmt.Printf("Environment variable $GITEA_CONF not set - defaulting to %s\n", giteaConf) + } + + if !path.IsAbs(giteaConf) { + setting.CustomConf = path.Join(giteaRoot, giteaConf) + } else { + setting.CustomConf = giteaConf + } + + tmpDataPath, err := os.MkdirTemp("", "data") + if err != nil { + fmt.Printf("Unable to create temporary data path %v\n", err) + os.Exit(1) + } + + setting.AppDataPath = tmpDataPath + + setting.SetCustomPathAndConf("", "", "") + setting.LoadForTest() + if err = git.InitFull(context.Background()); err != nil { + fmt.Printf("Unable to InitFull: %v\n", err) + os.Exit(1) + } + setting.InitDBConfig() + setting.NewLogServices(true) + + exitStatus := m.Run() + + if err := removeAllWithRetry(setting.RepoRootPath); err != nil { + fmt.Fprintf(os.Stderr, "os.RemoveAll: %v\n", err) + } + if err := removeAllWithRetry(tmpDataPath); err != nil { + fmt.Fprintf(os.Stderr, "os.RemoveAll: %v\n", err) + } + os.Exit(exitStatus) +} diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 31b88a798110..9291473f0dae 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -6,20 +6,28 @@ package migrations import ( - "context" - "errors" "fmt" "os" - "reflect" - "regexp" - "strings" + "code.gitea.io/gitea/models/migrations/v1_10" + "code.gitea.io/gitea/models/migrations/v1_11" + "code.gitea.io/gitea/models/migrations/v1_12" + "code.gitea.io/gitea/models/migrations/v1_13" + "code.gitea.io/gitea/models/migrations/v1_14" + "code.gitea.io/gitea/models/migrations/v1_15" + "code.gitea.io/gitea/models/migrations/v1_16" + "code.gitea.io/gitea/models/migrations/v1_17" + "code.gitea.io/gitea/models/migrations/v1_18" + "code.gitea.io/gitea/models/migrations/v1_19" + "code.gitea.io/gitea/models/migrations/v1_6" + "code.gitea.io/gitea/models/migrations/v1_7" + "code.gitea.io/gitea/models/migrations/v1_8" + "code.gitea.io/gitea/models/migrations/v1_9" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "xorm.io/xorm" "xorm.io/xorm/names" - "xorm.io/xorm/schemas" ) const minDBVersion = 70 // Gitea 1.5.3 @@ -66,365 +74,365 @@ var migrations = []Migration{ // Gitea 1.5.0 ends at v69 // v70 -> v71 - NewMigration("add issue_dependencies", addIssueDependencies), + NewMigration("add issue_dependencies", v1_6.AddIssueDependencies), // v71 -> v72 - NewMigration("protect each scratch token", addScratchHash), + NewMigration("protect each scratch token", v1_6.AddScratchHash), // v72 -> v73 - NewMigration("add review", addReview), + NewMigration("add review", v1_6.AddReview), // Gitea 1.6.0 ends at v73 // v73 -> v74 - NewMigration("add must_change_password column for users table", addMustChangePassword), + NewMigration("add must_change_password column for users table", v1_7.AddMustChangePassword), // v74 -> v75 - NewMigration("add approval whitelists to protected branches", addApprovalWhitelistsToProtectedBranches), + NewMigration("add approval whitelists to protected branches", v1_7.AddApprovalWhitelistsToProtectedBranches), // v75 -> v76 - NewMigration("clear nonused data which not deleted when user was deleted", clearNonusedData), + NewMigration("clear nonused data which not deleted when user was deleted", v1_7.ClearNonusedData), // Gitea 1.7.0 ends at v76 // v76 -> v77 - NewMigration("add pull request rebase with merge commit", addPullRequestRebaseWithMerge), + NewMigration("add pull request rebase with merge commit", v1_8.AddPullRequestRebaseWithMerge), // v77 -> v78 - NewMigration("add theme to users", addUserDefaultTheme), + NewMigration("add theme to users", v1_8.AddUserDefaultTheme), // v78 -> v79 - NewMigration("rename repo is_bare to repo is_empty", renameRepoIsBareToIsEmpty), + NewMigration("rename repo is_bare to repo is_empty", v1_8.RenameRepoIsBareToIsEmpty), // v79 -> v80 - NewMigration("add can close issues via commit in any branch", addCanCloseIssuesViaCommitInAnyBranch), + NewMigration("add can close issues via commit in any branch", v1_8.AddCanCloseIssuesViaCommitInAnyBranch), // v80 -> v81 - NewMigration("add is locked to issues", addIsLockedToIssues), + NewMigration("add is locked to issues", v1_8.AddIsLockedToIssues), // v81 -> v82 - NewMigration("update U2F counter type", changeU2FCounterType), + NewMigration("update U2F counter type", v1_8.ChangeU2FCounterType), // Gitea 1.8.0 ends at v82 // v82 -> v83 - NewMigration("hot fix for wrong release sha1 on release table", fixReleaseSha1OnReleaseTable), + NewMigration("hot fix for wrong release sha1 on release table", v1_9.FixReleaseSha1OnReleaseTable), // v83 -> v84 - NewMigration("add uploader id for table attachment", addUploaderIDForAttachment), + NewMigration("add uploader id for table attachment", v1_9.AddUploaderIDForAttachment), // v84 -> v85 - NewMigration("add table to store original imported gpg keys", addGPGKeyImport), + NewMigration("add table to store original imported gpg keys", v1_9.AddGPGKeyImport), // v85 -> v86 - NewMigration("hash application token", hashAppToken), + NewMigration("hash application token", v1_9.HashAppToken), // v86 -> v87 - NewMigration("add http method to webhook", addHTTPMethodToWebhook), + NewMigration("add http method to webhook", v1_9.AddHTTPMethodToWebhook), // v87 -> v88 - NewMigration("add avatar field to repository", addAvatarFieldToRepository), + NewMigration("add avatar field to repository", v1_9.AddAvatarFieldToRepository), // Gitea 1.9.0 ends at v88 // v88 -> v89 - NewMigration("add commit status context field to commit_status", addCommitStatusContext), + NewMigration("add commit status context field to commit_status", v1_10.AddCommitStatusContext), // v89 -> v90 - NewMigration("add original author/url migration info to issues, comments, and repo ", addOriginalMigrationInfo), + NewMigration("add original author/url migration info to issues, comments, and repo ", v1_10.AddOriginalMigrationInfo), // v90 -> v91 - NewMigration("change length of some repository columns", changeSomeColumnsLengthOfRepo), + NewMigration("change length of some repository columns", v1_10.ChangeSomeColumnsLengthOfRepo), // v91 -> v92 - NewMigration("add index on owner_id of repository and type, review_id of comment", addIndexOnRepositoryAndComment), + NewMigration("add index on owner_id of repository and type, review_id of comment", v1_10.AddIndexOnRepositoryAndComment), // v92 -> v93 - NewMigration("remove orphaned repository index statuses", removeLingeringIndexStatus), + NewMigration("remove orphaned repository index statuses", v1_10.RemoveLingeringIndexStatus), // v93 -> v94 - NewMigration("add email notification enabled preference to user", addEmailNotificationEnabledToUser), + NewMigration("add email notification enabled preference to user", v1_10.AddEmailNotificationEnabledToUser), // v94 -> v95 - NewMigration("add enable_status_check, status_check_contexts to protected_branch", addStatusCheckColumnsForProtectedBranches), + NewMigration("add enable_status_check, status_check_contexts to protected_branch", v1_10.AddStatusCheckColumnsForProtectedBranches), // v95 -> v96 - NewMigration("add table columns for cross referencing issues", addCrossReferenceColumns), + NewMigration("add table columns for cross referencing issues", v1_10.AddCrossReferenceColumns), // v96 -> v97 - NewMigration("delete orphaned attachments", deleteOrphanedAttachments), + NewMigration("delete orphaned attachments", v1_10.DeleteOrphanedAttachments), // v97 -> v98 - NewMigration("add repo_admin_change_team_access to user", addRepoAdminChangeTeamAccessColumnForUser), + NewMigration("add repo_admin_change_team_access to user", v1_10.AddRepoAdminChangeTeamAccessColumnForUser), // v98 -> v99 - NewMigration("add original author name and id on migrated release", addOriginalAuthorOnMigratedReleases), + NewMigration("add original author name and id on migrated release", v1_10.AddOriginalAuthorOnMigratedReleases), // v99 -> v100 - NewMigration("add task table and status column for repository table", addTaskTable), + NewMigration("add task table and status column for repository table", v1_10.AddTaskTable), // v100 -> v101 - NewMigration("update migration repositories' service type", updateMigrationServiceTypes), + NewMigration("update migration repositories' service type", v1_10.UpdateMigrationServiceTypes), // v101 -> v102 - NewMigration("change length of some external login users columns", changeSomeColumnsLengthOfExternalLoginUser), + NewMigration("change length of some external login users columns", v1_10.ChangeSomeColumnsLengthOfExternalLoginUser), // Gitea 1.10.0 ends at v102 // v102 -> v103 - NewMigration("update migration repositories' service type", dropColumnHeadUserNameOnPullRequest), + NewMigration("update migration repositories' service type", v1_11.DropColumnHeadUserNameOnPullRequest), // v103 -> v104 - NewMigration("Add WhitelistDeployKeys to protected branch", addWhitelistDeployKeysToBranches), + NewMigration("Add WhitelistDeployKeys to protected branch", v1_11.AddWhitelistDeployKeysToBranches), // v104 -> v105 - NewMigration("remove unnecessary columns from label", removeLabelUneededCols), + NewMigration("remove unnecessary columns from label", v1_11.RemoveLabelUneededCols), // v105 -> v106 - NewMigration("add includes_all_repositories to teams", addTeamIncludesAllRepositories), + NewMigration("add includes_all_repositories to teams", v1_11.AddTeamIncludesAllRepositories), // v106 -> v107 - NewMigration("add column `mode` to table watch", addModeColumnToWatch), + NewMigration("add column `mode` to table watch", v1_11.AddModeColumnToWatch), // v107 -> v108 - NewMigration("Add template options to repository", addTemplateToRepo), + NewMigration("Add template options to repository", v1_11.AddTemplateToRepo), // v108 -> v109 - NewMigration("Add comment_id on table notification", addCommentIDOnNotification), + NewMigration("Add comment_id on table notification", v1_11.AddCommentIDOnNotification), // v109 -> v110 - NewMigration("add can_create_org_repo to team", addCanCreateOrgRepoColumnForTeam), + NewMigration("add can_create_org_repo to team", v1_11.AddCanCreateOrgRepoColumnForTeam), // v110 -> v111 - NewMigration("change review content type to text", changeReviewContentToText), + NewMigration("change review content type to text", v1_11.ChangeReviewContentToText), // v111 -> v112 - NewMigration("update branch protection for can push and whitelist enable", addBranchProtectionCanPushAndEnableWhitelist), + NewMigration("update branch protection for can push and whitelist enable", v1_11.AddBranchProtectionCanPushAndEnableWhitelist), // v112 -> v113 - NewMigration("remove release attachments which repository deleted", removeAttachmentMissedRepo), + NewMigration("remove release attachments which repository deleted", v1_11.RemoveAttachmentMissedRepo), // v113 -> v114 - NewMigration("new feature: change target branch of pull requests", featureChangeTargetBranch), + NewMigration("new feature: change target branch of pull requests", v1_11.FeatureChangeTargetBranch), // v114 -> v115 - NewMigration("Remove authentication credentials from stored URL", sanitizeOriginalURL), + NewMigration("Remove authentication credentials from stored URL", v1_11.SanitizeOriginalURL), // v115 -> v116 - NewMigration("add user_id prefix to existing user avatar name", renameExistingUserAvatarName), + NewMigration("add user_id prefix to existing user avatar name", v1_11.RenameExistingUserAvatarName), // v116 -> v117 - NewMigration("Extend TrackedTimes", extendTrackedTimes), + NewMigration("Extend TrackedTimes", v1_11.ExtendTrackedTimes), // Gitea 1.11.0 ends at v117 // v117 -> v118 - NewMigration("Add block on rejected reviews branch protection", addBlockOnRejectedReviews), + NewMigration("Add block on rejected reviews branch protection", v1_12.AddBlockOnRejectedReviews), // v118 -> v119 - NewMigration("Add commit id and stale to reviews", addReviewCommitAndStale), + NewMigration("Add commit id and stale to reviews", v1_12.AddReviewCommitAndStale), // v119 -> v120 - NewMigration("Fix migrated repositories' git service type", fixMigratedRepositoryServiceType), + NewMigration("Fix migrated repositories' git service type", v1_12.FixMigratedRepositoryServiceType), // v120 -> v121 - NewMigration("Add owner_name on table repository", addOwnerNameOnRepository), + NewMigration("Add owner_name on table repository", v1_12.AddOwnerNameOnRepository), // v121 -> v122 - NewMigration("add is_restricted column for users table", addIsRestricted), + NewMigration("add is_restricted column for users table", v1_12.AddIsRestricted), // v122 -> v123 - NewMigration("Add Require Signed Commits to ProtectedBranch", addRequireSignedCommits), + NewMigration("Add Require Signed Commits to ProtectedBranch", v1_12.AddRequireSignedCommits), // v123 -> v124 - NewMigration("Add original information for reactions", addReactionOriginals), + NewMigration("Add original information for reactions", v1_12.AddReactionOriginals), // v124 -> v125 - NewMigration("Add columns to user and repository", addUserRepoMissingColumns), + NewMigration("Add columns to user and repository", v1_12.AddUserRepoMissingColumns), // v125 -> v126 - NewMigration("Add some columns on review for migration", addReviewMigrateInfo), + NewMigration("Add some columns on review for migration", v1_12.AddReviewMigrateInfo), // v126 -> v127 - NewMigration("Fix topic repository count", fixTopicRepositoryCount), + NewMigration("Fix topic repository count", v1_12.FixTopicRepositoryCount), // v127 -> v128 - NewMigration("add repository code language statistics", addLanguageStats), + NewMigration("add repository code language statistics", v1_12.AddLanguageStats), // v128 -> v129 - NewMigration("fix merge base for pull requests", fixMergeBase), + NewMigration("fix merge base for pull requests", v1_12.FixMergeBase), // v129 -> v130 - NewMigration("remove dependencies from deleted repositories", purgeUnusedDependencies), + NewMigration("remove dependencies from deleted repositories", v1_12.PurgeUnusedDependencies), // v130 -> v131 - NewMigration("Expand webhooks for more granularity", expandWebhooks), + NewMigration("Expand webhooks for more granularity", v1_12.ExpandWebhooks), // v131 -> v132 - NewMigration("Add IsSystemWebhook column to webhooks table", addSystemWebhookColumn), + NewMigration("Add IsSystemWebhook column to webhooks table", v1_12.AddSystemWebhookColumn), // v132 -> v133 - NewMigration("Add Branch Protection Protected Files Column", addBranchProtectionProtectedFilesColumn), + NewMigration("Add Branch Protection Protected Files Column", v1_12.AddBranchProtectionProtectedFilesColumn), // v133 -> v134 - NewMigration("Add EmailHash Table", addEmailHashTable), + NewMigration("Add EmailHash Table", v1_12.AddEmailHashTable), // v134 -> v135 - NewMigration("Refix merge base for merged pull requests", refixMergeBase), + NewMigration("Refix merge base for merged pull requests", v1_12.RefixMergeBase), // v135 -> v136 - NewMigration("Add OrgID column to Labels table", addOrgIDLabelColumn), + NewMigration("Add OrgID column to Labels table", v1_12.AddOrgIDLabelColumn), // v136 -> v137 - NewMigration("Add CommitsAhead and CommitsBehind Column to PullRequest Table", addCommitDivergenceToPulls), + NewMigration("Add CommitsAhead and CommitsBehind Column to PullRequest Table", v1_12.AddCommitDivergenceToPulls), // v137 -> v138 - NewMigration("Add Branch Protection Block Outdated Branch", addBlockOnOutdatedBranch), + NewMigration("Add Branch Protection Block Outdated Branch", v1_12.AddBlockOnOutdatedBranch), // v138 -> v139 - NewMigration("Add ResolveDoerID to Comment table", addResolveDoerIDCommentColumn), + NewMigration("Add ResolveDoerID to Comment table", v1_12.AddResolveDoerIDCommentColumn), // v139 -> v140 - NewMigration("prepend refs/heads/ to issue refs", prependRefsHeadsToIssueRefs), + NewMigration("prepend refs/heads/ to issue refs", v1_12.PrependRefsHeadsToIssueRefs), // Gitea 1.12.0 ends at v140 // v140 -> v141 - NewMigration("Save detected language file size to database instead of percent", fixLanguageStatsToSaveSize), + NewMigration("Save detected language file size to database instead of percent", v1_13.FixLanguageStatsToSaveSize), // v141 -> v142 - NewMigration("Add KeepActivityPrivate to User table", addKeepActivityPrivateUserColumn), + NewMigration("Add KeepActivityPrivate to User table", v1_13.AddKeepActivityPrivateUserColumn), // v142 -> v143 - NewMigration("Ensure Repository.IsArchived is not null", setIsArchivedToFalse), + NewMigration("Ensure Repository.IsArchived is not null", v1_13.SetIsArchivedToFalse), // v143 -> v144 - NewMigration("recalculate Stars number for all user", recalculateStars), + NewMigration("recalculate Stars number for all user", v1_13.RecalculateStars), // v144 -> v145 - NewMigration("update Matrix Webhook http method to 'PUT'", updateMatrixWebhookHTTPMethod), + NewMigration("update Matrix Webhook http method to 'PUT'", v1_13.UpdateMatrixWebhookHTTPMethod), // v145 -> v146 - NewMigration("Increase Language field to 50 in LanguageStats", increaseLanguageField), + NewMigration("Increase Language field to 50 in LanguageStats", v1_13.IncreaseLanguageField), // v146 -> v147 - NewMigration("Add projects info to repository table", addProjectsInfo), + NewMigration("Add projects info to repository table", v1_13.AddProjectsInfo), // v147 -> v148 - NewMigration("create review for 0 review id code comments", createReviewsForCodeComments), + NewMigration("create review for 0 review id code comments", v1_13.CreateReviewsForCodeComments), // v148 -> v149 - NewMigration("remove issue dependency comments who refer to non existing issues", purgeInvalidDependenciesComments), + NewMigration("remove issue dependency comments who refer to non existing issues", v1_13.PurgeInvalidDependenciesComments), // v149 -> v150 - NewMigration("Add Created and Updated to Milestone table", addCreatedAndUpdatedToMilestones), + NewMigration("Add Created and Updated to Milestone table", v1_13.AddCreatedAndUpdatedToMilestones), // v150 -> v151 - NewMigration("add primary key to repo_topic", addPrimaryKeyToRepoTopic), + NewMigration("add primary key to repo_topic", v1_13.AddPrimaryKeyToRepoTopic), // v151 -> v152 - NewMigration("set default password algorithm to Argon2", setDefaultPasswordToArgon2), + NewMigration("set default password algorithm to Argon2", v1_13.SetDefaultPasswordToArgon2), // v152 -> v153 - NewMigration("add TrustModel field to Repository", addTrustModelToRepository), + NewMigration("add TrustModel field to Repository", v1_13.AddTrustModelToRepository), // v153 > v154 - NewMigration("add Team review request support", addTeamReviewRequestSupport), + NewMigration("add Team review request support", v1_13.AddTeamReviewRequestSupport), // v154 > v155 - NewMigration("add timestamps to Star, Label, Follow, Watch and Collaboration", addTimeStamps), + NewMigration("add timestamps to Star, Label, Follow, Watch and Collaboration", v1_13.AddTimeStamps), // Gitea 1.13.0 ends at v155 // v155 -> v156 - NewMigration("add changed_protected_files column for pull_request table", addChangedProtectedFilesPullRequestColumn), + NewMigration("add changed_protected_files column for pull_request table", v1_14.AddChangedProtectedFilesPullRequestColumn), // v156 -> v157 - NewMigration("fix publisher ID for tag releases", fixPublisherIDforTagReleases), + NewMigration("fix publisher ID for tag releases", v1_14.FixPublisherIDforTagReleases), // v157 -> v158 - NewMigration("ensure repo topics are up-to-date", fixRepoTopics), + NewMigration("ensure repo topics are up-to-date", v1_14.FixRepoTopics), // v158 -> v159 - NewMigration("code comment replies should have the commitID of the review they are replying to", updateCodeCommentReplies), + NewMigration("code comment replies should have the commitID of the review they are replying to", v1_14.UpdateCodeCommentReplies), // v159 -> v160 - NewMigration("update reactions constraint", updateReactionConstraint), + NewMigration("update reactions constraint", v1_14.UpdateReactionConstraint), // v160 -> v161 - NewMigration("Add block on official review requests branch protection", addBlockOnOfficialReviewRequests), + NewMigration("Add block on official review requests branch protection", v1_14.AddBlockOnOfficialReviewRequests), // v161 -> v162 - NewMigration("Convert task type from int to string", convertTaskTypeToString), + NewMigration("Convert task type from int to string", v1_14.ConvertTaskTypeToString), // v162 -> v163 - NewMigration("Convert webhook task type from int to string", convertWebhookTaskTypeToString), + NewMigration("Convert webhook task type from int to string", v1_14.ConvertWebhookTaskTypeToString), // v163 -> v164 - NewMigration("Convert topic name from 25 to 50", convertTopicNameFrom25To50), + NewMigration("Convert topic name from 25 to 50", v1_14.ConvertTopicNameFrom25To50), // v164 -> v165 - NewMigration("Add scope and nonce columns to oauth2_grant table", addScopeAndNonceColumnsToOAuth2Grant), + NewMigration("Add scope and nonce columns to oauth2_grant table", v1_14.AddScopeAndNonceColumnsToOAuth2Grant), // v165 -> v166 - NewMigration("Convert hook task type from char(16) to varchar(16) and trim the column", convertHookTaskTypeToVarcharAndTrim), + NewMigration("Convert hook task type from char(16) to varchar(16) and trim the column", v1_14.ConvertHookTaskTypeToVarcharAndTrim), // v166 -> v167 - NewMigration("Where Password is Valid with Empty String delete it", recalculateUserEmptyPWD), + NewMigration("Where Password is Valid with Empty String delete it", v1_14.RecalculateUserEmptyPWD), // v167 -> v168 - NewMigration("Add user redirect", addUserRedirect), + NewMigration("Add user redirect", v1_14.AddUserRedirect), // v168 -> v169 - NewMigration("Recreate user table to fix default values", recreateUserTableToFixDefaultValues), + NewMigration("Recreate user table to fix default values", v1_14.RecreateUserTableToFixDefaultValues), // v169 -> v170 - NewMigration("Update DeleteBranch comments to set the old_ref to the commit_sha", commentTypeDeleteBranchUseOldRef), + NewMigration("Update DeleteBranch comments to set the old_ref to the commit_sha", v1_14.CommentTypeDeleteBranchUseOldRef), // v170 -> v171 - NewMigration("Add Dismissed to Review table", addDismissedReviewColumn), + NewMigration("Add Dismissed to Review table", v1_14.AddDismissedReviewColumn), // v171 -> v172 - NewMigration("Add Sorting to ProjectBoard table", addSortingColToProjectBoard), + NewMigration("Add Sorting to ProjectBoard table", v1_14.AddSortingColToProjectBoard), // v172 -> v173 - NewMigration("Add sessions table for go-chi/session", addSessionTable), + NewMigration("Add sessions table for go-chi/session", v1_14.AddSessionTable), // v173 -> v174 - NewMigration("Add time_id column to Comment", addTimeIDCommentColumn), + NewMigration("Add time_id column to Comment", v1_14.AddTimeIDCommentColumn), // v174 -> v175 - NewMigration("Create repo transfer table", addRepoTransfer), + NewMigration("Create repo transfer table", v1_14.AddRepoTransfer), // v175 -> v176 - NewMigration("Fix Postgres ID Sequences broken by recreate-table", fixPostgresIDSequences), + NewMigration("Fix Postgres ID Sequences broken by recreate-table", v1_14.FixPostgresIDSequences), // v176 -> v177 - NewMigration("Remove invalid labels from comments", removeInvalidLabels), + NewMigration("Remove invalid labels from comments", v1_14.RemoveInvalidLabels), // v177 -> v178 - NewMigration("Delete orphaned IssueLabels", deleteOrphanedIssueLabels), + NewMigration("Delete orphaned IssueLabels", v1_14.DeleteOrphanedIssueLabels), // Gitea 1.14.0 ends at v178 // v178 -> v179 - NewMigration("Add LFS columns to Mirror", addLFSMirrorColumns), + NewMigration("Add LFS columns to Mirror", v1_15.AddLFSMirrorColumns), // v179 -> v180 - NewMigration("Convert avatar url to text", convertAvatarURLToText), + NewMigration("Convert avatar url to text", v1_15.ConvertAvatarURLToText), // v180 -> v181 - NewMigration("Delete credentials from past migrations", deleteMigrationCredentials), + NewMigration("Delete credentials from past migrations", v1_15.DeleteMigrationCredentials), // v181 -> v182 - NewMigration("Always save primary email on email address table", addPrimaryEmail2EmailAddress), + NewMigration("Always save primary email on email address table", v1_15.AddPrimaryEmail2EmailAddress), // v182 -> v183 - NewMigration("Add issue resource index table", addIssueResourceIndexTable), + NewMigration("Add issue resource index table", v1_15.AddIssueResourceIndexTable), // v183 -> v184 - NewMigration("Create PushMirror table", createPushMirrorTable), + NewMigration("Create PushMirror table", v1_15.CreatePushMirrorTable), // v184 -> v185 - NewMigration("Rename Task errors to message", renameTaskErrorsToMessage), + NewMigration("Rename Task errors to message", v1_15.RenameTaskErrorsToMessage), // v185 -> v186 - NewMigration("Add new table repo_archiver", addRepoArchiver), + NewMigration("Add new table repo_archiver", v1_15.AddRepoArchiver), // v186 -> v187 - NewMigration("Create protected tag table", createProtectedTagTable), + NewMigration("Create protected tag table", v1_15.CreateProtectedTagTable), // v187 -> v188 - NewMigration("Drop unneeded webhook related columns", dropWebhookColumns), + NewMigration("Drop unneeded webhook related columns", v1_15.DropWebhookColumns), // v188 -> v189 - NewMigration("Add key is verified to gpg key", addKeyIsVerified), + NewMigration("Add key is verified to gpg key", v1_15.AddKeyIsVerified), // Gitea 1.15.0 ends at v189 // v189 -> v190 - NewMigration("Unwrap ldap.Sources", unwrapLDAPSourceCfg), + NewMigration("Unwrap ldap.Sources", v1_16.UnwrapLDAPSourceCfg), // v190 -> v191 - NewMigration("Add agit flow pull request support", addAgitFlowPullRequest), + NewMigration("Add agit flow pull request support", v1_16.AddAgitFlowPullRequest), // v191 -> v192 - NewMigration("Alter issue/comment table TEXT fields to LONGTEXT", alterIssueAndCommentTextFieldsToLongText), + NewMigration("Alter issue/comment table TEXT fields to LONGTEXT", v1_16.AlterIssueAndCommentTextFieldsToLongText), // v192 -> v193 - NewMigration("RecreateIssueResourceIndexTable to have a primary key instead of an unique index", recreateIssueResourceIndexTable), + NewMigration("RecreateIssueResourceIndexTable to have a primary key instead of an unique index", v1_16.RecreateIssueResourceIndexTable), // v193 -> v194 - NewMigration("Add repo id column for attachment table", addRepoIDForAttachment), + NewMigration("Add repo id column for attachment table", v1_16.AddRepoIDForAttachment), // v194 -> v195 - NewMigration("Add Branch Protection Unprotected Files Column", addBranchProtectionUnprotectedFilesColumn), + NewMigration("Add Branch Protection Unprotected Files Column", v1_16.AddBranchProtectionUnprotectedFilesColumn), // v195 -> v196 - NewMigration("Add table commit_status_index", addTableCommitStatusIndex), + NewMigration("Add table commit_status_index", v1_16.AddTableCommitStatusIndex), // v196 -> v197 - NewMigration("Add Color to ProjectBoard table", addColorColToProjectBoard), + NewMigration("Add Color to ProjectBoard table", v1_16.AddColorColToProjectBoard), // v197 -> v198 - NewMigration("Add renamed_branch table", addRenamedBranchTable), + NewMigration("Add renamed_branch table", v1_16.AddRenamedBranchTable), // v198 -> v199 - NewMigration("Add issue content history table", addTableIssueContentHistory), + NewMigration("Add issue content history table", v1_16.AddTableIssueContentHistory), // v199 -> v200 NewMigration("No-op (remote version is using AppState now)", noopMigration), // v200 -> v201 - NewMigration("Add table app_state", addTableAppState), + NewMigration("Add table app_state", v1_16.AddTableAppState), // v201 -> v202 - NewMigration("Drop table remote_version (if exists)", dropTableRemoteVersion), + NewMigration("Drop table remote_version (if exists)", v1_16.DropTableRemoteVersion), // v202 -> v203 - NewMigration("Create key/value table for user settings", createUserSettingsTable), + NewMigration("Create key/value table for user settings", v1_16.CreateUserSettingsTable), // v203 -> v204 - NewMigration("Add Sorting to ProjectIssue table", addProjectIssueSorting), + NewMigration("Add Sorting to ProjectIssue table", v1_16.AddProjectIssueSorting), // v204 -> v205 - NewMigration("Add key is verified to ssh key", addSSHKeyIsVerified), + NewMigration("Add key is verified to ssh key", v1_16.AddSSHKeyIsVerified), // v205 -> v206 - NewMigration("Migrate to higher varchar on user struct", migrateUserPasswordSalt), + NewMigration("Migrate to higher varchar on user struct", v1_16.MigrateUserPasswordSalt), // v206 -> v207 - NewMigration("Add authorize column to team_unit table", addAuthorizeColForTeamUnit), + NewMigration("Add authorize column to team_unit table", v1_16.AddAuthorizeColForTeamUnit), // v207 -> v208 - NewMigration("Add webauthn table and migrate u2f data to webauthn - NO-OPED", addWebAuthnCred), + NewMigration("Add webauthn table and migrate u2f data to webauthn - NO-OPED", v1_16.AddWebAuthnCred), // v208 -> v209 - NewMigration("Use base32.HexEncoding instead of base64 encoding for cred ID as it is case insensitive - NO-OPED", useBase32HexForCredIDInWebAuthnCredential), + NewMigration("Use base32.HexEncoding instead of base64 encoding for cred ID as it is case insensitive - NO-OPED", v1_16.UseBase32HexForCredIDInWebAuthnCredential), // v209 -> v210 - NewMigration("Increase WebAuthentication CredentialID size to 410 - NO-OPED", increaseCredentialIDTo410), + NewMigration("Increase WebAuthentication CredentialID size to 410 - NO-OPED", v1_16.IncreaseCredentialIDTo410), // v210 -> v211 - NewMigration("v208 was completely broken - remigrate", remigrateU2FCredentials), + NewMigration("v208 was completely broken - remigrate", v1_16.RemigrateU2FCredentials), // Gitea 1.16.2 ends at v211 // v211 -> v212 - NewMigration("Create ForeignReference table", createForeignReferenceTable), + NewMigration("Create ForeignReference table", v1_17.CreateForeignReferenceTable), // v212 -> v213 - NewMigration("Add package tables", addPackageTables), + NewMigration("Add package tables", v1_17.AddPackageTables), // v213 -> v214 - NewMigration("Add allow edits from maintainers to PullRequest table", addAllowMaintainerEdit), + NewMigration("Add allow edits from maintainers to PullRequest table", v1_17.AddAllowMaintainerEdit), // v214 -> v215 - NewMigration("Add auto merge table", addAutoMergeTable), + NewMigration("Add auto merge table", v1_17.AddAutoMergeTable), // v215 -> v216 - NewMigration("allow to view files in PRs", addReviewViewedFiles), + NewMigration("allow to view files in PRs", v1_17.AddReviewViewedFiles), // v216 -> v217 NewMigration("No-op (Improve Action table indices v1)", noopMigration), // v217 -> v218 - NewMigration("Alter hook_task table TEXT fields to LONGTEXT", alterHookTaskTextFieldsToLongText), + NewMigration("Alter hook_task table TEXT fields to LONGTEXT", v1_17.AlterHookTaskTextFieldsToLongText), // v218 -> v219 - NewMigration("Improve Action table indices v2", improveActionTableIndices), + NewMigration("Improve Action table indices v2", v1_17.ImproveActionTableIndices), // v219 -> v220 - NewMigration("Add sync_on_commit column to push_mirror table", addSyncOnCommitColForPushMirror), + NewMigration("Add sync_on_commit column to push_mirror table", v1_17.AddSyncOnCommitColForPushMirror), // v220 -> v221 - NewMigration("Add container repository property", addContainerRepositoryProperty), + NewMigration("Add container repository property", v1_17.AddContainerRepositoryProperty), // v221 -> v222 - NewMigration("Store WebAuthentication CredentialID as bytes and increase size to at least 1024", storeWebauthnCredentialIDAsBytes), + NewMigration("Store WebAuthentication CredentialID as bytes and increase size to at least 1024", v1_17.StoreWebauthnCredentialIDAsBytes), // v222 -> v223 - NewMigration("Drop old CredentialID column", dropOldCredentialIDColumn), + NewMigration("Drop old CredentialID column", v1_17.DropOldCredentialIDColumn), // v223 -> v224 - NewMigration("Rename CredentialIDBytes column to CredentialID", renameCredentialIDBytes), + NewMigration("Rename CredentialIDBytes column to CredentialID", v1_17.RenameCredentialIDBytes), // Gitea 1.17.0 ends at v224 // v224 -> v225 - NewMigration("Add badges to users", createUserBadgesTable), + NewMigration("Add badges to users", v1_18.CreateUserBadgesTable), // v225 -> v226 - NewMigration("Alter gpg_key/public_key content TEXT fields to MEDIUMTEXT", alterPublicGPGKeyContentFieldsToMediumText), + NewMigration("Alter gpg_key/public_key content TEXT fields to MEDIUMTEXT", v1_18.AlterPublicGPGKeyContentFieldsToMediumText), // v226 -> v227 - NewMigration("Conan and generic packages do not need to be semantically versioned", fixPackageSemverField), + NewMigration("Conan and generic packages do not need to be semantically versioned", v1_18.FixPackageSemverField), // v227 -> v228 - NewMigration("Create key/value table for system settings", createSystemSettingsTable), + NewMigration("Create key/value table for system settings", v1_18.CreateSystemSettingsTable), // v228 -> v229 - NewMigration("Add TeamInvite table", addTeamInviteTable), + NewMigration("Add TeamInvite table", v1_18.AddTeamInviteTable), // v229 -> v230 - NewMigration("Update counts of all open milestones", updateOpenMilestoneCounts), + NewMigration("Update counts of all open milestones", v1_18.UpdateOpenMilestoneCounts), // v230 -> v231 - NewMigration("Add ConfidentialClient column (default true) to OAuth2Application table", addConfidentialClientColumnToOAuth2ApplicationTable), + NewMigration("Add ConfidentialClient column (default true) to OAuth2Application table", v1_18.AddConfidentialClientColumnToOAuth2ApplicationTable), // v231 -> v232 - NewMigration("Add index for hook_task", addIndexForHookTask), + NewMigration("Add index for hook_task", v1_19.AddIndexForHookTask), } // GetCurrentDBVersion returns the current db version @@ -530,499 +538,3 @@ Please try upgrading to a lower version first (suggested v1.6.4), then upgrade t } return nil } - -// RecreateTables will recreate the tables for the provided beans using the newly provided bean definition and move all data to that new table -// WARNING: YOU MUST PROVIDE THE FULL BEAN DEFINITION -func RecreateTables(beans ...interface{}) func(*xorm.Engine) error { - return func(x *xorm.Engine) error { - sess := x.NewSession() - defer sess.Close() - if err := sess.Begin(); err != nil { - return err - } - sess = sess.StoreEngine("InnoDB") - for _, bean := range beans { - log.Info("Recreating Table: %s for Bean: %s", x.TableName(bean), reflect.Indirect(reflect.ValueOf(bean)).Type().Name()) - if err := recreateTable(sess, bean); err != nil { - return err - } - } - return sess.Commit() - } -} - -// recreateTable will recreate the table using the newly provided bean definition and move all data to that new table -// WARNING: YOU MUST PROVIDE THE FULL BEAN DEFINITION -// WARNING: YOU MUST COMMIT THE SESSION AT THE END -func recreateTable(sess *xorm.Session, bean interface{}) error { - // TODO: This will not work if there are foreign keys - - tableName := sess.Engine().TableName(bean) - tempTableName := fmt.Sprintf("tmp_recreate__%s", tableName) - - // We need to move the old table away and create a new one with the correct columns - // We will need to do this in stages to prevent data loss - // - // First create the temporary table - if err := sess.Table(tempTableName).CreateTable(bean); err != nil { - log.Error("Unable to create table %s. Error: %v", tempTableName, err) - return err - } - - if err := sess.Table(tempTableName).CreateUniques(bean); err != nil { - log.Error("Unable to create uniques for table %s. Error: %v", tempTableName, err) - return err - } - - if err := sess.Table(tempTableName).CreateIndexes(bean); err != nil { - log.Error("Unable to create indexes for table %s. Error: %v", tempTableName, err) - return err - } - - // Work out the column names from the bean - these are the columns to select from the old table and install into the new table - table, err := sess.Engine().TableInfo(bean) - if err != nil { - log.Error("Unable to get table info. Error: %v", err) - - return err - } - newTableColumns := table.Columns() - if len(newTableColumns) == 0 { - return fmt.Errorf("no columns in new table") - } - hasID := false - for _, column := range newTableColumns { - hasID = hasID || (column.IsPrimaryKey && column.IsAutoIncrement) - } - - if hasID && setting.Database.UseMSSQL { - if _, err := sess.Exec(fmt.Sprintf("SET IDENTITY_INSERT `%s` ON", tempTableName)); err != nil { - log.Error("Unable to set identity insert for table %s. Error: %v", tempTableName, err) - return err - } - } - - sqlStringBuilder := &strings.Builder{} - _, _ = sqlStringBuilder.WriteString("INSERT INTO `") - _, _ = sqlStringBuilder.WriteString(tempTableName) - _, _ = sqlStringBuilder.WriteString("` (`") - _, _ = sqlStringBuilder.WriteString(newTableColumns[0].Name) - _, _ = sqlStringBuilder.WriteString("`") - for _, column := range newTableColumns[1:] { - _, _ = sqlStringBuilder.WriteString(", `") - _, _ = sqlStringBuilder.WriteString(column.Name) - _, _ = sqlStringBuilder.WriteString("`") - } - _, _ = sqlStringBuilder.WriteString(")") - _, _ = sqlStringBuilder.WriteString(" SELECT ") - if newTableColumns[0].Default != "" { - _, _ = sqlStringBuilder.WriteString("COALESCE(`") - _, _ = sqlStringBuilder.WriteString(newTableColumns[0].Name) - _, _ = sqlStringBuilder.WriteString("`, ") - _, _ = sqlStringBuilder.WriteString(newTableColumns[0].Default) - _, _ = sqlStringBuilder.WriteString(")") - } else { - _, _ = sqlStringBuilder.WriteString("`") - _, _ = sqlStringBuilder.WriteString(newTableColumns[0].Name) - _, _ = sqlStringBuilder.WriteString("`") - } - - for _, column := range newTableColumns[1:] { - if column.Default != "" { - _, _ = sqlStringBuilder.WriteString(", COALESCE(`") - _, _ = sqlStringBuilder.WriteString(column.Name) - _, _ = sqlStringBuilder.WriteString("`, ") - _, _ = sqlStringBuilder.WriteString(column.Default) - _, _ = sqlStringBuilder.WriteString(")") - } else { - _, _ = sqlStringBuilder.WriteString(", `") - _, _ = sqlStringBuilder.WriteString(column.Name) - _, _ = sqlStringBuilder.WriteString("`") - } - } - _, _ = sqlStringBuilder.WriteString(" FROM `") - _, _ = sqlStringBuilder.WriteString(tableName) - _, _ = sqlStringBuilder.WriteString("`") - - if _, err := sess.Exec(sqlStringBuilder.String()); err != nil { - log.Error("Unable to set copy data in to temp table %s. Error: %v", tempTableName, err) - return err - } - - if hasID && setting.Database.UseMSSQL { - if _, err := sess.Exec(fmt.Sprintf("SET IDENTITY_INSERT `%s` OFF", tempTableName)); err != nil { - log.Error("Unable to switch off identity insert for table %s. Error: %v", tempTableName, err) - return err - } - } - - switch { - case setting.Database.UseSQLite3: - // SQLite will drop all the constraints on the old table - if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil { - log.Error("Unable to drop old table %s. Error: %v", tableName, err) - return err - } - - if err := sess.Table(tempTableName).DropIndexes(bean); err != nil { - log.Error("Unable to drop indexes on temporary table %s. Error: %v", tempTableName, err) - return err - } - - if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` RENAME TO `%s`", tempTableName, tableName)); err != nil { - log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err) - return err - } - - if err := sess.Table(tableName).CreateIndexes(bean); err != nil { - log.Error("Unable to recreate indexes on table %s. Error: %v", tableName, err) - return err - } - - if err := sess.Table(tableName).CreateUniques(bean); err != nil { - log.Error("Unable to recreate uniques on table %s. Error: %v", tableName, err) - return err - } - - case setting.Database.UseMySQL: - // MySQL will drop all the constraints on the old table - if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil { - log.Error("Unable to drop old table %s. Error: %v", tableName, err) - return err - } - - if err := sess.Table(tempTableName).DropIndexes(bean); err != nil { - log.Error("Unable to drop indexes on temporary table %s. Error: %v", tempTableName, err) - return err - } - - // SQLite and MySQL will move all the constraints from the temporary table to the new table - if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` RENAME TO `%s`", tempTableName, tableName)); err != nil { - log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err) - return err - } - - if err := sess.Table(tableName).CreateIndexes(bean); err != nil { - log.Error("Unable to recreate indexes on table %s. Error: %v", tableName, err) - return err - } - - if err := sess.Table(tableName).CreateUniques(bean); err != nil { - log.Error("Unable to recreate uniques on table %s. Error: %v", tableName, err) - return err - } - case setting.Database.UsePostgreSQL: - var originalSequences []string - type sequenceData struct { - LastValue int `xorm:"'last_value'"` - IsCalled bool `xorm:"'is_called'"` - } - sequenceMap := map[string]sequenceData{} - - schema := sess.Engine().Dialect().URI().Schema - sess.Engine().SetSchema("") - if err := sess.Table("information_schema.sequences").Cols("sequence_name").Where("sequence_name LIKE ? || '_%' AND sequence_catalog = ?", tableName, setting.Database.Name).Find(&originalSequences); err != nil { - log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err) - return err - } - sess.Engine().SetSchema(schema) - - for _, sequence := range originalSequences { - sequenceData := sequenceData{} - if _, err := sess.Table(sequence).Cols("last_value", "is_called").Get(&sequenceData); err != nil { - log.Error("Unable to get last_value and is_called from %s. Error: %v", sequence, err) - return err - } - sequenceMap[sequence] = sequenceData - - } - - // CASCADE causes postgres to drop all the constraints on the old table - if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s` CASCADE", tableName)); err != nil { - log.Error("Unable to drop old table %s. Error: %v", tableName, err) - return err - } - - // CASCADE causes postgres to move all the constraints from the temporary table to the new table - if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` RENAME TO `%s`", tempTableName, tableName)); err != nil { - log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err) - return err - } - - var indices []string - sess.Engine().SetSchema("") - if err := sess.Table("pg_indexes").Cols("indexname").Where("tablename = ? ", tableName).Find(&indices); err != nil { - log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err) - return err - } - sess.Engine().SetSchema(schema) - - for _, index := range indices { - newIndexName := strings.Replace(index, "tmp_recreate__", "", 1) - if _, err := sess.Exec(fmt.Sprintf("ALTER INDEX `%s` RENAME TO `%s`", index, newIndexName)); err != nil { - log.Error("Unable to rename %s to %s. Error: %v", index, newIndexName, err) - return err - } - } - - var sequences []string - sess.Engine().SetSchema("") - if err := sess.Table("information_schema.sequences").Cols("sequence_name").Where("sequence_name LIKE 'tmp_recreate__' || ? || '_%' AND sequence_catalog = ?", tableName, setting.Database.Name).Find(&sequences); err != nil { - log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err) - return err - } - sess.Engine().SetSchema(schema) - - for _, sequence := range sequences { - newSequenceName := strings.Replace(sequence, "tmp_recreate__", "", 1) - if _, err := sess.Exec(fmt.Sprintf("ALTER SEQUENCE `%s` RENAME TO `%s`", sequence, newSequenceName)); err != nil { - log.Error("Unable to rename %s sequence to %s. Error: %v", sequence, newSequenceName, err) - return err - } - val, ok := sequenceMap[newSequenceName] - if newSequenceName == tableName+"_id_seq" { - if ok && val.LastValue != 0 { - if _, err := sess.Exec(fmt.Sprintf("SELECT setval('%s', %d, %t)", newSequenceName, val.LastValue, val.IsCalled)); err != nil { - log.Error("Unable to reset %s to %d. Error: %v", newSequenceName, val, err) - return err - } - } else { - // We're going to try to guess this - if _, err := sess.Exec(fmt.Sprintf("SELECT setval('%s', COALESCE((SELECT MAX(id)+1 FROM `%s`), 1), false)", newSequenceName, tableName)); err != nil { - log.Error("Unable to reset %s. Error: %v", newSequenceName, err) - return err - } - } - } else if ok { - if _, err := sess.Exec(fmt.Sprintf("SELECT setval('%s', %d, %t)", newSequenceName, val.LastValue, val.IsCalled)); err != nil { - log.Error("Unable to reset %s to %d. Error: %v", newSequenceName, val, err) - return err - } - } - - } - - case setting.Database.UseMSSQL: - // MSSQL will drop all the constraints on the old table - if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil { - log.Error("Unable to drop old table %s. Error: %v", tableName, err) - return err - } - - // MSSQL sp_rename will move all the constraints from the temporary table to the new table - if _, err := sess.Exec(fmt.Sprintf("sp_rename `%s`,`%s`", tempTableName, tableName)); err != nil { - log.Error("Unable to rename %s to %s. Error: %v", tempTableName, tableName, err) - return err - } - - default: - log.Fatal("Unrecognized DB") - } - return nil -} - -// WARNING: YOU MUST COMMIT THE SESSION AT THE END -func dropTableColumns(sess *xorm.Session, tableName string, columnNames ...string) (err error) { - if tableName == "" || len(columnNames) == 0 { - return nil - } - // TODO: This will not work if there are foreign keys - - switch { - case setting.Database.UseSQLite3: - // First drop the indexes on the columns - res, errIndex := sess.Query(fmt.Sprintf("PRAGMA index_list(`%s`)", tableName)) - if errIndex != nil { - return errIndex - } - for _, row := range res { - indexName := row["name"] - indexRes, err := sess.Query(fmt.Sprintf("PRAGMA index_info(`%s`)", indexName)) - if err != nil { - return err - } - if len(indexRes) != 1 { - continue - } - indexColumn := string(indexRes[0]["name"]) - for _, name := range columnNames { - if name == indexColumn { - _, err := sess.Exec(fmt.Sprintf("DROP INDEX `%s`", indexName)) - if err != nil { - return err - } - } - } - } - - // Here we need to get the columns from the original table - sql := fmt.Sprintf("SELECT sql FROM sqlite_master WHERE tbl_name='%s' and type='table'", tableName) - res, err := sess.Query(sql) - if err != nil { - return err - } - tableSQL := string(res[0]["sql"]) - - // Get the string offset for column definitions: `CREATE TABLE ( column-definitions... )` - columnDefinitionsIndex := strings.Index(tableSQL, "(") - if columnDefinitionsIndex < 0 { - return errors.New("couldn't find column definitions") - } - - // Separate out the column definitions - tableSQL = tableSQL[columnDefinitionsIndex:] - - // Remove the required columnNames - for _, name := range columnNames { - tableSQL = regexp.MustCompile(regexp.QuoteMeta("`"+name+"`")+"[^`,)]*?[,)]").ReplaceAllString(tableSQL, "") - } - - // Ensure the query is ended properly - tableSQL = strings.TrimSpace(tableSQL) - if tableSQL[len(tableSQL)-1] != ')' { - if tableSQL[len(tableSQL)-1] == ',' { - tableSQL = tableSQL[:len(tableSQL)-1] - } - tableSQL += ")" - } - - // Find all the columns in the table - columns := regexp.MustCompile("`([^`]*)`").FindAllString(tableSQL, -1) - - tableSQL = fmt.Sprintf("CREATE TABLE `new_%s_new` ", tableName) + tableSQL - if _, err := sess.Exec(tableSQL); err != nil { - return err - } - - // Now restore the data - columnsSeparated := strings.Join(columns, ",") - insertSQL := fmt.Sprintf("INSERT INTO `new_%s_new` (%s) SELECT %s FROM %s", tableName, columnsSeparated, columnsSeparated, tableName) - if _, err := sess.Exec(insertSQL); err != nil { - return err - } - - // Now drop the old table - if _, err := sess.Exec(fmt.Sprintf("DROP TABLE `%s`", tableName)); err != nil { - return err - } - - // Rename the table - if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `new_%s_new` RENAME TO `%s`", tableName, tableName)); err != nil { - return err - } - - case setting.Database.UsePostgreSQL: - cols := "" - for _, col := range columnNames { - if cols != "" { - cols += ", " - } - cols += "DROP COLUMN `" + col + "` CASCADE" - } - if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` %s", tableName, cols)); err != nil { - return fmt.Errorf("Drop table `%s` columns %v: %w", tableName, columnNames, err) - } - case setting.Database.UseMySQL: - // Drop indexes on columns first - sql := fmt.Sprintf("SHOW INDEX FROM %s WHERE column_name IN ('%s')", tableName, strings.Join(columnNames, "','")) - res, err := sess.Query(sql) - if err != nil { - return err - } - for _, index := range res { - indexName := index["column_name"] - if len(indexName) > 0 { - _, err := sess.Exec(fmt.Sprintf("DROP INDEX `%s` ON `%s`", indexName, tableName)) - if err != nil { - return err - } - } - } - - // Now drop the columns - cols := "" - for _, col := range columnNames { - if cols != "" { - cols += ", " - } - cols += "DROP COLUMN `" + col + "`" - } - if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` %s", tableName, cols)); err != nil { - return fmt.Errorf("Drop table `%s` columns %v: %w", tableName, columnNames, err) - } - case setting.Database.UseMSSQL: - cols := "" - for _, col := range columnNames { - if cols != "" { - cols += ", " - } - cols += "`" + strings.ToLower(col) + "`" - } - sql := fmt.Sprintf("SELECT Name FROM sys.default_constraints WHERE parent_object_id = OBJECT_ID('%[1]s') AND parent_column_id IN (SELECT column_id FROM sys.columns WHERE LOWER(name) IN (%[2]s) AND object_id = OBJECT_ID('%[1]s'))", - tableName, strings.ReplaceAll(cols, "`", "'")) - constraints := make([]string, 0) - if err := sess.SQL(sql).Find(&constraints); err != nil { - return fmt.Errorf("Find constraints: %w", err) - } - for _, constraint := range constraints { - if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` DROP CONSTRAINT `%s`", tableName, constraint)); err != nil { - return fmt.Errorf("Drop table `%s` default constraint `%s`: %w", tableName, constraint, err) - } - } - sql = fmt.Sprintf("SELECT DISTINCT Name FROM sys.indexes INNER JOIN sys.index_columns ON indexes.index_id = index_columns.index_id AND indexes.object_id = index_columns.object_id WHERE indexes.object_id = OBJECT_ID('%[1]s') AND index_columns.column_id IN (SELECT column_id FROM sys.columns WHERE LOWER(name) IN (%[2]s) AND object_id = OBJECT_ID('%[1]s'))", - tableName, strings.ReplaceAll(cols, "`", "'")) - constraints = make([]string, 0) - if err := sess.SQL(sql).Find(&constraints); err != nil { - return fmt.Errorf("Find constraints: %w", err) - } - for _, constraint := range constraints { - if _, err := sess.Exec(fmt.Sprintf("DROP INDEX `%[2]s` ON `%[1]s`", tableName, constraint)); err != nil { - return fmt.Errorf("Drop index `%s` on `%s`: %w", constraint, tableName, err) - } - } - - if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `%s` DROP COLUMN %s", tableName, cols)); err != nil { - return fmt.Errorf("Drop table `%s` columns %v: %w", tableName, columnNames, err) - } - default: - log.Fatal("Unrecognized DB") - } - - return nil -} - -// modifyColumn will modify column's type or other property. SQLITE is not supported -func modifyColumn(x *xorm.Engine, tableName string, col *schemas.Column) error { - var indexes map[string]*schemas.Index - var err error - // MSSQL have to remove index at first, otherwise alter column will fail - // ref. https://sqlzealots.com/2018/05/09/error-message-the-index-is-dependent-on-column-alter-table-alter-column-failed-because-one-or-more-objects-access-this-column/ - if x.Dialect().URI().DBType == schemas.MSSQL { - indexes, err = x.Dialect().GetIndexes(x.DB(), context.Background(), tableName) - if err != nil { - return err - } - - for _, index := range indexes { - _, err = x.Exec(x.Dialect().DropIndexSQL(tableName, index)) - if err != nil { - return err - } - } - } - - defer func() { - for _, index := range indexes { - _, err = x.Exec(x.Dialect().CreateIndexSQL(tableName, index)) - if err != nil { - log.Error("Create index %s on table %s failed: %v", index.Name, tableName, err) - } - } - }() - - alterSQL := x.Dialect().ModifyColumnSQL(tableName, col) - if _, err := x.Exec(alterSQL); err != nil { - return err - } - return nil -} diff --git a/models/migrations/migrations_test.go b/models/migrations/migrations_test.go deleted file mode 100644 index 5cd70626b46c..000000000000 --- a/models/migrations/migrations_test.go +++ /dev/null @@ -1,365 +0,0 @@ -// Copyright 2021 The Gitea Authors. All rights reserved. -// Use of this source code is governed by a MIT-style -// license that can be found in the LICENSE file. - -package migrations - -import ( - "context" - "database/sql" - "fmt" - "os" - "path" - "path/filepath" - "runtime" - "testing" - "time" - - "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/models/unittest" - "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/git" - "code.gitea.io/gitea/modules/setting" - "code.gitea.io/gitea/modules/timeutil" - "code.gitea.io/gitea/modules/util" - - "github.com/stretchr/testify/assert" - "xorm.io/xorm" - "xorm.io/xorm/names" -) - -func TestMain(m *testing.M) { - giteaRoot := base.SetupGiteaRoot() - if giteaRoot == "" { - fmt.Println("Environment variable $GITEA_ROOT not set") - os.Exit(1) - } - giteaBinary := "gitea" - if runtime.GOOS == "windows" { - giteaBinary += ".exe" - } - setting.AppPath = path.Join(giteaRoot, giteaBinary) - if _, err := os.Stat(setting.AppPath); err != nil { - fmt.Printf("Could not find gitea binary at %s\n", setting.AppPath) - os.Exit(1) - } - - giteaConf := os.Getenv("GITEA_CONF") - if giteaConf == "" { - giteaConf = path.Join(filepath.Dir(setting.AppPath), "tests/sqlite.ini") - fmt.Printf("Environment variable $GITEA_CONF not set - defaulting to %s\n", giteaConf) - } - - if !path.IsAbs(giteaConf) { - setting.CustomConf = path.Join(giteaRoot, giteaConf) - } else { - setting.CustomConf = giteaConf - } - - tmpDataPath, err := os.MkdirTemp("", "data") - if err != nil { - fmt.Printf("Unable to create temporary data path %v\n", err) - os.Exit(1) - } - - setting.AppDataPath = tmpDataPath - - setting.SetCustomPathAndConf("", "", "") - setting.LoadForTest() - if err = git.InitFull(context.Background()); err != nil { - fmt.Printf("Unable to InitFull: %v\n", err) - os.Exit(1) - } - setting.InitDBConfig() - setting.NewLogServices(true) - - exitStatus := m.Run() - - if err := removeAllWithRetry(setting.RepoRootPath); err != nil { - fmt.Fprintf(os.Stderr, "os.RemoveAll: %v\n", err) - } - if err := removeAllWithRetry(tmpDataPath); err != nil { - fmt.Fprintf(os.Stderr, "os.RemoveAll: %v\n", err) - } - os.Exit(exitStatus) -} - -func removeAllWithRetry(dir string) error { - var err error - for i := 0; i < 20; i++ { - err = os.RemoveAll(dir) - if err == nil { - break - } - time.Sleep(100 * time.Millisecond) - } - return err -} - -func newXORMEngine() (*xorm.Engine, error) { - if err := db.InitEngine(context.Background()); err != nil { - return nil, err - } - x := unittest.GetXORMEngine() - return x, nil -} - -func deleteDB() error { - switch { - case setting.Database.UseSQLite3: - if err := util.Remove(setting.Database.Path); err != nil { - return err - } - return os.MkdirAll(path.Dir(setting.Database.Path), os.ModePerm) - - case setting.Database.UseMySQL: - db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/", - setting.Database.User, setting.Database.Passwd, setting.Database.Host)) - if err != nil { - return err - } - defer db.Close() - - if _, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS %s", setting.Database.Name)); err != nil { - return err - } - - if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", setting.Database.Name)); err != nil { - return err - } - return nil - case setting.Database.UsePostgreSQL: - db, err := sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/?sslmode=%s", - setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.SSLMode)) - if err != nil { - return err - } - defer db.Close() - - if _, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS %s", setting.Database.Name)); err != nil { - return err - } - - if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s", setting.Database.Name)); err != nil { - return err - } - db.Close() - - // Check if we need to setup a specific schema - if len(setting.Database.Schema) != 0 { - db, err = sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=%s", - setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.Name, setting.Database.SSLMode)) - if err != nil { - return err - } - defer db.Close() - - schrows, err := db.Query(fmt.Sprintf("SELECT 1 FROM information_schema.schemata WHERE schema_name = '%s'", setting.Database.Schema)) - if err != nil { - return err - } - defer schrows.Close() - - if !schrows.Next() { - // Create and setup a DB schema - _, err = db.Exec(fmt.Sprintf("CREATE SCHEMA %s", setting.Database.Schema)) - if err != nil { - return err - } - } - - // Make the user's default search path the created schema; this will affect new connections - _, err = db.Exec(fmt.Sprintf(`ALTER USER "%s" SET search_path = %s`, setting.Database.User, setting.Database.Schema)) - if err != nil { - return err - } - return nil - } - case setting.Database.UseMSSQL: - host, port := setting.ParseMSSQLHostPort(setting.Database.Host) - db, err := sql.Open("mssql", fmt.Sprintf("server=%s; port=%s; database=%s; user id=%s; password=%s;", - host, port, "master", setting.Database.User, setting.Database.Passwd)) - if err != nil { - return err - } - defer db.Close() - - if _, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS [%s]", setting.Database.Name)); err != nil { - return err - } - if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE [%s]", setting.Database.Name)); err != nil { - return err - } - } - - return nil -} - -// prepareTestEnv prepares the test environment and reset the database. The skip parameter should usually be 0. -// Provide models to be sync'd with the database - in particular any models you expect fixtures to be loaded from. -// -// fixtures in `models/migrations/fixtures/` will be loaded automatically -func prepareTestEnv(t *testing.T, skip int, syncModels ...interface{}) (*xorm.Engine, func()) { - t.Helper() - ourSkip := 2 - ourSkip += skip - deferFn := PrintCurrentTest(t, ourSkip) - assert.NoError(t, os.RemoveAll(setting.RepoRootPath)) - assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "tests/gitea-repositories-meta"), setting.RepoRootPath)) - ownerDirs, err := os.ReadDir(setting.RepoRootPath) - if err != nil { - assert.NoError(t, err, "unable to read the new repo root: %v\n", err) - } - for _, ownerDir := range ownerDirs { - if !ownerDir.Type().IsDir() { - continue - } - repoDirs, err := os.ReadDir(filepath.Join(setting.RepoRootPath, ownerDir.Name())) - if err != nil { - assert.NoError(t, err, "unable to read the new repo root: %v\n", err) - } - for _, repoDir := range repoDirs { - _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "pack"), 0o755) - _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "info"), 0o755) - _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "refs", "heads"), 0o755) - _ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "refs", "tag"), 0o755) - } - } - - if err := deleteDB(); err != nil { - t.Errorf("unable to reset database: %v", err) - return nil, deferFn - } - - x, err := newXORMEngine() - assert.NoError(t, err) - if x != nil { - oldDefer := deferFn - deferFn = func() { - oldDefer() - if err := x.Close(); err != nil { - t.Errorf("error during close: %v", err) - } - if err := deleteDB(); err != nil { - t.Errorf("unable to reset database: %v", err) - } - } - } - if err != nil { - return x, deferFn - } - - if len(syncModels) > 0 { - if err := x.Sync2(syncModels...); err != nil { - t.Errorf("error during sync: %v", err) - return x, deferFn - } - } - - fixturesDir := filepath.Join(filepath.Dir(setting.AppPath), "models", "migrations", "fixtures", t.Name()) - - if _, err := os.Stat(fixturesDir); err == nil { - t.Logf("initializing fixtures from: %s", fixturesDir) - if err := unittest.InitFixtures( - unittest.FixturesOptions{ - Dir: fixturesDir, - }, x); err != nil { - t.Errorf("error whilst initializing fixtures from %s: %v", fixturesDir, err) - return x, deferFn - } - if err := unittest.LoadFixtures(x); err != nil { - t.Errorf("error whilst loading fixtures from %s: %v", fixturesDir, err) - return x, deferFn - } - } else if !os.IsNotExist(err) { - t.Errorf("unexpected error whilst checking for existence of fixtures: %v", err) - } else { - t.Logf("no fixtures found in: %s", fixturesDir) - } - - return x, deferFn -} - -func Test_dropTableColumns(t *testing.T) { - x, deferable := prepareTestEnv(t, 0) - if x == nil || t.Failed() { - defer deferable() - return - } - defer deferable() - - type DropTest struct { - ID int64 `xorm:"pk autoincr"` - FirstColumn string - ToDropColumn string `xorm:"unique"` - AnotherColumn int64 - CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` - UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` - } - - columns := []string{ - "first_column", - "to_drop_column", - "another_column", - "created_unix", - "updated_unix", - } - - for i := range columns { - x.SetMapper(names.GonicMapper{}) - if err := x.Sync2(new(DropTest)); err != nil { - t.Errorf("unable to create DropTest table: %v", err) - return - } - sess := x.NewSession() - if err := sess.Begin(); err != nil { - sess.Close() - t.Errorf("unable to begin transaction: %v", err) - return - } - if err := dropTableColumns(sess, "drop_test", columns[i:]...); err != nil { - sess.Close() - t.Errorf("Unable to drop columns[%d:]: %s from drop_test: %v", i, columns[i:], err) - return - } - if err := sess.Commit(); err != nil { - sess.Close() - t.Errorf("unable to commit transaction: %v", err) - return - } - sess.Close() - if err := x.DropTables(new(DropTest)); err != nil { - t.Errorf("unable to drop table: %v", err) - return - } - for j := range columns[i+1:] { - x.SetMapper(names.GonicMapper{}) - if err := x.Sync2(new(DropTest)); err != nil { - t.Errorf("unable to create DropTest table: %v", err) - return - } - dropcols := append([]string{columns[i]}, columns[j+i+1:]...) - sess := x.NewSession() - if err := sess.Begin(); err != nil { - sess.Close() - t.Errorf("unable to begin transaction: %v", err) - return - } - if err := dropTableColumns(sess, "drop_test", dropcols...); err != nil { - sess.Close() - t.Errorf("Unable to drop columns: %s from drop_test: %v", dropcols, err) - return - } - if err := sess.Commit(); err != nil { - sess.Close() - t.Errorf("unable to commit transaction: %v", err) - return - } - sess.Close() - if err := x.DropTables(new(DropTest)); err != nil { - t.Errorf("unable to drop table: %v", err) - return - } - } - } -} diff --git a/models/migrations/v100.go b/models/migrations/v1_10/v100.go similarity index 96% rename from models/migrations/v100.go rename to models/migrations/v1_10/v100.go index 0ff59e0044a2..af58b4b21d19 100644 --- a/models/migrations/v100.go +++ b/models/migrations/v1_10/v100.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_10 //nolint import ( "net/url" @@ -12,7 +12,7 @@ import ( "xorm.io/xorm" ) -func updateMigrationServiceTypes(x *xorm.Engine) error { +func UpdateMigrationServiceTypes(x *xorm.Engine) error { type Repository struct { ID int64 OriginalServiceType int `xorm:"index default(0)"` diff --git a/models/migrations/v101.go b/models/migrations/v1_10/v101.go similarity index 82% rename from models/migrations/v101.go rename to models/migrations/v1_10/v101.go index 9ef82a2933b1..350e537a97cc 100644 --- a/models/migrations/v101.go +++ b/models/migrations/v1_10/v101.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_10 //nolint import ( "xorm.io/xorm" ) -func changeSomeColumnsLengthOfExternalLoginUser(x *xorm.Engine) error { +func ChangeSomeColumnsLengthOfExternalLoginUser(x *xorm.Engine) error { type ExternalLoginUser struct { AccessToken string `xorm:"TEXT"` AccessTokenSecret string `xorm:"TEXT"` diff --git a/models/migrations/v88.go b/models/migrations/v1_10/v88.go similarity index 94% rename from models/migrations/v88.go rename to models/migrations/v1_10/v88.go index 11cc26209ac8..32659006ea9d 100644 --- a/models/migrations/v88.go +++ b/models/migrations/v1_10/v88.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_10 //nolint import ( "crypto/sha1" @@ -15,7 +15,7 @@ func hashContext(context string) string { return fmt.Sprintf("%x", sha1.Sum([]byte(context))) } -func addCommitStatusContext(x *xorm.Engine) error { +func AddCommitStatusContext(x *xorm.Engine) error { type CommitStatus struct { ID int64 `xorm:"pk autoincr"` ContextHash string `xorm:"char(40) index"` diff --git a/models/migrations/v89.go b/models/migrations/v1_10/v89.go similarity index 89% rename from models/migrations/v89.go rename to models/migrations/v1_10/v89.go index a972b07b6de1..4b21ef20ff17 100644 --- a/models/migrations/v89.go +++ b/models/migrations/v1_10/v89.go @@ -2,11 +2,11 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_10 //nolint import "xorm.io/xorm" -func addOriginalMigrationInfo(x *xorm.Engine) error { +func AddOriginalMigrationInfo(x *xorm.Engine) error { // Issue see models/issue.go type Issue struct { OriginalAuthor string diff --git a/models/migrations/v90.go b/models/migrations/v1_10/v90.go similarity index 83% rename from models/migrations/v90.go rename to models/migrations/v1_10/v90.go index 72f7534dc879..aa08ac36bc6d 100644 --- a/models/migrations/v90.go +++ b/models/migrations/v1_10/v90.go @@ -2,11 +2,11 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_10 //nolint import "xorm.io/xorm" -func changeSomeColumnsLengthOfRepo(x *xorm.Engine) error { +func ChangeSomeColumnsLengthOfRepo(x *xorm.Engine) error { type Repository struct { ID int64 `xorm:"pk autoincr"` Description string `xorm:"TEXT"` diff --git a/models/migrations/v91.go b/models/migrations/v1_10/v91.go similarity index 86% rename from models/migrations/v91.go rename to models/migrations/v1_10/v91.go index 3c49d9b96ae8..b8c083f8d4ae 100644 --- a/models/migrations/v91.go +++ b/models/migrations/v1_10/v91.go @@ -2,11 +2,11 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_10 //nolint import "xorm.io/xorm" -func addIndexOnRepositoryAndComment(x *xorm.Engine) error { +func AddIndexOnRepositoryAndComment(x *xorm.Engine) error { type Repository struct { ID int64 `xorm:"pk autoincr"` OwnerID int64 `xorm:"index"` diff --git a/models/migrations/v92.go b/models/migrations/v1_10/v92.go similarity index 82% rename from models/migrations/v92.go rename to models/migrations/v1_10/v92.go index e343dedb6869..c0552aaab5b9 100644 --- a/models/migrations/v92.go +++ b/models/migrations/v1_10/v92.go @@ -2,14 +2,14 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_10 //nolint import ( "xorm.io/builder" "xorm.io/xorm" ) -func removeLingeringIndexStatus(x *xorm.Engine) error { +func RemoveLingeringIndexStatus(x *xorm.Engine) error { _, err := x.Exec(builder.Delete(builder.NotIn("`repo_id`", builder.Select("`id`").From("`repository`"))).From("`repo_indexer_status`")) return err } diff --git a/models/migrations/v93.go b/models/migrations/v1_10/v93.go similarity index 80% rename from models/migrations/v93.go rename to models/migrations/v1_10/v93.go index 0cb9d6631fcf..6ce89f0d49b3 100644 --- a/models/migrations/v93.go +++ b/models/migrations/v1_10/v93.go @@ -2,11 +2,11 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_10 //nolint import "xorm.io/xorm" -func addEmailNotificationEnabledToUser(x *xorm.Engine) error { +func AddEmailNotificationEnabledToUser(x *xorm.Engine) error { // User see models/user.go type User struct { EmailNotificationsPreference string `xorm:"VARCHAR(20) NOT NULL DEFAULT 'enabled'"` diff --git a/models/migrations/v94.go b/models/migrations/v1_10/v94.go similarity index 87% rename from models/migrations/v94.go rename to models/migrations/v1_10/v94.go index 8c1e33b647ca..542e45c139ff 100644 --- a/models/migrations/v94.go +++ b/models/migrations/v1_10/v94.go @@ -2,11 +2,11 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_10 //nolint import "xorm.io/xorm" -func addStatusCheckColumnsForProtectedBranches(x *xorm.Engine) error { +func AddStatusCheckColumnsForProtectedBranches(x *xorm.Engine) error { type ProtectedBranch struct { EnableStatusCheck bool `xorm:"NOT NULL DEFAULT false"` StatusCheckContexts []string `xorm:"JSON TEXT"` diff --git a/models/migrations/v95.go b/models/migrations/v1_10/v95.go similarity index 85% rename from models/migrations/v95.go rename to models/migrations/v1_10/v95.go index 94787f75010d..48a0c4ea7fbc 100644 --- a/models/migrations/v95.go +++ b/models/migrations/v1_10/v95.go @@ -2,11 +2,11 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_10 //nolint import "xorm.io/xorm" -func addCrossReferenceColumns(x *xorm.Engine) error { +func AddCrossReferenceColumns(x *xorm.Engine) error { // Comment see models/comment.go type Comment struct { RefRepoID int64 `xorm:"index"` diff --git a/models/migrations/v96.go b/models/migrations/v1_10/v96.go similarity index 94% rename from models/migrations/v96.go rename to models/migrations/v1_10/v96.go index eaeab72b01bf..372ca9e65a84 100644 --- a/models/migrations/v96.go +++ b/models/migrations/v1_10/v96.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_10 //nolint import ( "path/filepath" @@ -13,7 +13,7 @@ import ( "xorm.io/xorm" ) -func deleteOrphanedAttachments(x *xorm.Engine) error { +func DeleteOrphanedAttachments(x *xorm.Engine) error { type Attachment struct { ID int64 `xorm:"pk autoincr"` UUID string `xorm:"uuid UNIQUE"` diff --git a/models/migrations/v97.go b/models/migrations/v1_10/v97.go similarity index 78% rename from models/migrations/v97.go rename to models/migrations/v1_10/v97.go index 8e58886e2e5a..4438a9ed50c5 100644 --- a/models/migrations/v97.go +++ b/models/migrations/v1_10/v97.go @@ -2,11 +2,11 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_10 //nolint import "xorm.io/xorm" -func addRepoAdminChangeTeamAccessColumnForUser(x *xorm.Engine) error { +func AddRepoAdminChangeTeamAccessColumnForUser(x *xorm.Engine) error { type User struct { RepoAdminChangeTeamAccess bool `xorm:"NOT NULL DEFAULT false"` } diff --git a/models/migrations/v98.go b/models/migrations/v1_10/v98.go similarity index 79% rename from models/migrations/v98.go rename to models/migrations/v1_10/v98.go index 617e1ec3d7d6..8e9ebb7d970b 100644 --- a/models/migrations/v98.go +++ b/models/migrations/v1_10/v98.go @@ -2,11 +2,11 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_10 //nolint import "xorm.io/xorm" -func addOriginalAuthorOnMigratedReleases(x *xorm.Engine) error { +func AddOriginalAuthorOnMigratedReleases(x *xorm.Engine) error { type Release struct { ID int64 OriginalAuthor string diff --git a/models/migrations/v99.go b/models/migrations/v1_10/v99.go similarity index 94% rename from models/migrations/v99.go rename to models/migrations/v1_10/v99.go index b6f6babcee70..21554f6effcd 100644 --- a/models/migrations/v99.go +++ b/models/migrations/v1_10/v99.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_10 //nolint import ( "code.gitea.io/gitea/modules/timeutil" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addTaskTable(x *xorm.Engine) error { +func AddTaskTable(x *xorm.Engine) error { // TaskType defines task type type TaskType int diff --git a/models/migrations/v102.go b/models/migrations/v1_11/v102.go similarity index 59% rename from models/migrations/v102.go rename to models/migrations/v1_11/v102.go index 03079d0bb441..49d9d3ae71dc 100644 --- a/models/migrations/v102.go +++ b/models/migrations/v1_11/v102.go @@ -2,19 +2,21 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_11 //nolint import ( + "code.gitea.io/gitea/models/migrations/base" + "xorm.io/xorm" ) -func dropColumnHeadUserNameOnPullRequest(x *xorm.Engine) error { +func DropColumnHeadUserNameOnPullRequest(x *xorm.Engine) error { sess := x.NewSession() defer sess.Close() if err := sess.Begin(); err != nil { return err } - if err := dropTableColumns(sess, "pull_request", "head_user_name"); err != nil { + if err := base.DropTableColumns(sess, "pull_request", "head_user_name"); err != nil { return err } return sess.Commit() diff --git a/models/migrations/v103.go b/models/migrations/v1_11/v103.go similarity index 80% rename from models/migrations/v103.go rename to models/migrations/v1_11/v103.go index fed025c5cdf0..e9114adeef89 100644 --- a/models/migrations/v103.go +++ b/models/migrations/v1_11/v103.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_11 //nolint import ( "xorm.io/xorm" ) -func addWhitelistDeployKeysToBranches(x *xorm.Engine) error { +func AddWhitelistDeployKeysToBranches(x *xorm.Engine) error { type ProtectedBranch struct { ID int64 WhitelistDeployKeys bool `xorm:"NOT NULL DEFAULT false"` diff --git a/models/migrations/v104.go b/models/migrations/v1_11/v104.go similarity index 65% rename from models/migrations/v104.go rename to models/migrations/v1_11/v104.go index 72e23640400e..0ab3682f6eba 100644 --- a/models/migrations/v104.go +++ b/models/migrations/v1_11/v104.go @@ -2,13 +2,15 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_11 //nolint import ( + "code.gitea.io/gitea/models/migrations/base" + "xorm.io/xorm" ) -func removeLabelUneededCols(x *xorm.Engine) error { +func RemoveLabelUneededCols(x *xorm.Engine) error { // Make sure the columns exist before dropping them type Label struct { QueryString string @@ -23,10 +25,10 @@ func removeLabelUneededCols(x *xorm.Engine) error { if err := sess.Begin(); err != nil { return err } - if err := dropTableColumns(sess, "label", "query_string"); err != nil { + if err := base.DropTableColumns(sess, "label", "query_string"); err != nil { return err } - if err := dropTableColumns(sess, "label", "is_selected"); err != nil { + if err := base.DropTableColumns(sess, "label", "is_selected"); err != nil { return err } return sess.Commit() diff --git a/models/migrations/v105.go b/models/migrations/v1_11/v105.go similarity index 86% rename from models/migrations/v105.go rename to models/migrations/v1_11/v105.go index 5d9a98cce575..07aeedcd62ac 100644 --- a/models/migrations/v105.go +++ b/models/migrations/v1_11/v105.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_11 //nolint import ( "xorm.io/xorm" ) -func addTeamIncludesAllRepositories(x *xorm.Engine) error { +func AddTeamIncludesAllRepositories(x *xorm.Engine) error { type Team struct { ID int64 `xorm:"pk autoincr"` IncludesAllRepositories bool `xorm:"NOT NULL DEFAULT false"` diff --git a/models/migrations/v106.go b/models/migrations/v1_11/v106.go similarity index 88% rename from models/migrations/v106.go rename to models/migrations/v1_11/v106.go index 201fc10266a0..af7750866714 100644 --- a/models/migrations/v106.go +++ b/models/migrations/v1_11/v106.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_11 //nolint import ( "xorm.io/xorm" @@ -17,7 +17,7 @@ type Watch struct { Mode RepoWatchMode `xorm:"SMALLINT NOT NULL DEFAULT 1"` } -func addModeColumnToWatch(x *xorm.Engine) (err error) { +func AddModeColumnToWatch(x *xorm.Engine) (err error) { if err = x.Sync2(new(Watch)); err != nil { return } diff --git a/models/migrations/v107.go b/models/migrations/v1_11/v107.go similarity index 83% rename from models/migrations/v107.go rename to models/migrations/v1_11/v107.go index 22990a0fa6d5..5cc0d5282da3 100644 --- a/models/migrations/v107.go +++ b/models/migrations/v1_11/v107.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_11 //nolint import ( "xorm.io/xorm" ) -func addTemplateToRepo(x *xorm.Engine) error { +func AddTemplateToRepo(x *xorm.Engine) error { type Repository struct { IsTemplate bool `xorm:"INDEX NOT NULL DEFAULT false"` TemplateID int64 `xorm:"INDEX"` diff --git a/models/migrations/v108.go b/models/migrations/v1_11/v108.go similarity index 80% rename from models/migrations/v108.go rename to models/migrations/v1_11/v108.go index 60b8fb47aec3..06ff1b16e3eb 100644 --- a/models/migrations/v108.go +++ b/models/migrations/v1_11/v108.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_11 //nolint import ( "xorm.io/xorm" ) -func addCommentIDOnNotification(x *xorm.Engine) error { +func AddCommentIDOnNotification(x *xorm.Engine) error { type Notification struct { ID int64 `xorm:"pk autoincr"` CommentID int64 diff --git a/models/migrations/v109.go b/models/migrations/v1_11/v109.go similarity index 77% rename from models/migrations/v109.go rename to models/migrations/v1_11/v109.go index abe731768116..2bfd2536bf5c 100644 --- a/models/migrations/v109.go +++ b/models/migrations/v1_11/v109.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_11 //nolint import ( "xorm.io/xorm" ) -func addCanCreateOrgRepoColumnForTeam(x *xorm.Engine) error { +func AddCanCreateOrgRepoColumnForTeam(x *xorm.Engine) error { type Team struct { CanCreateOrgRepo bool `xorm:"NOT NULL DEFAULT false"` } diff --git a/models/migrations/v110.go b/models/migrations/v1_11/v110.go similarity index 91% rename from models/migrations/v110.go rename to models/migrations/v1_11/v110.go index 4a1c3c47a75a..813a753e0c22 100644 --- a/models/migrations/v110.go +++ b/models/migrations/v1_11/v110.go @@ -2,14 +2,14 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_11 //nolint import ( "xorm.io/xorm" "xorm.io/xorm/schemas" ) -func changeReviewContentToText(x *xorm.Engine) error { +func ChangeReviewContentToText(x *xorm.Engine) error { switch x.Dialect().URI().DBType { case schemas.MYSQL: _, err := x.Exec("ALTER TABLE review MODIFY COLUMN content TEXT") diff --git a/models/migrations/v111.go b/models/migrations/v1_11/v111.go similarity index 99% rename from models/migrations/v111.go rename to models/migrations/v1_11/v111.go index 65fe7c5332ce..f1f1d7cb0fbb 100644 --- a/models/migrations/v111.go +++ b/models/migrations/v1_11/v111.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_11 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addBranchProtectionCanPushAndEnableWhitelist(x *xorm.Engine) error { +func AddBranchProtectionCanPushAndEnableWhitelist(x *xorm.Engine) error { type ProtectedBranch struct { CanPush bool `xorm:"NOT NULL DEFAULT false"` EnableApprovalsWhitelist bool `xorm:"NOT NULL DEFAULT false"` diff --git a/models/migrations/v112.go b/models/migrations/v1_11/v112.go similarity index 93% rename from models/migrations/v112.go rename to models/migrations/v1_11/v112.go index 9da7d8a781c9..f8e84cf7529f 100644 --- a/models/migrations/v112.go +++ b/models/migrations/v1_11/v112.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_11 //nolint import ( "fmt" @@ -15,7 +15,7 @@ import ( "xorm.io/xorm" ) -func removeAttachmentMissedRepo(x *xorm.Engine) error { +func RemoveAttachmentMissedRepo(x *xorm.Engine) error { type Attachment struct { UUID string `xorm:"uuid"` } diff --git a/models/migrations/v113.go b/models/migrations/v1_11/v113.go similarity index 82% rename from models/migrations/v113.go rename to models/migrations/v1_11/v113.go index 4af246863d0d..36ab1bd9c4bd 100644 --- a/models/migrations/v113.go +++ b/models/migrations/v1_11/v113.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_11 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func featureChangeTargetBranch(x *xorm.Engine) error { +func FeatureChangeTargetBranch(x *xorm.Engine) error { type Comment struct { OldRef string NewRef string diff --git a/models/migrations/v114.go b/models/migrations/v1_11/v114.go similarity index 93% rename from models/migrations/v114.go rename to models/migrations/v1_11/v114.go index 4dd07c9e59a1..688dd06d42f3 100644 --- a/models/migrations/v114.go +++ b/models/migrations/v1_11/v114.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_11 //nolint import ( "net/url" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func sanitizeOriginalURL(x *xorm.Engine) error { +func SanitizeOriginalURL(x *xorm.Engine) error { type Repository struct { ID int64 OriginalURL string `xorm:"VARCHAR(2048)"` diff --git a/models/migrations/v115.go b/models/migrations/v1_11/v115.go similarity index 98% rename from models/migrations/v115.go rename to models/migrations/v1_11/v115.go index 3e61cb6e0ea2..1fbf0c4f2558 100644 --- a/models/migrations/v115.go +++ b/models/migrations/v1_11/v115.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_11 //nolint import ( "crypto/md5" @@ -21,7 +21,7 @@ import ( "xorm.io/xorm" ) -func renameExistingUserAvatarName(x *xorm.Engine) error { +func RenameExistingUserAvatarName(x *xorm.Engine) error { sess := x.NewSession() defer sess.Close() diff --git a/models/migrations/v116.go b/models/migrations/v1_11/v116.go similarity index 89% rename from models/migrations/v116.go rename to models/migrations/v1_11/v116.go index c684c05fdd33..6b6d91777b75 100644 --- a/models/migrations/v116.go +++ b/models/migrations/v1_11/v116.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_11 //nolint import ( "xorm.io/xorm" ) -func extendTrackedTimes(x *xorm.Engine) error { +func ExtendTrackedTimes(x *xorm.Engine) error { type TrackedTime struct { Time int64 `xorm:"NOT NULL"` Deleted bool `xorm:"NOT NULL DEFAULT false"` diff --git a/models/migrations/v117.go b/models/migrations/v1_12/v117.go similarity index 80% rename from models/migrations/v117.go rename to models/migrations/v1_12/v117.go index 662d6c7b4679..6a102e0df7ae 100644 --- a/models/migrations/v117.go +++ b/models/migrations/v1_12/v117.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "xorm.io/xorm" ) -func addBlockOnRejectedReviews(x *xorm.Engine) error { +func AddBlockOnRejectedReviews(x *xorm.Engine) error { type ProtectedBranch struct { BlockOnRejectedReviews bool `xorm:"NOT NULL DEFAULT false"` } diff --git a/models/migrations/v118.go b/models/migrations/v1_12/v118.go similarity index 88% rename from models/migrations/v118.go rename to models/migrations/v1_12/v118.go index c79cbb8ae3bb..227daffc45fb 100644 --- a/models/migrations/v118.go +++ b/models/migrations/v1_12/v118.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "xorm.io/xorm" ) -func addReviewCommitAndStale(x *xorm.Engine) error { +func AddReviewCommitAndStale(x *xorm.Engine) error { type Review struct { CommitID string `xorm:"VARCHAR(40)"` Stale bool `xorm:"NOT NULL DEFAULT false"` diff --git a/models/migrations/v119.go b/models/migrations/v1_12/v119.go similarity index 81% rename from models/migrations/v119.go rename to models/migrations/v1_12/v119.go index 9622ff587c7f..998ca004d2e0 100644 --- a/models/migrations/v119.go +++ b/models/migrations/v1_12/v119.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "xorm.io/xorm" ) -func fixMigratedRepositoryServiceType(x *xorm.Engine) error { +func FixMigratedRepositoryServiceType(x *xorm.Engine) error { // structs.GithubService: // GithubService = 2 _, err := x.Exec("UPDATE repository SET original_service_type = ? WHERE original_url LIKE 'https://github.com/%'", 2) diff --git a/models/migrations/v120.go b/models/migrations/v1_12/v120.go similarity index 85% rename from models/migrations/v120.go rename to models/migrations/v1_12/v120.go index 91d5b503f3f1..cc35ce5f3ea6 100644 --- a/models/migrations/v120.go +++ b/models/migrations/v1_12/v120.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "xorm.io/xorm" ) -func addOwnerNameOnRepository(x *xorm.Engine) error { +func AddOwnerNameOnRepository(x *xorm.Engine) error { type Repository struct { OwnerName string } diff --git a/models/migrations/v121.go b/models/migrations/v1_12/v121.go similarity index 84% rename from models/migrations/v121.go rename to models/migrations/v1_12/v121.go index c1ff7df3ade1..19864658d1fa 100644 --- a/models/migrations/v121.go +++ b/models/migrations/v1_12/v121.go @@ -2,11 +2,11 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import "xorm.io/xorm" -func addIsRestricted(x *xorm.Engine) error { +func AddIsRestricted(x *xorm.Engine) error { // User see models/user.go type User struct { ID int64 `xorm:"pk autoincr"` diff --git a/models/migrations/v122.go b/models/migrations/v1_12/v122.go similarity index 81% rename from models/migrations/v122.go rename to models/migrations/v1_12/v122.go index 7f4a49e69ce9..b0edae93bdba 100644 --- a/models/migrations/v122.go +++ b/models/migrations/v1_12/v122.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "xorm.io/xorm" ) -func addRequireSignedCommits(x *xorm.Engine) error { +func AddRequireSignedCommits(x *xorm.Engine) error { type ProtectedBranch struct { RequireSignedCommits bool `xorm:"NOT NULL DEFAULT false"` } diff --git a/models/migrations/v123.go b/models/migrations/v1_12/v123.go similarity index 82% rename from models/migrations/v123.go rename to models/migrations/v1_12/v123.go index e1b772381e11..1ecfdce7363a 100644 --- a/models/migrations/v123.go +++ b/models/migrations/v1_12/v123.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "xorm.io/xorm" ) -func addReactionOriginals(x *xorm.Engine) error { +func AddReactionOriginals(x *xorm.Engine) error { type Reaction struct { OriginalAuthorID int64 `xorm:"INDEX NOT NULL DEFAULT(0)"` OriginalAuthor string diff --git a/models/migrations/v124.go b/models/migrations/v1_12/v124.go similarity index 86% rename from models/migrations/v124.go rename to models/migrations/v1_12/v124.go index 0b61a04cbc7f..0fc86378dbc1 100644 --- a/models/migrations/v124.go +++ b/models/migrations/v1_12/v124.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "xorm.io/xorm" ) -func addUserRepoMissingColumns(x *xorm.Engine) error { +func AddUserRepoMissingColumns(x *xorm.Engine) error { type VisibleType int type User struct { PasswdHashAlgo string `xorm:"NOT NULL DEFAULT 'pbkdf2'"` diff --git a/models/migrations/v125.go b/models/migrations/v1_12/v125.go similarity index 83% rename from models/migrations/v125.go rename to models/migrations/v1_12/v125.go index 64483e139775..d74f888e9064 100644 --- a/models/migrations/v125.go +++ b/models/migrations/v1_12/v125.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addReviewMigrateInfo(x *xorm.Engine) error { +func AddReviewMigrateInfo(x *xorm.Engine) error { type Review struct { OriginalAuthor string OriginalAuthorID int64 diff --git a/models/migrations/v126.go b/models/migrations/v1_12/v126.go similarity index 89% rename from models/migrations/v126.go rename to models/migrations/v1_12/v126.go index bce13a61bd96..51dfb5167384 100644 --- a/models/migrations/v126.go +++ b/models/migrations/v1_12/v126.go @@ -2,14 +2,14 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "xorm.io/builder" "xorm.io/xorm" ) -func fixTopicRepositoryCount(x *xorm.Engine) error { +func FixTopicRepositoryCount(x *xorm.Engine) error { _, err := x.Exec(builder.Delete(builder.NotIn("`repo_id`", builder.Select("`id`").From("`repository`"))).From("`repo_topic`")) if err != nil { return err diff --git a/models/migrations/v127.go b/models/migrations/v1_12/v127.go similarity index 94% rename from models/migrations/v127.go rename to models/migrations/v1_12/v127.go index 7be1e326d45a..5849b82566d8 100644 --- a/models/migrations/v127.go +++ b/models/migrations/v1_12/v127.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "fmt" @@ -12,7 +12,7 @@ import ( "xorm.io/xorm" ) -func addLanguageStats(x *xorm.Engine) error { +func AddLanguageStats(x *xorm.Engine) error { // LanguageStat see models/repo_language_stats.go type LanguageStat struct { ID int64 `xorm:"pk autoincr"` diff --git a/models/migrations/v128.go b/models/migrations/v1_12/v128.go similarity index 98% rename from models/migrations/v128.go rename to models/migrations/v1_12/v128.go index 7e84ff5b7178..71e8e3207727 100644 --- a/models/migrations/v128.go +++ b/models/migrations/v1_12/v128.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "fmt" @@ -18,7 +18,7 @@ import ( "xorm.io/xorm" ) -func fixMergeBase(x *xorm.Engine) error { +func FixMergeBase(x *xorm.Engine) error { type Repository struct { ID int64 `xorm:"pk autoincr"` OwnerID int64 `xorm:"UNIQUE(s) index"` diff --git a/models/migrations/v129.go b/models/migrations/v1_12/v129.go similarity index 85% rename from models/migrations/v129.go rename to models/migrations/v1_12/v129.go index e935f2e07cb6..28bc5f604f9e 100644 --- a/models/migrations/v129.go +++ b/models/migrations/v1_12/v129.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "xorm.io/xorm" ) -func purgeUnusedDependencies(x *xorm.Engine) error { +func PurgeUnusedDependencies(x *xorm.Engine) error { if _, err := x.Exec("DELETE FROM issue_dependency WHERE issue_id NOT IN (SELECT id FROM issue)"); err != nil { return err } diff --git a/models/migrations/v130.go b/models/migrations/v1_12/v130.go similarity index 97% rename from models/migrations/v130.go rename to models/migrations/v1_12/v130.go index 7ffed3fd1767..ca3765be7bd1 100644 --- a/models/migrations/v130.go +++ b/models/migrations/v1_12/v130.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "code.gitea.io/gitea/modules/json" @@ -11,7 +11,7 @@ import ( "xorm.io/xorm" ) -func expandWebhooks(x *xorm.Engine) error { +func ExpandWebhooks(x *xorm.Engine) error { type HookEvents struct { Create bool `json:"create"` Delete bool `json:"delete"` diff --git a/models/migrations/v131.go b/models/migrations/v1_12/v131.go similarity index 83% rename from models/migrations/v131.go rename to models/migrations/v1_12/v131.go index 48fd3e29c949..14d954b4ba8e 100644 --- a/models/migrations/v131.go +++ b/models/migrations/v1_12/v131.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addSystemWebhookColumn(x *xorm.Engine) error { +func AddSystemWebhookColumn(x *xorm.Engine) error { type Webhook struct { IsSystemWebhook bool `xorm:"NOT NULL DEFAULT false"` } diff --git a/models/migrations/v132.go b/models/migrations/v1_12/v132.go similarity index 81% rename from models/migrations/v132.go rename to models/migrations/v1_12/v132.go index e67a67e907e2..8d93460f76b3 100644 --- a/models/migrations/v132.go +++ b/models/migrations/v1_12/v132.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addBranchProtectionProtectedFilesColumn(x *xorm.Engine) error { +func AddBranchProtectionProtectedFilesColumn(x *xorm.Engine) error { type ProtectedBranch struct { ProtectedFilePatterns string `xorm:"TEXT"` } diff --git a/models/migrations/v133.go b/models/migrations/v1_12/v133.go similarity index 84% rename from models/migrations/v133.go rename to models/migrations/v1_12/v133.go index ea0411d470be..1d69c47b9f23 100644 --- a/models/migrations/v133.go +++ b/models/migrations/v1_12/v133.go @@ -2,11 +2,11 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import "xorm.io/xorm" -func addEmailHashTable(x *xorm.Engine) error { +func AddEmailHashTable(x *xorm.Engine) error { // EmailHash represents a pre-generated hash map type EmailHash struct { Hash string `xorm:"pk varchar(32)"` diff --git a/models/migrations/v134.go b/models/migrations/v1_12/v134.go similarity index 98% rename from models/migrations/v134.go rename to models/migrations/v1_12/v134.go index 75c6768720bb..297db37a08f9 100644 --- a/models/migrations/v134.go +++ b/models/migrations/v1_12/v134.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "fmt" @@ -18,7 +18,7 @@ import ( "xorm.io/xorm" ) -func refixMergeBase(x *xorm.Engine) error { +func RefixMergeBase(x *xorm.Engine) error { type Repository struct { ID int64 `xorm:"pk autoincr"` OwnerID int64 `xorm:"UNIQUE(s) index"` diff --git a/models/migrations/v135.go b/models/migrations/v1_12/v135.go similarity index 83% rename from models/migrations/v135.go rename to models/migrations/v1_12/v135.go index eaa852d44fcd..9453ecdd581f 100644 --- a/models/migrations/v135.go +++ b/models/migrations/v1_12/v135.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addOrgIDLabelColumn(x *xorm.Engine) error { +func AddOrgIDLabelColumn(x *xorm.Engine) error { type Label struct { OrgID int64 `xorm:"INDEX"` } diff --git a/models/migrations/v136.go b/models/migrations/v1_12/v136.go similarity index 97% rename from models/migrations/v136.go rename to models/migrations/v1_12/v136.go index b2192f38530b..b114ddf50831 100644 --- a/models/migrations/v136.go +++ b/models/migrations/v1_12/v136.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "fmt" @@ -19,7 +19,7 @@ import ( "xorm.io/xorm" ) -func addCommitDivergenceToPulls(x *xorm.Engine) error { +func AddCommitDivergenceToPulls(x *xorm.Engine) error { type Repository struct { ID int64 `xorm:"pk autoincr"` OwnerID int64 `xorm:"UNIQUE(s) index"` diff --git a/models/migrations/v137.go b/models/migrations/v1_12/v137.go similarity index 80% rename from models/migrations/v137.go rename to models/migrations/v1_12/v137.go index f175cf8a80f1..6eb6b1ebb38f 100644 --- a/models/migrations/v137.go +++ b/models/migrations/v1_12/v137.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "xorm.io/xorm" ) -func addBlockOnOutdatedBranch(x *xorm.Engine) error { +func AddBlockOnOutdatedBranch(x *xorm.Engine) error { type ProtectedBranch struct { BlockOnOutdatedBranch bool `xorm:"NOT NULL DEFAULT false"` } diff --git a/models/migrations/v138.go b/models/migrations/v1_12/v138.go similarity index 81% rename from models/migrations/v138.go rename to models/migrations/v1_12/v138.go index 03235200abc8..c101c6e4cdfa 100644 --- a/models/migrations/v138.go +++ b/models/migrations/v1_12/v138.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addResolveDoerIDCommentColumn(x *xorm.Engine) error { +func AddResolveDoerIDCommentColumn(x *xorm.Engine) error { type Comment struct { ResolveDoerID int64 } diff --git a/models/migrations/v139.go b/models/migrations/v1_12/v139.go similarity index 90% rename from models/migrations/v139.go rename to models/migrations/v1_12/v139.go index 46b14b9869bd..69daa94f9814 100644 --- a/models/migrations/v139.go +++ b/models/migrations/v1_12/v139.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_12 //nolint import ( "code.gitea.io/gitea/modules/setting" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func prependRefsHeadsToIssueRefs(x *xorm.Engine) error { +func PrependRefsHeadsToIssueRefs(x *xorm.Engine) error { var query string switch { diff --git a/models/migrations/v140.go b/models/migrations/v1_13/v140.go similarity index 86% rename from models/migrations/v140.go rename to models/migrations/v1_13/v140.go index b54740f1a946..37aeeaeb6b13 100644 --- a/models/migrations/v140.go +++ b/models/migrations/v1_13/v140.go @@ -2,17 +2,18 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_13 //nolint import ( "fmt" + "code.gitea.io/gitea/models/migrations/base" "code.gitea.io/gitea/modules/setting" "xorm.io/xorm" ) -func fixLanguageStatsToSaveSize(x *xorm.Engine) error { +func FixLanguageStatsToSaveSize(x *xorm.Engine) error { // LanguageStat see models/repo_language_stats.go type LanguageStat struct { Size int64 `xorm:"NOT NULL DEFAULT 0"` @@ -52,5 +53,5 @@ func fixLanguageStatsToSaveSize(x *xorm.Engine) error { sess := x.NewSession() defer sess.Close() - return dropTableColumns(sess, "language_stat", "percentage") + return base.DropTableColumns(sess, "language_stat", "percentage") } diff --git a/models/migrations/v141.go b/models/migrations/v1_13/v141.go similarity index 81% rename from models/migrations/v141.go rename to models/migrations/v1_13/v141.go index 21247cc78f92..7dd1cc5d6738 100644 --- a/models/migrations/v141.go +++ b/models/migrations/v1_13/v141.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_13 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addKeepActivityPrivateUserColumn(x *xorm.Engine) error { +func AddKeepActivityPrivateUserColumn(x *xorm.Engine) error { type User struct { KeepActivityPrivate bool `xorm:"NOT NULL DEFAULT false"` } diff --git a/models/migrations/v142.go b/models/migrations/v1_13/v142.go similarity index 87% rename from models/migrations/v142.go rename to models/migrations/v1_13/v142.go index d8ccc112d6ee..3a2206b6c683 100644 --- a/models/migrations/v142.go +++ b/models/migrations/v1_13/v142.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_13 //nolint import ( "code.gitea.io/gitea/modules/log" @@ -11,7 +11,7 @@ import ( "xorm.io/xorm" ) -func setIsArchivedToFalse(x *xorm.Engine) error { +func SetIsArchivedToFalse(x *xorm.Engine) error { type Repository struct { IsArchived bool `xorm:"INDEX"` } diff --git a/models/migrations/v143.go b/models/migrations/v1_13/v143.go similarity index 93% rename from models/migrations/v143.go rename to models/migrations/v1_13/v143.go index 17f3af44974a..eee66c0a0d4a 100644 --- a/models/migrations/v143.go +++ b/models/migrations/v1_13/v143.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_13 //nolint import ( "code.gitea.io/gitea/modules/log" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func recalculateStars(x *xorm.Engine) (err error) { +func RecalculateStars(x *xorm.Engine) (err error) { // because of issue https://github.com/go-gitea/gitea/issues/11949, // recalculate Stars number for all users to fully fix it. diff --git a/models/migrations/v144.go b/models/migrations/v1_13/v144.go similarity index 88% rename from models/migrations/v144.go rename to models/migrations/v1_13/v144.go index 81279a54c910..0b8b91268b77 100644 --- a/models/migrations/v144.go +++ b/models/migrations/v1_13/v144.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_13 //nolint import ( "code.gitea.io/gitea/modules/log" @@ -11,7 +11,7 @@ import ( "xorm.io/xorm" ) -func updateMatrixWebhookHTTPMethod(x *xorm.Engine) error { +func UpdateMatrixWebhookHTTPMethod(x *xorm.Engine) error { matrixHookTaskType := 9 // value comes from the models package type Webhook struct { HTTPMethod string diff --git a/models/migrations/v145.go b/models/migrations/v1_13/v145.go similarity index 97% rename from models/migrations/v145.go rename to models/migrations/v1_13/v145.go index afc60497e318..b12da3c6757b 100644 --- a/models/migrations/v145.go +++ b/models/migrations/v1_13/v145.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_13 //nolint import ( "fmt" @@ -12,7 +12,7 @@ import ( "xorm.io/xorm" ) -func increaseLanguageField(x *xorm.Engine) error { +func IncreaseLanguageField(x *xorm.Engine) error { type LanguageStat struct { RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` Language string `xorm:"VARCHAR(50) UNIQUE(s) INDEX NOT NULL"` diff --git a/models/migrations/v146.go b/models/migrations/v1_13/v146.go similarity index 96% rename from models/migrations/v146.go rename to models/migrations/v1_13/v146.go index 092589820076..7afd325371f5 100644 --- a/models/migrations/v146.go +++ b/models/migrations/v1_13/v146.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_13 //nolint import ( "code.gitea.io/gitea/modules/timeutil" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addProjectsInfo(x *xorm.Engine) error { +func AddProjectsInfo(x *xorm.Engine) error { // Create new tables type ( ProjectType uint8 diff --git a/models/migrations/v147.go b/models/migrations/v1_13/v147.go similarity index 98% rename from models/migrations/v147.go rename to models/migrations/v1_13/v147.go index ad4ec4ef7ffd..1518b8dd24fc 100644 --- a/models/migrations/v147.go +++ b/models/migrations/v1_13/v147.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_13 //nolint import ( "code.gitea.io/gitea/modules/timeutil" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func createReviewsForCodeComments(x *xorm.Engine) error { +func CreateReviewsForCodeComments(x *xorm.Engine) error { // Review type Review struct { ID int64 `xorm:"pk autoincr"` diff --git a/models/migrations/v148.go b/models/migrations/v1_13/v148.go similarity index 79% rename from models/migrations/v148.go rename to models/migrations/v1_13/v148.go index 35d17f5b2cc0..40ede7174c86 100644 --- a/models/migrations/v148.go +++ b/models/migrations/v1_13/v148.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_13 //nolint import ( "xorm.io/xorm" ) -func purgeInvalidDependenciesComments(x *xorm.Engine) error { +func PurgeInvalidDependenciesComments(x *xorm.Engine) error { _, err := x.Exec("DELETE FROM comment WHERE dependent_issue_id != 0 AND dependent_issue_id NOT IN (SELECT id FROM issue)") return err } diff --git a/models/migrations/v149.go b/models/migrations/v1_13/v149.go similarity index 85% rename from models/migrations/v149.go rename to models/migrations/v1_13/v149.go index 4d2cf5b9767e..f0054b752df4 100644 --- a/models/migrations/v149.go +++ b/models/migrations/v1_13/v149.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_13 //nolint import ( "fmt" @@ -12,7 +12,7 @@ import ( "xorm.io/xorm" ) -func addCreatedAndUpdatedToMilestones(x *xorm.Engine) error { +func AddCreatedAndUpdatedToMilestones(x *xorm.Engine) error { type Milestone struct { CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` diff --git a/models/migrations/v150.go b/models/migrations/v1_13/v150.go similarity index 79% rename from models/migrations/v150.go rename to models/migrations/v1_13/v150.go index 41d6a90401ad..99e6ddf685b4 100644 --- a/models/migrations/v150.go +++ b/models/migrations/v1_13/v150.go @@ -2,15 +2,16 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_13 //nolint import ( + "code.gitea.io/gitea/models/migrations/base" "code.gitea.io/gitea/modules/timeutil" "xorm.io/xorm" ) -func addPrimaryKeyToRepoTopic(x *xorm.Engine) error { +func AddPrimaryKeyToRepoTopic(x *xorm.Engine) error { // Topic represents a topic of repositories type Topic struct { ID int64 `xorm:"pk autoincr"` @@ -32,8 +33,8 @@ func addPrimaryKeyToRepoTopic(x *xorm.Engine) error { return err } - recreateTable(sess, &Topic{}) - recreateTable(sess, &RepoTopic{}) + base.RecreateTable(sess, &Topic{}) + base.RecreateTable(sess, &RepoTopic{}) return sess.Commit() } diff --git a/models/migrations/v151.go b/models/migrations/v1_13/v151.go similarity index 98% rename from models/migrations/v151.go rename to models/migrations/v1_13/v151.go index 50314d816236..9efda9364593 100644 --- a/models/migrations/v151.go +++ b/models/migrations/v1_13/v151.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_13 //nolint import ( "context" @@ -16,7 +16,7 @@ import ( "xorm.io/xorm/schemas" ) -func setDefaultPasswordToArgon2(x *xorm.Engine) error { +func SetDefaultPasswordToArgon2(x *xorm.Engine) error { switch { case setting.Database.UseMySQL: _, err := x.Exec("ALTER TABLE `user` ALTER passwd_hash_algo SET DEFAULT 'argon2';") diff --git a/models/migrations/v152.go b/models/migrations/v1_13/v152.go similarity index 77% rename from models/migrations/v152.go rename to models/migrations/v1_13/v152.go index f71f71e22f60..ec49a2fb97b2 100644 --- a/models/migrations/v152.go +++ b/models/migrations/v1_13/v152.go @@ -2,11 +2,11 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_13 //nolint import "xorm.io/xorm" -func addTrustModelToRepository(x *xorm.Engine) error { +func AddTrustModelToRepository(x *xorm.Engine) error { type Repository struct { TrustModel int } diff --git a/models/migrations/v153.go b/models/migrations/v1_13/v153.go similarity index 84% rename from models/migrations/v153.go rename to models/migrations/v1_13/v153.go index 1e5ae9f7da47..1428edd3c117 100644 --- a/models/migrations/v153.go +++ b/models/migrations/v1_13/v153.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_13 //nolint import ( "xorm.io/xorm" ) -func addTeamReviewRequestSupport(x *xorm.Engine) error { +func AddTeamReviewRequestSupport(x *xorm.Engine) error { type Review struct { ReviewerTeamID int64 `xorm:"NOT NULL DEFAULT 0"` } diff --git a/models/migrations/v154.go b/models/migrations/v1_13/v154.go similarity index 95% rename from models/migrations/v154.go rename to models/migrations/v1_13/v154.go index bb17fb4725a0..8976db675cf9 100644 --- a/models/migrations/v154.go +++ b/models/migrations/v1_13/v154.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_13 //nolint import ( "code.gitea.io/gitea/modules/timeutil" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addTimeStamps(x *xorm.Engine) error { +func AddTimeStamps(x *xorm.Engine) error { // this will add timestamps where it is useful to have // Star represents a starred repo by an user. diff --git a/models/migrations/v1_14/main_test.go b/models/migrations/v1_14/main_test.go new file mode 100644 index 000000000000..859f7520ee7a --- /dev/null +++ b/models/migrations/v1_14/main_test.go @@ -0,0 +1,15 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package v1_14 //nolint + +import ( + "testing" + + "code.gitea.io/gitea/models/migrations/base" +) + +func TestMain(m *testing.M) { + base.MainTest(m) +} diff --git a/models/migrations/v155.go b/models/migrations/v1_14/v155.go similarity index 81% rename from models/migrations/v155.go rename to models/migrations/v1_14/v155.go index f95b4dfa3f5a..630eb94f1ad1 100644 --- a/models/migrations/v155.go +++ b/models/migrations/v1_14/v155.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addChangedProtectedFilesPullRequestColumn(x *xorm.Engine) error { +func AddChangedProtectedFilesPullRequestColumn(x *xorm.Engine) error { type PullRequest struct { ChangedProtectedFiles []string `xorm:"TEXT JSON"` } diff --git a/models/migrations/v156.go b/models/migrations/v1_14/v156.go similarity index 98% rename from models/migrations/v156.go rename to models/migrations/v1_14/v156.go index 2c146892d2c1..698c1c942b5c 100644 --- a/models/migrations/v156.go +++ b/models/migrations/v1_14/v156.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( "fmt" @@ -25,7 +25,7 @@ func userPath(userName string) string { return filepath.Join(setting.RepoRootPath, strings.ToLower(userName)) } -func fixPublisherIDforTagReleases(x *xorm.Engine) error { +func FixPublisherIDforTagReleases(x *xorm.Engine) error { type Release struct { ID int64 RepoID int64 diff --git a/models/migrations/v157.go b/models/migrations/v1_14/v157.go similarity index 95% rename from models/migrations/v157.go rename to models/migrations/v1_14/v157.go index e6738fd4df7d..12f0876d611b 100644 --- a/models/migrations/v157.go +++ b/models/migrations/v1_14/v157.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( "xorm.io/xorm" ) -func fixRepoTopics(x *xorm.Engine) error { +func FixRepoTopics(x *xorm.Engine) error { type Topic struct { ID int64 `xorm:"pk autoincr"` Name string `xorm:"UNIQUE VARCHAR(25)"` diff --git a/models/migrations/v158.go b/models/migrations/v1_14/v158.go similarity index 97% rename from models/migrations/v158.go rename to models/migrations/v1_14/v158.go index 472516d70e13..e6c9e629f7ff 100644 --- a/models/migrations/v158.go +++ b/models/migrations/v1_14/v158.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( "fmt" @@ -14,7 +14,7 @@ import ( "xorm.io/xorm" ) -func updateCodeCommentReplies(x *xorm.Engine) error { +func UpdateCodeCommentReplies(x *xorm.Engine) error { type Comment struct { ID int64 `xorm:"pk autoincr"` CommitSHA string `xorm:"VARCHAR(40)"` diff --git a/models/migrations/v159.go b/models/migrations/v1_14/v159.go similarity index 84% rename from models/migrations/v159.go rename to models/migrations/v1_14/v159.go index 68043b941277..60be2b12bdaf 100644 --- a/models/migrations/v159.go +++ b/models/migrations/v1_14/v159.go @@ -2,15 +2,16 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( + "code.gitea.io/gitea/models/migrations/base" "code.gitea.io/gitea/modules/timeutil" "xorm.io/xorm" ) -func updateReactionConstraint(x *xorm.Engine) error { +func UpdateReactionConstraint(x *xorm.Engine) error { // Reaction represents a reactions on issues and comments. type Reaction struct { ID int64 `xorm:"pk autoincr"` @@ -30,7 +31,7 @@ func updateReactionConstraint(x *xorm.Engine) error { return err } - if err := recreateTable(sess, &Reaction{}); err != nil { + if err := base.RecreateTable(sess, &Reaction{}); err != nil { return err } diff --git a/models/migrations/v160.go b/models/migrations/v1_14/v160.go similarity index 79% rename from models/migrations/v160.go rename to models/migrations/v1_14/v160.go index e1a4b4821d91..5bdf180ef901 100644 --- a/models/migrations/v160.go +++ b/models/migrations/v1_14/v160.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( "xorm.io/xorm" ) -func addBlockOnOfficialReviewRequests(x *xorm.Engine) error { +func AddBlockOnOfficialReviewRequests(x *xorm.Engine) error { type ProtectedBranch struct { BlockOnOfficialReviewRequests bool `xorm:"NOT NULL DEFAULT false"` } diff --git a/models/migrations/v161.go b/models/migrations/v1_14/v161.go similarity index 86% rename from models/migrations/v161.go rename to models/migrations/v1_14/v161.go index af6bdf16aa78..cf661caa3756 100644 --- a/models/migrations/v161.go +++ b/models/migrations/v1_14/v161.go @@ -2,15 +2,17 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( "context" + "code.gitea.io/gitea/models/migrations/base" + "xorm.io/xorm" ) -func convertTaskTypeToString(x *xorm.Engine) error { +func ConvertTaskTypeToString(x *xorm.Engine) error { const ( GOGS int = iota + 1 SLACK @@ -64,7 +66,7 @@ func convertTaskTypeToString(x *xorm.Engine) error { if err := sess.Begin(); err != nil { return err } - if err := dropTableColumns(sess, "hook_task", "type"); err != nil { + if err := base.DropTableColumns(sess, "hook_task", "type"); err != nil { return err } diff --git a/models/migrations/v162.go b/models/migrations/v1_14/v162.go similarity index 82% rename from models/migrations/v162.go rename to models/migrations/v1_14/v162.go index cf2baadbca17..bfaa824fa2c0 100644 --- a/models/migrations/v162.go +++ b/models/migrations/v1_14/v162.go @@ -2,13 +2,15 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( + "code.gitea.io/gitea/models/migrations/base" + "xorm.io/xorm" ) -func convertWebhookTaskTypeToString(x *xorm.Engine) error { +func ConvertWebhookTaskTypeToString(x *xorm.Engine) error { const ( GOGS int = iota + 1 SLACK @@ -53,7 +55,7 @@ func convertWebhookTaskTypeToString(x *xorm.Engine) error { if err := sess.Begin(); err != nil { return err } - if err := dropTableColumns(sess, "webhook", "hook_task_type"); err != nil { + if err := base.DropTableColumns(sess, "webhook", "hook_task_type"); err != nil { return err } diff --git a/models/migrations/v163.go b/models/migrations/v1_14/v163.go similarity index 76% rename from models/migrations/v163.go rename to models/migrations/v1_14/v163.go index 150cc34f02e4..8044dd4035cf 100644 --- a/models/migrations/v163.go +++ b/models/migrations/v1_14/v163.go @@ -2,13 +2,15 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( + "code.gitea.io/gitea/models/migrations/base" + "xorm.io/xorm" ) -func convertTopicNameFrom25To50(x *xorm.Engine) error { +func ConvertTopicNameFrom25To50(x *xorm.Engine) error { type Topic struct { ID int64 `xorm:"pk autoincr"` Name string `xorm:"UNIQUE VARCHAR(50)"` @@ -26,7 +28,7 @@ func convertTopicNameFrom25To50(x *xorm.Engine) error { if err := sess.Begin(); err != nil { return err } - if err := recreateTable(sess, new(Topic)); err != nil { + if err := base.RecreateTable(sess, new(Topic)); err != nil { return err } diff --git a/models/migrations/v164.go b/models/migrations/v1_14/v164.go similarity index 92% rename from models/migrations/v164.go rename to models/migrations/v1_14/v164.go index 02343fac2496..0a1424850330 100644 --- a/models/migrations/v164.go +++ b/models/migrations/v1_14/v164.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( "fmt" @@ -30,7 +30,7 @@ func (grant *OAuth2Grant) TableName() string { return "oauth2_grant" } -func addScopeAndNonceColumnsToOAuth2Grant(x *xorm.Engine) error { +func AddScopeAndNonceColumnsToOAuth2Grant(x *xorm.Engine) error { if err := x.Sync2(new(OAuth2Grant)); err != nil { return fmt.Errorf("Sync2: %w", err) } diff --git a/models/migrations/v165.go b/models/migrations/v1_14/v165.go similarity index 84% rename from models/migrations/v165.go rename to models/migrations/v1_14/v165.go index 87e1a24f2812..d42dea96a512 100644 --- a/models/migrations/v165.go +++ b/models/migrations/v1_14/v165.go @@ -2,14 +2,16 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( + "code.gitea.io/gitea/models/migrations/base" + "xorm.io/xorm" "xorm.io/xorm/schemas" ) -func convertHookTaskTypeToVarcharAndTrim(x *xorm.Engine) error { +func ConvertHookTaskTypeToVarcharAndTrim(x *xorm.Engine) error { dbType := x.Dialect().URI().DBType if dbType == schemas.SQLITE { // For SQLITE, varchar or char will always be represented as TEXT return nil @@ -19,7 +21,7 @@ func convertHookTaskTypeToVarcharAndTrim(x *xorm.Engine) error { Typ string `xorm:"VARCHAR(16) index"` } - if err := modifyColumn(x, "hook_task", &schemas.Column{ + if err := base.ModifyColumn(x, "hook_task", &schemas.Column{ Name: "typ", SQLType: schemas.SQLType{ Name: "VARCHAR", @@ -45,7 +47,7 @@ func convertHookTaskTypeToVarcharAndTrim(x *xorm.Engine) error { Type string `xorm:"VARCHAR(16) index"` } - if err := modifyColumn(x, "webhook", &schemas.Column{ + if err := base.ModifyColumn(x, "webhook", &schemas.Column{ Name: "type", SQLType: schemas.SQLType{ Name: "VARCHAR", diff --git a/models/migrations/v166.go b/models/migrations/v1_14/v166.go similarity index 97% rename from models/migrations/v166.go rename to models/migrations/v1_14/v166.go index 1b6e68b5733a..bdb18ffa6454 100644 --- a/models/migrations/v166.go +++ b/models/migrations/v1_14/v166.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( "crypto/sha256" @@ -16,7 +16,7 @@ import ( "xorm.io/xorm" ) -func recalculateUserEmptyPWD(x *xorm.Engine) (err error) { +func RecalculateUserEmptyPWD(x *xorm.Engine) (err error) { const ( algoBcrypt = "bcrypt" algoScrypt = "scrypt" diff --git a/models/migrations/v167.go b/models/migrations/v1_14/v167.go similarity index 86% rename from models/migrations/v167.go rename to models/migrations/v1_14/v167.go index 26d7cfd4f876..8098a7621306 100644 --- a/models/migrations/v167.go +++ b/models/migrations/v1_14/v167.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addUserRedirect(x *xorm.Engine) (err error) { +func AddUserRedirect(x *xorm.Engine) (err error) { type UserRedirect struct { ID int64 `xorm:"pk autoincr"` LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"` diff --git a/models/migrations/v168.go b/models/migrations/v1_14/v168.go similarity index 69% rename from models/migrations/v168.go rename to models/migrations/v1_14/v168.go index c34bb1d40560..e62ab909a0ca 100644 --- a/models/migrations/v168.go +++ b/models/migrations/v1_14/v168.go @@ -2,10 +2,10 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import "xorm.io/xorm" -func recreateUserTableToFixDefaultValues(_ *xorm.Engine) error { +func RecreateUserTableToFixDefaultValues(_ *xorm.Engine) error { return nil } diff --git a/models/migrations/v169.go b/models/migrations/v1_14/v169.go similarity index 77% rename from models/migrations/v169.go rename to models/migrations/v1_14/v169.go index e976281c5b10..f5fe332d97fa 100644 --- a/models/migrations/v169.go +++ b/models/migrations/v1_14/v169.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( "xorm.io/xorm" ) -func commentTypeDeleteBranchUseOldRef(x *xorm.Engine) error { +func CommentTypeDeleteBranchUseOldRef(x *xorm.Engine) error { _, err := x.Exec("UPDATE comment SET old_ref = commit_sha, commit_sha = '' WHERE type = 11") return err } diff --git a/models/migrations/v170.go b/models/migrations/v1_14/v170.go similarity index 83% rename from models/migrations/v170.go rename to models/migrations/v1_14/v170.go index 2d654fb2b171..cb0f927a2f58 100644 --- a/models/migrations/v170.go +++ b/models/migrations/v1_14/v170.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addDismissedReviewColumn(x *xorm.Engine) error { +func AddDismissedReviewColumn(x *xorm.Engine) error { type Review struct { Dismissed bool `xorm:"NOT NULL DEFAULT false"` } diff --git a/models/migrations/v171.go b/models/migrations/v1_14/v171.go similarity index 82% rename from models/migrations/v171.go rename to models/migrations/v1_14/v171.go index 8b27493ceac2..0c94fd4f93c3 100644 --- a/models/migrations/v171.go +++ b/models/migrations/v1_14/v171.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addSortingColToProjectBoard(x *xorm.Engine) error { +func AddSortingColToProjectBoard(x *xorm.Engine) error { type ProjectBoard struct { Sorting int8 `xorm:"NOT NULL DEFAULT 0"` } diff --git a/models/migrations/v172.go b/models/migrations/v1_14/v172.go similarity index 85% rename from models/migrations/v172.go rename to models/migrations/v1_14/v172.go index 125522a4b8ea..6518c0317478 100644 --- a/models/migrations/v172.go +++ b/models/migrations/v1_14/v172.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( "code.gitea.io/gitea/modules/timeutil" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addSessionTable(x *xorm.Engine) error { +func AddSessionTable(x *xorm.Engine) error { type Session struct { Key string `xorm:"pk CHAR(16)"` Data []byte `xorm:"BLOB"` diff --git a/models/migrations/v173.go b/models/migrations/v1_14/v173.go similarity index 82% rename from models/migrations/v173.go rename to models/migrations/v1_14/v173.go index c1f167e6f6a3..c8c9c39c6951 100644 --- a/models/migrations/v173.go +++ b/models/migrations/v1_14/v173.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addTimeIDCommentColumn(x *xorm.Engine) error { +func AddTimeIDCommentColumn(x *xorm.Engine) error { type Comment struct { TimeID int64 } diff --git a/models/migrations/v174.go b/models/migrations/v1_14/v174.go similarity index 90% rename from models/migrations/v174.go rename to models/migrations/v1_14/v174.go index b6c555525ef9..9a139764c33a 100644 --- a/models/migrations/v174.go +++ b/models/migrations/v1_14/v174.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addRepoTransfer(x *xorm.Engine) error { +func AddRepoTransfer(x *xorm.Engine) error { type RepoTransfer struct { ID int64 `xorm:"pk autoincr"` DoerID int64 diff --git a/models/migrations/v175.go b/models/migrations/v1_14/v175.go similarity index 95% rename from models/migrations/v175.go rename to models/migrations/v1_14/v175.go index 2dfefe987b68..e66871f5eee5 100644 --- a/models/migrations/v175.go +++ b/models/migrations/v1_14/v175.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( "fmt" @@ -14,7 +14,7 @@ import ( "xorm.io/xorm" ) -func fixPostgresIDSequences(x *xorm.Engine) error { +func FixPostgresIDSequences(x *xorm.Engine) error { if !setting.Database.UsePostgreSQL { return nil } diff --git a/models/migrations/v176.go b/models/migrations/v1_14/v176.go similarity index 94% rename from models/migrations/v176.go rename to models/migrations/v1_14/v176.go index 6436330a8dd8..4a343159ec9b 100644 --- a/models/migrations/v176.go +++ b/models/migrations/v1_14/v176.go @@ -2,16 +2,16 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( "xorm.io/xorm" ) -// removeInvalidLabels looks through the database to look for comments and issue_labels +// RemoveInvalidLabels looks through the database to look for comments and issue_labels // that refer to labels do not belong to the repository or organization that repository // that the issue is in -func removeInvalidLabels(x *xorm.Engine) error { +func RemoveInvalidLabels(x *xorm.Engine) error { type Comment struct { ID int64 `xorm:"pk autoincr"` Type int `xorm:"INDEX"` diff --git a/models/migrations/v176_test.go b/models/migrations/v1_14/v176_test.go similarity index 91% rename from models/migrations/v176_test.go rename to models/migrations/v1_14/v176_test.go index bc066c3b3272..c088af9066b1 100644 --- a/models/migrations/v176_test.go +++ b/models/migrations/v1_14/v176_test.go @@ -2,15 +2,17 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( "testing" + "code.gitea.io/gitea/models/migrations/base" + "github.com/stretchr/testify/assert" ) -func Test_removeInvalidLabels(t *testing.T) { +func Test_RemoveInvalidLabels(t *testing.T) { // Models used by the migration type Comment struct { ID int64 `xorm:"pk autoincr"` @@ -46,7 +48,7 @@ func Test_removeInvalidLabels(t *testing.T) { } // load and prepare the test database - x, deferable := prepareTestEnv(t, 0, new(Comment), new(Issue), new(Repository), new(IssueLabel), new(Label)) + x, deferable := base.PrepareTestEnv(t, 0, new(Comment), new(Issue), new(Repository), new(IssueLabel), new(Label)) if x == nil || t.Failed() { defer deferable() return @@ -78,7 +80,7 @@ func Test_removeInvalidLabels(t *testing.T) { } // Run the migration - if err := removeInvalidLabels(x); err != nil { + if err := RemoveInvalidLabels(x); err != nil { t.Errorf("unable to RemoveInvalidLabels: %v", err) } diff --git a/models/migrations/v177.go b/models/migrations/v1_14/v177.go similarity index 86% rename from models/migrations/v177.go rename to models/migrations/v1_14/v177.go index f28826f17094..c3086cd8e948 100644 --- a/models/migrations/v177.go +++ b/models/migrations/v1_14/v177.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( "fmt" @@ -10,8 +10,8 @@ import ( "xorm.io/xorm" ) -// deleteOrphanedIssueLabels looks through the database for issue_labels where the label no longer exists and deletes them. -func deleteOrphanedIssueLabels(x *xorm.Engine) error { +// DeleteOrphanedIssueLabels looks through the database for issue_labels where the label no longer exists and deletes them. +func DeleteOrphanedIssueLabels(x *xorm.Engine) error { type IssueLabel struct { ID int64 `xorm:"pk autoincr"` IssueID int64 `xorm:"UNIQUE(s)"` diff --git a/models/migrations/v177_test.go b/models/migrations/v1_14/v177_test.go similarity index 89% rename from models/migrations/v177_test.go rename to models/migrations/v1_14/v177_test.go index 5a58e2c6146b..4e061316d33b 100644 --- a/models/migrations/v177_test.go +++ b/models/migrations/v1_14/v177_test.go @@ -2,17 +2,18 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_14 //nolint import ( "testing" + "code.gitea.io/gitea/models/migrations/base" "code.gitea.io/gitea/modules/timeutil" "github.com/stretchr/testify/assert" ) -func Test_deleteOrphanedIssueLabels(t *testing.T) { +func Test_DeleteOrphanedIssueLabels(t *testing.T) { // Create the models used in the migration type IssueLabel struct { ID int64 `xorm:"pk autoincr"` @@ -34,7 +35,7 @@ func Test_deleteOrphanedIssueLabels(t *testing.T) { } // Prepare and load the testing database - x, deferable := prepareTestEnv(t, 0, new(IssueLabel), new(Label)) + x, deferable := base.PrepareTestEnv(t, 0, new(IssueLabel), new(Label)) if x == nil || t.Failed() { defer deferable() return @@ -55,7 +56,7 @@ func Test_deleteOrphanedIssueLabels(t *testing.T) { } // Run the migration - if err := deleteOrphanedIssueLabels(x); err != nil { + if err := DeleteOrphanedIssueLabels(x); err != nil { assert.NoError(t, err) return } diff --git a/models/migrations/v1_15/main_test.go b/models/migrations/v1_15/main_test.go new file mode 100644 index 000000000000..d589734e37d6 --- /dev/null +++ b/models/migrations/v1_15/main_test.go @@ -0,0 +1,15 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package v1_15 //nolint + +import ( + "testing" + + "code.gitea.io/gitea/models/migrations/base" +) + +func TestMain(m *testing.M) { + base.MainTest(m) +} diff --git a/models/migrations/v178.go b/models/migrations/v1_15/v178.go similarity index 83% rename from models/migrations/v178.go rename to models/migrations/v1_15/v178.go index c2a9af618e43..27ece98916ad 100644 --- a/models/migrations/v178.go +++ b/models/migrations/v1_15/v178.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_15 //nolint import ( "xorm.io/xorm" ) -func addLFSMirrorColumns(x *xorm.Engine) error { +func AddLFSMirrorColumns(x *xorm.Engine) error { type Mirror struct { LFS bool `xorm:"lfs_enabled NOT NULL DEFAULT false"` LFSEndpoint string `xorm:"lfs_endpoint TEXT"` diff --git a/models/migrations/v179.go b/models/migrations/v1_15/v179.go similarity index 74% rename from models/migrations/v179.go rename to models/migrations/v1_15/v179.go index e6dddef27333..c23bf91766c9 100644 --- a/models/migrations/v179.go +++ b/models/migrations/v1_15/v179.go @@ -2,21 +2,23 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_15 //nolint import ( + "code.gitea.io/gitea/models/migrations/base" + "xorm.io/xorm" "xorm.io/xorm/schemas" ) -func convertAvatarURLToText(x *xorm.Engine) error { +func ConvertAvatarURLToText(x *xorm.Engine) error { dbType := x.Dialect().URI().DBType if dbType == schemas.SQLITE { // For SQLITE, varchar or char will always be represented as TEXT return nil } // Some oauth2 providers may give very long avatar urls (i.e. Google) - return modifyColumn(x, "external_login_user", &schemas.Column{ + return base.ModifyColumn(x, "external_login_user", &schemas.Column{ Name: "avatar_url", SQLType: schemas.SQLType{ Name: schemas.Text, diff --git a/models/migrations/v180.go b/models/migrations/v1_15/v180.go similarity index 97% rename from models/migrations/v180.go rename to models/migrations/v1_15/v180.go index 4468a7107801..fc948bb1f5ef 100644 --- a/models/migrations/v180.go +++ b/models/migrations/v1_15/v180.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_15 //nolint import ( "code.gitea.io/gitea/modules/json" @@ -12,7 +12,7 @@ import ( "xorm.io/xorm" ) -func deleteMigrationCredentials(x *xorm.Engine) (err error) { +func DeleteMigrationCredentials(x *xorm.Engine) (err error) { // Task represents a task type Task struct { ID int64 diff --git a/models/migrations/v181.go b/models/migrations/v1_15/v181.go similarity index 96% rename from models/migrations/v181.go rename to models/migrations/v1_15/v181.go index 65045593ad6f..7ec3dae3767d 100644 --- a/models/migrations/v181.go +++ b/models/migrations/v1_15/v181.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_15 //nolint import ( "strings" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addPrimaryEmail2EmailAddress(x *xorm.Engine) (err error) { +func AddPrimaryEmail2EmailAddress(x *xorm.Engine) (err error) { type User struct { ID int64 `xorm:"pk autoincr"` Email string `xorm:"NOT NULL"` diff --git a/models/migrations/v181_test.go b/models/migrations/v1_15/v181_test.go similarity index 84% rename from models/migrations/v181_test.go rename to models/migrations/v1_15/v181_test.go index b9a6c6619b71..f621d0d162ff 100644 --- a/models/migrations/v181_test.go +++ b/models/migrations/v1_15/v181_test.go @@ -2,16 +2,18 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_15 //nolint import ( "strings" "testing" + "code.gitea.io/gitea/models/migrations/base" + "github.com/stretchr/testify/assert" ) -func Test_addPrimaryEmail2EmailAddress(t *testing.T) { +func Test_AddPrimaryEmail2EmailAddress(t *testing.T) { type User struct { ID int64 Email string @@ -19,14 +21,14 @@ func Test_addPrimaryEmail2EmailAddress(t *testing.T) { } // Prepare and load the testing database - x, deferable := prepareTestEnv(t, 0, new(User)) + x, deferable := base.PrepareTestEnv(t, 0, new(User)) if x == nil || t.Failed() { defer deferable() return } defer deferable() - err := addPrimaryEmail2EmailAddress(x) + err := AddPrimaryEmail2EmailAddress(x) assert.NoError(t, err) type EmailAddress struct { diff --git a/models/migrations/v182.go b/models/migrations/v1_15/v182.go similarity index 92% rename from models/migrations/v182.go rename to models/migrations/v1_15/v182.go index 29c2d2654a26..32282089afed 100644 --- a/models/migrations/v182.go +++ b/models/migrations/v1_15/v182.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_15 //nolint import ( "xorm.io/xorm" ) -func addIssueResourceIndexTable(x *xorm.Engine) error { +func AddIssueResourceIndexTable(x *xorm.Engine) error { type ResourceIndex struct { GroupID int64 `xorm:"pk"` MaxIndex int64 `xorm:"index"` diff --git a/models/migrations/v182_test.go b/models/migrations/v1_15/v182_test.go similarity index 83% rename from models/migrations/v182_test.go rename to models/migrations/v1_15/v182_test.go index 0d3eda9c51a6..b227e557ae6e 100644 --- a/models/migrations/v182_test.go +++ b/models/migrations/v1_15/v182_test.go @@ -2,15 +2,17 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_15 //nolint import ( "testing" + "code.gitea.io/gitea/models/migrations/base" + "github.com/stretchr/testify/assert" ) -func Test_addIssueResourceIndexTable(t *testing.T) { +func Test_AddIssueResourceIndexTable(t *testing.T) { // Create the models used in the migration type Issue struct { ID int64 `xorm:"pk autoincr"` @@ -19,7 +21,7 @@ func Test_addIssueResourceIndexTable(t *testing.T) { } // Prepare and load the testing database - x, deferable := prepareTestEnv(t, 0, new(Issue)) + x, deferable := base.PrepareTestEnv(t, 0, new(Issue)) if x == nil || t.Failed() { defer deferable() return @@ -27,7 +29,7 @@ func Test_addIssueResourceIndexTable(t *testing.T) { defer deferable() // Run the migration - if err := addIssueResourceIndexTable(x); err != nil { + if err := AddIssueResourceIndexTable(x); err != nil { assert.NoError(t, err) return } diff --git a/models/migrations/v183.go b/models/migrations/v1_15/v183.go similarity index 91% rename from models/migrations/v183.go rename to models/migrations/v1_15/v183.go index 0dc3af28a764..48039f8dc4cc 100644 --- a/models/migrations/v183.go +++ b/models/migrations/v1_15/v183.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_15 //nolint import ( "fmt" @@ -13,7 +13,7 @@ import ( "xorm.io/xorm" ) -func createPushMirrorTable(x *xorm.Engine) error { +func CreatePushMirrorTable(x *xorm.Engine) error { type PushMirror struct { ID int64 `xorm:"pk autoincr"` RepoID int64 `xorm:"INDEX"` diff --git a/models/migrations/v184.go b/models/migrations/v1_15/v184.go similarity index 88% rename from models/migrations/v184.go rename to models/migrations/v1_15/v184.go index 593a8100a8a5..195b419bc321 100644 --- a/models/migrations/v184.go +++ b/models/migrations/v1_15/v184.go @@ -2,18 +2,19 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_15 //nolint import ( "context" "fmt" + "code.gitea.io/gitea/models/migrations/base" "code.gitea.io/gitea/modules/setting" "xorm.io/xorm" ) -func renameTaskErrorsToMessage(x *xorm.Engine) error { +func RenameTaskErrorsToMessage(x *xorm.Engine) error { type Task struct { Errors string `xorm:"TEXT"` // if task failed, saved the error reason Type int @@ -48,7 +49,7 @@ func renameTaskErrorsToMessage(x *xorm.Engine) error { if messageExist { // if both errors and message exist, drop message at first - if err := dropTableColumns(sess, "task", "message"); err != nil { + if err := base.DropTableColumns(sess, "task", "message"); err != nil { return err } } diff --git a/models/migrations/v185.go b/models/migrations/v1_15/v185.go similarity index 88% rename from models/migrations/v185.go rename to models/migrations/v1_15/v185.go index 096994889703..4b8ed2e03824 100644 --- a/models/migrations/v185.go +++ b/models/migrations/v1_15/v185.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_15 //nolint import ( "xorm.io/xorm" ) -func addRepoArchiver(x *xorm.Engine) error { +func AddRepoArchiver(x *xorm.Engine) error { // RepoArchiver represents all archivers type RepoArchiver struct { ID int64 `xorm:"pk autoincr"` diff --git a/models/migrations/v186.go b/models/migrations/v1_15/v186.go similarity index 88% rename from models/migrations/v186.go rename to models/migrations/v1_15/v186.go index eb6ec7118cd7..3f53ff6a11a4 100644 --- a/models/migrations/v186.go +++ b/models/migrations/v1_15/v186.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_15 //nolint import ( "code.gitea.io/gitea/modules/timeutil" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func createProtectedTagTable(x *xorm.Engine) error { +func CreateProtectedTagTable(x *xorm.Engine) error { type ProtectedTag struct { ID int64 `xorm:"pk autoincr"` RepoID int64 diff --git a/models/migrations/v187.go b/models/migrations/v1_15/v187.go similarity index 71% rename from models/migrations/v187.go rename to models/migrations/v1_15/v187.go index 627423717a30..c3f60d1db876 100644 --- a/models/migrations/v187.go +++ b/models/migrations/v1_15/v187.go @@ -2,13 +2,15 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_15 //nolint import ( + "code.gitea.io/gitea/models/migrations/base" + "xorm.io/xorm" ) -func dropWebhookColumns(x *xorm.Engine) error { +func DropWebhookColumns(x *xorm.Engine) error { // Make sure the columns exist before dropping them type Webhook struct { Signature string `xorm:"TEXT"` @@ -35,10 +37,10 @@ func dropWebhookColumns(x *xorm.Engine) error { if err := sess.Begin(); err != nil { return err } - if err := dropTableColumns(sess, "webhook", "signature", "is_ssl"); err != nil { + if err := base.DropTableColumns(sess, "webhook", "signature", "is_ssl"); err != nil { return err } - if err := dropTableColumns(sess, "hook_task", "typ", "url", "signature", "http_method", "content_type", "is_ssl"); err != nil { + if err := base.DropTableColumns(sess, "hook_task", "typ", "url", "signature", "http_method", "content_type", "is_ssl"); err != nil { return err } diff --git a/models/migrations/v188.go b/models/migrations/v1_15/v188.go similarity index 80% rename from models/migrations/v188.go rename to models/migrations/v1_15/v188.go index 52ef4aaa810b..265b6f2f3f56 100644 --- a/models/migrations/v188.go +++ b/models/migrations/v1_15/v188.go @@ -2,11 +2,11 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_15 //nolint import "xorm.io/xorm" -func addKeyIsVerified(x *xorm.Engine) error { +func AddKeyIsVerified(x *xorm.Engine) error { type GPGKey struct { Verified bool `xorm:"NOT NULL DEFAULT false"` } diff --git a/models/migrations/v1_16/main_test.go b/models/migrations/v1_16/main_test.go new file mode 100644 index 000000000000..8109a8a26360 --- /dev/null +++ b/models/migrations/v1_16/main_test.go @@ -0,0 +1,15 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package v1_16 //nolint + +import ( + "testing" + + "code.gitea.io/gitea/models/migrations/base" +) + +func TestMain(m *testing.M) { + base.MainTest(m) +} diff --git a/models/migrations/v189.go b/models/migrations/v1_16/v189.go similarity index 92% rename from models/migrations/v189.go rename to models/migrations/v1_16/v189.go index 823e27e2ea0f..b04115845e26 100644 --- a/models/migrations/v189.go +++ b/models/migrations/v1_16/v189.go @@ -2,18 +2,19 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "encoding/binary" "fmt" + "code.gitea.io/gitea/models/migrations/base" "code.gitea.io/gitea/modules/json" "xorm.io/xorm" ) -func unwrapLDAPSourceCfg(x *xorm.Engine) error { +func UnwrapLDAPSourceCfg(x *xorm.Engine) error { jsonUnmarshalHandleDoubleEncode := func(bs []byte, v interface{}) error { err := json.Unmarshal(bs, v) if err != nil { @@ -103,7 +104,7 @@ func unwrapLDAPSourceCfg(x *xorm.Engine) error { if err := sess.Begin(); err != nil { return err } - if err := dropTableColumns(sess, "login_source", "is_actived"); err != nil { + if err := base.DropTableColumns(sess, "login_source", "is_actived"); err != nil { return err } diff --git a/models/migrations/v189_test.go b/models/migrations/v1_16/v189_test.go similarity index 83% rename from models/migrations/v189_test.go rename to models/migrations/v1_16/v189_test.go index 4ec3fe8c6007..9c0f0967cda3 100644 --- a/models/migrations/v189_test.go +++ b/models/migrations/v1_16/v189_test.go @@ -2,11 +2,12 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "testing" + "code.gitea.io/gitea/models/migrations/base" "code.gitea.io/gitea/modules/json" "github.com/stretchr/testify/assert" @@ -25,9 +26,9 @@ func (ls *LoginSourceOriginalV189) TableName() string { return "login_source" } -func Test_unwrapLDAPSourceCfg(t *testing.T) { +func Test_UnwrapLDAPSourceCfg(t *testing.T) { // Prepare and load the testing database - x, deferable := prepareTestEnv(t, 0, new(LoginSourceOriginalV189)) + x, deferable := base.PrepareTestEnv(t, 0, new(LoginSourceOriginalV189)) if x == nil || t.Failed() { defer deferable() return @@ -44,7 +45,7 @@ func Test_unwrapLDAPSourceCfg(t *testing.T) { } // Run the migration - if err := unwrapLDAPSourceCfg(x); err != nil { + if err := UnwrapLDAPSourceCfg(x); err != nil { assert.NoError(t, err) return } @@ -75,8 +76,8 @@ func Test_unwrapLDAPSourceCfg(t *testing.T) { return } - assert.EqualValues(t, expected, converted, "unwrapLDAPSourceCfg failed for %d", source.ID) - assert.EqualValues(t, source.ID%2 == 0, source.IsActive, "unwrapLDAPSourceCfg failed for %d", source.ID) + assert.EqualValues(t, expected, converted, "UnwrapLDAPSourceCfg failed for %d", source.ID) + assert.EqualValues(t, source.ID%2 == 0, source.IsActive, "UnwrapLDAPSourceCfg failed for %d", source.ID) } } } diff --git a/models/migrations/v190.go b/models/migrations/v1_16/v190.go similarity index 84% rename from models/migrations/v190.go rename to models/migrations/v1_16/v190.go index 00046ff2a18e..a669fc31fab1 100644 --- a/models/migrations/v190.go +++ b/models/migrations/v1_16/v190.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addAgitFlowPullRequest(x *xorm.Engine) error { +func AddAgitFlowPullRequest(x *xorm.Engine) error { type PullRequestFlow int type PullRequest struct { diff --git a/models/migrations/v191.go b/models/migrations/v1_16/v191.go similarity index 88% rename from models/migrations/v191.go rename to models/migrations/v1_16/v191.go index 9a688243e19c..461ac653d415 100644 --- a/models/migrations/v191.go +++ b/models/migrations/v1_16/v191.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "code.gitea.io/gitea/modules/setting" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func alterIssueAndCommentTextFieldsToLongText(x *xorm.Engine) error { +func AlterIssueAndCommentTextFieldsToLongText(x *xorm.Engine) error { sess := x.NewSession() defer sess.Close() if err := sess.Begin(); err != nil { diff --git a/models/migrations/v192.go b/models/migrations/v1_16/v192.go similarity index 61% rename from models/migrations/v192.go rename to models/migrations/v1_16/v192.go index f436e93d621b..e3ac2654fde3 100644 --- a/models/migrations/v192.go +++ b/models/migrations/v1_16/v192.go @@ -2,17 +2,19 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( + "code.gitea.io/gitea/models/migrations/base" + "xorm.io/xorm" ) -func recreateIssueResourceIndexTable(x *xorm.Engine) error { +func RecreateIssueResourceIndexTable(x *xorm.Engine) error { type IssueIndex struct { GroupID int64 `xorm:"pk"` MaxIndex int64 `xorm:"index"` } - return RecreateTables(new(IssueIndex))(x) + return base.RecreateTables(new(IssueIndex))(x) } diff --git a/models/migrations/v193.go b/models/migrations/v1_16/v193.go similarity index 93% rename from models/migrations/v193.go rename to models/migrations/v1_16/v193.go index c8244a1b3de9..8bf960feb3b5 100644 --- a/models/migrations/v193.go +++ b/models/migrations/v1_16/v193.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "xorm.io/xorm" ) -func addRepoIDForAttachment(x *xorm.Engine) error { +func AddRepoIDForAttachment(x *xorm.Engine) error { type Attachment struct { ID int64 `xorm:"pk autoincr"` UUID string `xorm:"uuid UNIQUE"` diff --git a/models/migrations/v193_test.go b/models/migrations/v1_16/v193_test.go similarity index 86% rename from models/migrations/v193_test.go rename to models/migrations/v1_16/v193_test.go index b250d154f782..b573a54bb055 100644 --- a/models/migrations/v193_test.go +++ b/models/migrations/v1_16/v193_test.go @@ -2,15 +2,17 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "testing" + "code.gitea.io/gitea/models/migrations/base" + "github.com/stretchr/testify/assert" ) -func Test_addRepoIDForAttachment(t *testing.T) { +func Test_AddRepoIDForAttachment(t *testing.T) { type Attachment struct { ID int64 `xorm:"pk autoincr"` UUID string `xorm:"uuid UNIQUE"` @@ -31,14 +33,14 @@ func Test_addRepoIDForAttachment(t *testing.T) { } // Prepare and load the testing database - x, deferrable := prepareTestEnv(t, 0, new(Attachment), new(Issue), new(Release)) + x, deferrable := base.PrepareTestEnv(t, 0, new(Attachment), new(Issue), new(Release)) defer deferrable() if x == nil || t.Failed() { return } // Run the migration - if err := addRepoIDForAttachment(x); err != nil { + if err := AddRepoIDForAttachment(x); err != nil { assert.NoError(t, err) return } diff --git a/models/migrations/v194.go b/models/migrations/v1_16/v194.go similarity index 82% rename from models/migrations/v194.go rename to models/migrations/v1_16/v194.go index 6bd2f19ef531..8486b1131add 100644 --- a/models/migrations/v194.go +++ b/models/migrations/v1_16/v194.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addBranchProtectionUnprotectedFilesColumn(x *xorm.Engine) error { +func AddBranchProtectionUnprotectedFilesColumn(x *xorm.Engine) error { type ProtectedBranch struct { UnprotectedFilePatterns string `xorm:"TEXT"` } diff --git a/models/migrations/v195.go b/models/migrations/v1_16/v195.go similarity index 94% rename from models/migrations/v195.go rename to models/migrations/v1_16/v195.go index 8594dddf1fc1..a7165cbf758a 100644 --- a/models/migrations/v195.go +++ b/models/migrations/v1_16/v195.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addTableCommitStatusIndex(x *xorm.Engine) error { +func AddTableCommitStatusIndex(x *xorm.Engine) error { // CommitStatusIndex represents a table for commit status index type CommitStatusIndex struct { ID int64 diff --git a/models/migrations/v195_test.go b/models/migrations/v1_16/v195_test.go similarity index 85% rename from models/migrations/v195_test.go rename to models/migrations/v1_16/v195_test.go index 05f8469daaf8..06ff13b52bc1 100644 --- a/models/migrations/v195_test.go +++ b/models/migrations/v1_16/v195_test.go @@ -2,15 +2,17 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "testing" + "code.gitea.io/gitea/models/migrations/base" + "github.com/stretchr/testify/assert" ) -func Test_addTableCommitStatusIndex(t *testing.T) { +func Test_AddTableCommitStatusIndex(t *testing.T) { // Create the models used in the migration type CommitStatus struct { ID int64 `xorm:"pk autoincr"` @@ -20,7 +22,7 @@ func Test_addTableCommitStatusIndex(t *testing.T) { } // Prepare and load the testing database - x, deferable := prepareTestEnv(t, 0, new(CommitStatus)) + x, deferable := base.PrepareTestEnv(t, 0, new(CommitStatus)) if x == nil || t.Failed() { defer deferable() return @@ -28,7 +30,7 @@ func Test_addTableCommitStatusIndex(t *testing.T) { defer deferable() // Run the migration - if err := addTableCommitStatusIndex(x); err != nil { + if err := AddTableCommitStatusIndex(x); err != nil { assert.NoError(t, err) return } diff --git a/models/migrations/v196.go b/models/migrations/v1_16/v196.go similarity index 82% rename from models/migrations/v196.go rename to models/migrations/v1_16/v196.go index 0423d0268b78..b73a56607ef7 100644 --- a/models/migrations/v196.go +++ b/models/migrations/v1_16/v196.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addColorColToProjectBoard(x *xorm.Engine) error { +func AddColorColToProjectBoard(x *xorm.Engine) error { type ProjectBoard struct { Color string `xorm:"VARCHAR(7)"` } diff --git a/models/migrations/v197.go b/models/migrations/v1_16/v197.go similarity index 85% rename from models/migrations/v197.go rename to models/migrations/v1_16/v197.go index 3517896a23dd..da2e9ae76f3a 100644 --- a/models/migrations/v197.go +++ b/models/migrations/v1_16/v197.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "xorm.io/xorm" ) -func addRenamedBranchTable(x *xorm.Engine) error { +func AddRenamedBranchTable(x *xorm.Engine) error { type RenamedBranch struct { ID int64 `xorm:"pk autoincr"` RepoID int64 `xorm:"INDEX NOT NULL"` diff --git a/models/migrations/v198.go b/models/migrations/v1_16/v198.go similarity index 90% rename from models/migrations/v198.go rename to models/migrations/v1_16/v198.go index 4b1515109e1d..0e09ee53065c 100644 --- a/models/migrations/v198.go +++ b/models/migrations/v1_16/v198.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "fmt" @@ -12,7 +12,7 @@ import ( "xorm.io/xorm" ) -func addTableIssueContentHistory(x *xorm.Engine) error { +func AddTableIssueContentHistory(x *xorm.Engine) error { type IssueContentHistory struct { ID int64 `xorm:"pk autoincr"` PosterID int64 diff --git a/models/migrations/v199.go b/models/migrations/v1_16/v199.go similarity index 92% rename from models/migrations/v199.go rename to models/migrations/v1_16/v199.go index 29f9d49dbeae..53ed7e4e8a56 100644 --- a/models/migrations/v199.go +++ b/models/migrations/v1_16/v199.go @@ -2,6 +2,6 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint // We used to use a table `remote_version` to store information for updater, now we use `AppState`, so this migration task is a no-op now. diff --git a/models/migrations/v200.go b/models/migrations/v1_16/v200.go similarity index 86% rename from models/migrations/v200.go rename to models/migrations/v1_16/v200.go index f0f107bf77d7..70ee36354ca0 100644 --- a/models/migrations/v200.go +++ b/models/migrations/v1_16/v200.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addTableAppState(x *xorm.Engine) error { +func AddTableAppState(x *xorm.Engine) error { type AppState struct { ID string `xorm:"pk varchar(200)"` Revision int64 diff --git a/models/migrations/v201.go b/models/migrations/v1_16/v201.go similarity index 82% rename from models/migrations/v201.go rename to models/migrations/v1_16/v201.go index 637c30617c84..6a2eda77b1ea 100644 --- a/models/migrations/v201.go +++ b/models/migrations/v1_16/v201.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "xorm.io/xorm" ) -func dropTableRemoteVersion(x *xorm.Engine) error { +func DropTableRemoteVersion(x *xorm.Engine) error { // drop the orphaned table introduced in `v199`, now the update checker also uses AppState, do not need this table _ = x.DropTables("remote_version") return nil diff --git a/models/migrations/v202.go b/models/migrations/v1_16/v202.go similarity index 89% rename from models/migrations/v202.go rename to models/migrations/v1_16/v202.go index 1bfc28d63702..de0576b8d6d1 100644 --- a/models/migrations/v202.go +++ b/models/migrations/v1_16/v202.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func createUserSettingsTable(x *xorm.Engine) error { +func CreateUserSettingsTable(x *xorm.Engine) error { type UserSetting struct { ID int64 `xorm:"pk autoincr"` UserID int64 `xorm:"index unique(key_userid)"` // to load all of someone's settings diff --git a/models/migrations/v203.go b/models/migrations/v1_16/v203.go similarity index 82% rename from models/migrations/v203.go rename to models/migrations/v1_16/v203.go index 2e1dd7289a25..78903cb59516 100644 --- a/models/migrations/v203.go +++ b/models/migrations/v1_16/v203.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "xorm.io/xorm" ) -func addProjectIssueSorting(x *xorm.Engine) error { +func AddProjectIssueSorting(x *xorm.Engine) error { // ProjectIssue saves relation from issue to a project type ProjectIssue struct { Sorting int64 `xorm:"NOT NULL DEFAULT 0"` diff --git a/models/migrations/v204.go b/models/migrations/v1_16/v204.go similarity index 80% rename from models/migrations/v204.go rename to models/migrations/v1_16/v204.go index ad21cfbd845d..8151866fa24b 100644 --- a/models/migrations/v204.go +++ b/models/migrations/v1_16/v204.go @@ -2,11 +2,11 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import "xorm.io/xorm" -func addSSHKeyIsVerified(x *xorm.Engine) error { +func AddSSHKeyIsVerified(x *xorm.Engine) error { type PublicKey struct { Verified bool `xorm:"NOT NULL DEFAULT false"` } diff --git a/models/migrations/v205.go b/models/migrations/v1_16/v205.go similarity index 74% rename from models/migrations/v205.go rename to models/migrations/v1_16/v205.go index 7aefa0431ac1..9cca445d3533 100644 --- a/models/migrations/v205.go +++ b/models/migrations/v1_16/v205.go @@ -2,21 +2,23 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( + "code.gitea.io/gitea/models/migrations/base" + "xorm.io/xorm" "xorm.io/xorm/schemas" ) -func migrateUserPasswordSalt(x *xorm.Engine) error { +func MigrateUserPasswordSalt(x *xorm.Engine) error { dbType := x.Dialect().URI().DBType // For SQLITE, the max length doesn't matter. if dbType == schemas.SQLITE { return nil } - if err := modifyColumn(x, "user", &schemas.Column{ + if err := base.ModifyColumn(x, "user", &schemas.Column{ Name: "rands", SQLType: schemas.SQLType{ Name: "VARCHAR", @@ -29,7 +31,7 @@ func migrateUserPasswordSalt(x *xorm.Engine) error { return err } - return modifyColumn(x, "user", &schemas.Column{ + return base.ModifyColumn(x, "user", &schemas.Column{ Name: "salt", SQLType: schemas.SQLType{ Name: "VARCHAR", diff --git a/models/migrations/v206.go b/models/migrations/v1_16/v206.go similarity index 89% rename from models/migrations/v206.go rename to models/migrations/v1_16/v206.go index 525a47572218..b2530d1005a3 100644 --- a/models/migrations/v206.go +++ b/models/migrations/v1_16/v206.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addAuthorizeColForTeamUnit(x *xorm.Engine) error { +func AddAuthorizeColForTeamUnit(x *xorm.Engine) error { type TeamUnit struct { ID int64 `xorm:"pk autoincr"` OrgID int64 `xorm:"INDEX"` diff --git a/models/migrations/v207.go b/models/migrations/v1_16/v207.go similarity index 79% rename from models/migrations/v207.go rename to models/migrations/v1_16/v207.go index f60dfc3dc359..f93ae4c33977 100644 --- a/models/migrations/v207.go +++ b/models/migrations/v1_16/v207.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "xorm.io/xorm" ) -func addWebAuthnCred(x *xorm.Engine) error { +func AddWebAuthnCred(x *xorm.Engine) error { // NO-OP Don't migrate here - let v210 do this. return nil diff --git a/models/migrations/v208.go b/models/migrations/v1_16/v208.go similarity index 71% rename from models/migrations/v208.go rename to models/migrations/v1_16/v208.go index 28754061214f..40f8b05b8009 100644 --- a/models/migrations/v208.go +++ b/models/migrations/v1_16/v208.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "xorm.io/xorm" ) -func useBase32HexForCredIDInWebAuthnCredential(x *xorm.Engine) error { +func UseBase32HexForCredIDInWebAuthnCredential(x *xorm.Engine) error { // noop return nil } diff --git a/models/migrations/v209.go b/models/migrations/v1_16/v209.go similarity index 78% rename from models/migrations/v209.go rename to models/migrations/v1_16/v209.go index 710684ef508d..e2f06bbfb057 100644 --- a/models/migrations/v209.go +++ b/models/migrations/v1_16/v209.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "xorm.io/xorm" ) -func increaseCredentialIDTo410(x *xorm.Engine) error { +func IncreaseCredentialIDTo410(x *xorm.Engine) error { // no-op // v208 was completely wrong // So now we have to no-op again. diff --git a/models/migrations/v210.go b/models/migrations/v1_16/v210.go similarity index 96% rename from models/migrations/v210.go rename to models/migrations/v1_16/v210.go index 891c96fb3031..b59b35660758 100644 --- a/models/migrations/v210.go +++ b/models/migrations/v1_16/v210.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "crypto/elliptic" @@ -10,6 +10,7 @@ import ( "fmt" "strings" + "code.gitea.io/gitea/models/migrations/base" "code.gitea.io/gitea/modules/timeutil" "github.com/tstranex/u2f" @@ -18,7 +19,7 @@ import ( ) // v208 migration was completely broken -func remigrateU2FCredentials(x *xorm.Engine) error { +func RemigrateU2FCredentials(x *xorm.Engine) error { // Create webauthnCredential table type webauthnCredential struct { ID int64 `xorm:"pk autoincr"` @@ -58,7 +59,7 @@ func remigrateU2FCredentials(x *xorm.Engine) error { return err } - if err := recreateTable(sess, new(webauthnCredential)); err != nil { + if err := base.RecreateTable(sess, new(webauthnCredential)); err != nil { _ = sess.Close() return err } diff --git a/models/migrations/v210_test.go b/models/migrations/v1_16/v210_test.go similarity index 87% rename from models/migrations/v210_test.go rename to models/migrations/v1_16/v210_test.go index 70dbe61b06eb..20c430594e62 100644 --- a/models/migrations/v210_test.go +++ b/models/migrations/v1_16/v210_test.go @@ -2,18 +2,19 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_16 //nolint import ( "testing" + "code.gitea.io/gitea/models/migrations/base" "code.gitea.io/gitea/modules/timeutil" "github.com/stretchr/testify/assert" "xorm.io/xorm/schemas" ) -func Test_remigrateU2FCredentials(t *testing.T) { +func Test_RemigrateU2FCredentials(t *testing.T) { // Create webauthnCredential table type WebauthnCredential struct { ID int64 `xorm:"pk autoincr"` @@ -44,7 +45,7 @@ func Test_remigrateU2FCredentials(t *testing.T) { } // Prepare and load the testing database - x, deferable := prepareTestEnv(t, 0, new(WebauthnCredential), new(U2fRegistration), new(ExpectedWebauthnCredential)) + x, deferable := base.PrepareTestEnv(t, 0, new(WebauthnCredential), new(U2fRegistration), new(ExpectedWebauthnCredential)) if x == nil || t.Failed() { defer deferable() return @@ -56,7 +57,7 @@ func Test_remigrateU2FCredentials(t *testing.T) { } // Run the migration - if err := remigrateU2FCredentials(x); err != nil { + if err := RemigrateU2FCredentials(x); err != nil { assert.NoError(t, err) return } diff --git a/models/migrations/v1_17/main_test.go b/models/migrations/v1_17/main_test.go new file mode 100644 index 000000000000..0f1708de8b69 --- /dev/null +++ b/models/migrations/v1_17/main_test.go @@ -0,0 +1,15 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package v1_17 // nolint + +import ( + "testing" + + "code.gitea.io/gitea/models/migrations/base" +) + +func TestMain(m *testing.M) { + base.MainTest(m) +} diff --git a/models/migrations/v211.go b/models/migrations/v1_17/v211.go similarity index 90% rename from models/migrations/v211.go rename to models/migrations/v1_17/v211.go index ec7cb46d472f..de9eb4b4b0d9 100644 --- a/models/migrations/v211.go +++ b/models/migrations/v1_17/v211.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_17 // nolint import ( "fmt" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func createForeignReferenceTable(x *xorm.Engine) error { +func CreateForeignReferenceTable(x *xorm.Engine) error { type ForeignReference struct { // RepoID is the first column in all indices. now we only need 2 indices: (repo, local) and (repo, foreign, type) RepoID int64 `xorm:"UNIQUE(repo_foreign_type) INDEX(repo_local)" ` diff --git a/models/migrations/v212.go b/models/migrations/v1_17/v212.go similarity index 97% rename from models/migrations/v212.go rename to models/migrations/v1_17/v212.go index 9d16f0556c8c..5187f5e72f49 100644 --- a/models/migrations/v212.go +++ b/models/migrations/v1_17/v212.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_17 // nolint import ( "code.gitea.io/gitea/modules/timeutil" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addPackageTables(x *xorm.Engine) error { +func AddPackageTables(x *xorm.Engine) error { type Package struct { ID int64 `xorm:"pk autoincr"` OwnerID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"` diff --git a/models/migrations/v213.go b/models/migrations/v1_17/v213.go similarity index 83% rename from models/migrations/v213.go rename to models/migrations/v1_17/v213.go index b1dbf98d1ea2..7b1b158f9fd1 100644 --- a/models/migrations/v213.go +++ b/models/migrations/v1_17/v213.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_17 // nolint import ( "xorm.io/xorm" ) -func addAllowMaintainerEdit(x *xorm.Engine) error { +func AddAllowMaintainerEdit(x *xorm.Engine) error { // PullRequest represents relation between pull request and repositories. type PullRequest struct { AllowMaintainerEdit bool `xorm:"NOT NULL DEFAULT false"` diff --git a/models/migrations/v214.go b/models/migrations/v1_17/v214.go similarity index 88% rename from models/migrations/v214.go rename to models/migrations/v1_17/v214.go index dfe5d776a0f2..e6fa53d4b849 100644 --- a/models/migrations/v214.go +++ b/models/migrations/v1_17/v214.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_17 // nolint import ( "xorm.io/xorm" ) -func addAutoMergeTable(x *xorm.Engine) error { +func AddAutoMergeTable(x *xorm.Engine) error { type MergeStyle string type PullAutoMerge struct { ID int64 `xorm:"pk autoincr"` diff --git a/models/migrations/v215.go b/models/migrations/v1_17/v215.go similarity index 91% rename from models/migrations/v215.go rename to models/migrations/v1_17/v215.go index d65488a18126..e1485159641b 100644 --- a/models/migrations/v215.go +++ b/models/migrations/v1_17/v215.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_17 // nolint import ( "code.gitea.io/gitea/models/pull" @@ -11,7 +11,7 @@ import ( "xorm.io/xorm" ) -func addReviewViewedFiles(x *xorm.Engine) error { +func AddReviewViewedFiles(x *xorm.Engine) error { type ReviewState struct { ID int64 `xorm:"pk autoincr"` UserID int64 `xorm:"NOT NULL UNIQUE(pull_commit_user)"` diff --git a/models/migrations/v216.go b/models/migrations/v1_17/v216.go similarity index 92% rename from models/migrations/v216.go rename to models/migrations/v1_17/v216.go index ab44808402e9..bde58257721b 100644 --- a/models/migrations/v216.go +++ b/models/migrations/v1_17/v216.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_17 // nolint // This migration added non-ideal indices to the action table which on larger datasets slowed things down // it has been superceded by v218.go diff --git a/models/migrations/v217.go b/models/migrations/v1_17/v217.go similarity index 87% rename from models/migrations/v217.go rename to models/migrations/v1_17/v217.go index 280dba17a917..abba9e8ec9fe 100644 --- a/models/migrations/v217.go +++ b/models/migrations/v1_17/v217.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_17 // nolint import ( "code.gitea.io/gitea/modules/setting" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func alterHookTaskTextFieldsToLongText(x *xorm.Engine) error { +func AlterHookTaskTextFieldsToLongText(x *xorm.Engine) error { sess := x.NewSession() defer sess.Close() if err := sess.Begin(); err != nil { diff --git a/models/migrations/v218.go b/models/migrations/v1_17/v218.go similarity index 95% rename from models/migrations/v218.go rename to models/migrations/v1_17/v218.go index e08c6c5b0f5e..a5cd1c591ad5 100644 --- a/models/migrations/v218.go +++ b/models/migrations/v1_17/v218.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_17 // nolint import ( "code.gitea.io/gitea/modules/setting" @@ -48,6 +48,6 @@ func (*improveActionTableIndicesAction) TableIndices() []*schemas.Index { return indices } -func improveActionTableIndices(x *xorm.Engine) error { +func ImproveActionTableIndices(x *xorm.Engine) error { return x.Sync2(&improveActionTableIndicesAction{}) } diff --git a/models/migrations/v219.go b/models/migrations/v1_17/v219.go similarity index 89% rename from models/migrations/v219.go rename to models/migrations/v1_17/v219.go index 7b4f34b70403..d22f4e6b8e5d 100644 --- a/models/migrations/v219.go +++ b/models/migrations/v1_17/v219.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_17 // nolint import ( "time" @@ -13,7 +13,7 @@ import ( "xorm.io/xorm" ) -func addSyncOnCommitColForPushMirror(x *xorm.Engine) error { +func AddSyncOnCommitColForPushMirror(x *xorm.Engine) error { type PushMirror struct { ID int64 `xorm:"pk autoincr"` RepoID int64 `xorm:"INDEX"` diff --git a/models/migrations/v220.go b/models/migrations/v1_17/v220.go similarity index 93% rename from models/migrations/v220.go rename to models/migrations/v1_17/v220.go index 8138bc5bb149..bbceb933b3f6 100644 --- a/models/migrations/v220.go +++ b/models/migrations/v1_17/v220.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_17 // nolint import ( packages_model "code.gitea.io/gitea/models/packages" @@ -12,7 +12,7 @@ import ( "xorm.io/xorm/schemas" ) -func addContainerRepositoryProperty(x *xorm.Engine) (err error) { +func AddContainerRepositoryProperty(x *xorm.Engine) (err error) { switch x.Dialect().URI().DBType { case schemas.SQLITE: _, err = x.Exec("INSERT INTO package_property (ref_type, ref_id, name, value) SELECT ?, p.id, ?, u.lower_name || '/' || p.lower_name FROM package p JOIN `user` u ON p.owner_id = u.id WHERE p.type = ?", diff --git a/models/migrations/v221.go b/models/migrations/v1_17/v221.go similarity index 96% rename from models/migrations/v221.go rename to models/migrations/v1_17/v221.go index f3bcfcdf1de2..17744d53ab02 100644 --- a/models/migrations/v221.go +++ b/models/migrations/v1_17/v221.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_17 // nolint import ( "encoding/base32" @@ -13,7 +13,7 @@ import ( "xorm.io/xorm" ) -func storeWebauthnCredentialIDAsBytes(x *xorm.Engine) error { +func StoreWebauthnCredentialIDAsBytes(x *xorm.Engine) error { // Create webauthnCredential table type webauthnCredential struct { ID int64 `xorm:"pk autoincr"` diff --git a/models/migrations/v221_test.go b/models/migrations/v1_17/v221_test.go similarity index 85% rename from models/migrations/v221_test.go rename to models/migrations/v1_17/v221_test.go index c50ca5c87329..d635820f82a1 100644 --- a/models/migrations/v221_test.go +++ b/models/migrations/v1_17/v221_test.go @@ -2,16 +2,18 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_17 // nolint import ( "encoding/base32" "testing" + "code.gitea.io/gitea/models/migrations/base" + "github.com/stretchr/testify/assert" ) -func Test_storeWebauthnCredentialIDAsBytes(t *testing.T) { +func Test_StoreWebauthnCredentialIDAsBytes(t *testing.T) { // Create webauthnCredential table type WebauthnCredential struct { ID int64 `xorm:"pk autoincr"` @@ -37,13 +39,13 @@ func Test_storeWebauthnCredentialIDAsBytes(t *testing.T) { } // Prepare and load the testing database - x, deferable := prepareTestEnv(t, 0, new(WebauthnCredential), new(ExpectedWebauthnCredential)) + x, deferable := base.PrepareTestEnv(t, 0, new(WebauthnCredential), new(ExpectedWebauthnCredential)) defer deferable() if x == nil || t.Failed() { return } - if err := storeWebauthnCredentialIDAsBytes(x); err != nil { + if err := StoreWebauthnCredentialIDAsBytes(x); err != nil { assert.NoError(t, err) return } diff --git a/models/migrations/v222.go b/models/migrations/v1_17/v222.go similarity index 89% rename from models/migrations/v222.go rename to models/migrations/v1_17/v222.go index 99acdfd20608..3aafb1848d3e 100644 --- a/models/migrations/v222.go +++ b/models/migrations/v1_17/v222.go @@ -2,18 +2,19 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_17 // nolint import ( "context" "fmt" + "code.gitea.io/gitea/models/migrations/base" "code.gitea.io/gitea/modules/timeutil" "xorm.io/xorm" ) -func dropOldCredentialIDColumn(x *xorm.Engine) error { +func DropOldCredentialIDColumn(x *xorm.Engine) error { // This migration maybe rerun so that we should check if it has been run credentialIDExist, err := x.Dialect().IsColumnExist(x.DB(), context.Background(), "webauthn_credential", "credential_id") if err != nil { @@ -57,7 +58,7 @@ func dropOldCredentialIDColumn(x *xorm.Engine) error { sess := x.NewSession() defer sess.Close() - if err := dropTableColumns(sess, "webauthn_credential", "credential_id"); err != nil { + if err := base.DropTableColumns(sess, "webauthn_credential", "credential_id"); err != nil { return fmt.Errorf("unable to drop old credentialID column: %w", err) } return sess.Commit() diff --git a/models/migrations/v223.go b/models/migrations/v1_17/v223.go similarity index 93% rename from models/migrations/v223.go rename to models/migrations/v1_17/v223.go index 9f4c6acfe332..530ddf0e05c8 100644 --- a/models/migrations/v223.go +++ b/models/migrations/v1_17/v223.go @@ -2,19 +2,20 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_17 // nolint import ( "context" "fmt" + "code.gitea.io/gitea/models/migrations/base" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" "xorm.io/xorm" ) -func renameCredentialIDBytes(x *xorm.Engine) error { +func RenameCredentialIDBytes(x *xorm.Engine) error { // This migration maybe rerun so that we should check if it has been run credentialIDExist, err := x.Dialect().IsColumnExist(x.DB(), context.Background(), "webauthn_credential", "credential_id") if err != nil { @@ -59,7 +60,7 @@ func renameCredentialIDBytes(x *xorm.Engine) error { if credentialIDExist { // if both errors and message exist, drop message at first - if err := dropTableColumns(sess, "webauthn_credential", "credential_id"); err != nil { + if err := base.DropTableColumns(sess, "webauthn_credential", "credential_id"); err != nil { return err } } diff --git a/models/migrations/v1_18/main_test.go b/models/migrations/v1_18/main_test.go new file mode 100644 index 000000000000..cb0934042843 --- /dev/null +++ b/models/migrations/v1_18/main_test.go @@ -0,0 +1,15 @@ +// Copyright 2021 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package v1_18 // nolint + +import ( + "testing" + + "code.gitea.io/gitea/models/migrations/base" +) + +func TestMain(m *testing.M) { + base.MainTest(m) +} diff --git a/models/migrations/v224.go b/models/migrations/v1_18/v224.go similarity index 87% rename from models/migrations/v224.go rename to models/migrations/v1_18/v224.go index 2ed161ef4da7..34dbcc1aa192 100644 --- a/models/migrations/v224.go +++ b/models/migrations/v1_18/v224.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_18 // nolint import ( "xorm.io/xorm" ) -func createUserBadgesTable(x *xorm.Engine) error { +func CreateUserBadgesTable(x *xorm.Engine) error { type Badge struct { ID int64 `xorm:"pk autoincr"` Description string diff --git a/models/migrations/v225.go b/models/migrations/v1_18/v225.go similarity index 87% rename from models/migrations/v225.go rename to models/migrations/v1_18/v225.go index 6dd460eb68a9..8848a8982587 100644 --- a/models/migrations/v225.go +++ b/models/migrations/v1_18/v225.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_18 // nolint import ( "code.gitea.io/gitea/modules/setting" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func alterPublicGPGKeyContentFieldsToMediumText(x *xorm.Engine) error { +func AlterPublicGPGKeyContentFieldsToMediumText(x *xorm.Engine) error { sess := x.NewSession() defer sess.Close() if err := sess.Begin(); err != nil { diff --git a/models/migrations/v226.go b/models/migrations/v1_18/v226.go similarity index 82% rename from models/migrations/v226.go rename to models/migrations/v1_18/v226.go index 2f85bca21f67..bff88cbefa0b 100644 --- a/models/migrations/v226.go +++ b/models/migrations/v1_18/v226.go @@ -2,14 +2,14 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_18 // nolint import ( "xorm.io/builder" "xorm.io/xorm" ) -func fixPackageSemverField(x *xorm.Engine) error { +func FixPackageSemverField(x *xorm.Engine) error { _, err := x.Exec(builder.Update(builder.Eq{"semver_compatible": false}).From("`package`").Where(builder.In("`type`", "conan", "generic"))) return err } diff --git a/models/migrations/v227.go b/models/migrations/v1_18/v227.go similarity index 95% rename from models/migrations/v227.go rename to models/migrations/v1_18/v227.go index 36c0a5eef138..7dc468108c3a 100644 --- a/models/migrations/v227.go +++ b/models/migrations/v1_18/v227.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_18 // nolint import ( "fmt" @@ -43,7 +43,7 @@ func insertSettingsIfNotExist(x *xorm.Engine, sysSettings []*SystemSetting) erro return sess.Commit() } -func createSystemSettingsTable(x *xorm.Engine) error { +func CreateSystemSettingsTable(x *xorm.Engine) error { if err := x.Sync2(new(SystemSetting)); err != nil { return fmt.Errorf("sync2: %w", err) } diff --git a/models/migrations/v228.go b/models/migrations/v1_18/v228.go similarity index 92% rename from models/migrations/v228.go rename to models/migrations/v1_18/v228.go index 62c81ef9d8c2..28ce171b535a 100644 --- a/models/migrations/v228.go +++ b/models/migrations/v1_18/v228.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_18 // nolint import ( "code.gitea.io/gitea/modules/timeutil" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addTeamInviteTable(x *xorm.Engine) error { +func AddTeamInviteTable(x *xorm.Engine) error { type TeamInvite struct { ID int64 `xorm:"pk autoincr"` Token string `xorm:"UNIQUE(token) INDEX NOT NULL DEFAULT ''"` diff --git a/models/migrations/v229.go b/models/migrations/v1_18/v229.go similarity index 94% rename from models/migrations/v229.go rename to models/migrations/v1_18/v229.go index 42ec2033fee2..ea7c3ed32910 100644 --- a/models/migrations/v229.go +++ b/models/migrations/v1_18/v229.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_18 //nolint import ( "fmt" @@ -13,7 +13,7 @@ import ( "xorm.io/xorm" ) -func updateOpenMilestoneCounts(x *xorm.Engine) error { +func UpdateOpenMilestoneCounts(x *xorm.Engine) error { var openMilestoneIDs []int64 err := x.Table("milestone").Select("id").Where(builder.Neq{"is_closed": 1}).Find(&openMilestoneIDs) if err != nil { diff --git a/models/migrations/v229_test.go b/models/migrations/v1_18/v229_test.go similarity index 75% rename from models/migrations/v229_test.go rename to models/migrations/v1_18/v229_test.go index f8a147c9bd69..caa24b26b8c0 100644 --- a/models/migrations/v229_test.go +++ b/models/migrations/v1_18/v229_test.go @@ -2,27 +2,28 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_18 //nolint import ( "testing" "code.gitea.io/gitea/models/issues" + "code.gitea.io/gitea/models/migrations/base" "github.com/stretchr/testify/assert" ) -func Test_updateOpenMilestoneCounts(t *testing.T) { +func Test_UpdateOpenMilestoneCounts(t *testing.T) { type ExpectedMilestone issues.Milestone // Prepare and load the testing database - x, deferable := prepareTestEnv(t, 0, new(issues.Milestone), new(ExpectedMilestone), new(issues.Issue)) + x, deferable := base.PrepareTestEnv(t, 0, new(issues.Milestone), new(ExpectedMilestone), new(issues.Issue)) defer deferable() if x == nil || t.Failed() { return } - if err := updateOpenMilestoneCounts(x); err != nil { + if err := UpdateOpenMilestoneCounts(x); err != nil { assert.NoError(t, err) return } diff --git a/models/migrations/v230.go b/models/migrations/v1_18/v230.go similarity index 72% rename from models/migrations/v230.go rename to models/migrations/v1_18/v230.go index f08e6a37641f..fe98e07a4582 100644 --- a/models/migrations/v230.go +++ b/models/migrations/v1_18/v230.go @@ -2,14 +2,14 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_18 // nolint import ( "xorm.io/xorm" ) -// addConfidentialColumnToOAuth2ApplicationTable: add ConfidentialClient column, setting existing rows to true -func addConfidentialClientColumnToOAuth2ApplicationTable(x *xorm.Engine) error { +// AddConfidentialColumnToOAuth2ApplicationTable: add ConfidentialClient column, setting existing rows to true +func AddConfidentialClientColumnToOAuth2ApplicationTable(x *xorm.Engine) error { type OAuth2Application struct { ConfidentialClient bool `xorm:"NOT NULL DEFAULT TRUE"` } diff --git a/models/migrations/v230_test.go b/models/migrations/v1_18/v230_test.go similarity index 75% rename from models/migrations/v230_test.go rename to models/migrations/v1_18/v230_test.go index 98ba3f5d9720..0af13a1b9ee5 100644 --- a/models/migrations/v230_test.go +++ b/models/migrations/v1_18/v230_test.go @@ -2,28 +2,30 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_18 //nolint import ( "testing" + "code.gitea.io/gitea/models/migrations/base" + "github.com/stretchr/testify/assert" ) -func Test_addConfidentialClientColumnToOAuth2ApplicationTable(t *testing.T) { +func Test_AddConfidentialClientColumnToOAuth2ApplicationTable(t *testing.T) { // premigration type OAuth2Application struct { ID int64 } // Prepare and load the testing database - x, deferable := prepareTestEnv(t, 0, new(OAuth2Application)) + x, deferable := base.PrepareTestEnv(t, 0, new(OAuth2Application)) defer deferable() if x == nil || t.Failed() { return } - if err := addConfidentialClientColumnToOAuth2ApplicationTable(x); err != nil { + if err := AddConfidentialClientColumnToOAuth2ApplicationTable(x); err != nil { assert.NoError(t, err) return } diff --git a/models/migrations/v231.go b/models/migrations/v1_19/v231.go similarity index 83% rename from models/migrations/v231.go rename to models/migrations/v1_19/v231.go index 34dc72294a79..809a1cfa5769 100644 --- a/models/migrations/v231.go +++ b/models/migrations/v1_19/v231.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_19 //nolint import ( "xorm.io/xorm" ) -func addIndexForHookTask(x *xorm.Engine) error { +func AddIndexForHookTask(x *xorm.Engine) error { type HookTask struct { ID int64 `xorm:"pk autoincr"` HookID int64 `xorm:"index"` diff --git a/models/migrations/v70.go b/models/migrations/v1_6/v70.go similarity index 97% rename from models/migrations/v70.go rename to models/migrations/v1_6/v70.go index b2563544b2d1..880bcb8af747 100644 --- a/models/migrations/v70.go +++ b/models/migrations/v1_6/v70.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_6 // nolint import ( "fmt" @@ -13,7 +13,7 @@ import ( "xorm.io/xorm" ) -func addIssueDependencies(x *xorm.Engine) (err error) { +func AddIssueDependencies(x *xorm.Engine) (err error) { type IssueDependency struct { ID int64 `xorm:"pk autoincr"` UserID int64 `xorm:"NOT NULL"` diff --git a/models/migrations/v71.go b/models/migrations/v1_6/v71.go similarity index 81% rename from models/migrations/v71.go rename to models/migrations/v1_6/v71.go index 70314386d711..c021a24abcc2 100644 --- a/models/migrations/v71.go +++ b/models/migrations/v1_6/v71.go @@ -2,20 +2,19 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_6 // nolint import ( - "crypto/sha256" "fmt" + "code.gitea.io/gitea/models/migrations/base" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" - "golang.org/x/crypto/pbkdf2" "xorm.io/xorm" ) -func addScratchHash(x *xorm.Engine) error { +func AddScratchHash(x *xorm.Engine) error { // TwoFactor see models/twofactor.go type TwoFactor struct { ID int64 `xorm:"pk autoincr"` @@ -58,7 +57,7 @@ func addScratchHash(x *xorm.Engine) error { return err } tfa.ScratchSalt = salt - tfa.ScratchHash = hashToken(tfa.ScratchToken, salt) + tfa.ScratchHash = base.HashToken(tfa.ScratchToken, salt) if _, err := sess.ID(tfa.ID).Cols("scratch_salt, scratch_hash").Update(tfa); err != nil { return fmt.Errorf("couldn't add in scratch_hash and scratch_salt: %w", err) @@ -75,13 +74,8 @@ func addScratchHash(x *xorm.Engine) error { return err } - if err := dropTableColumns(sess, "two_factor", "scratch_token"); err != nil { + if err := base.DropTableColumns(sess, "two_factor", "scratch_token"); err != nil { return err } return sess.Commit() } - -func hashToken(token, salt string) string { - tempHash := pbkdf2.Key([]byte(token), []byte(salt), 10000, 50, sha256.New) - return fmt.Sprintf("%x", tempHash) -} diff --git a/models/migrations/v72.go b/models/migrations/v1_6/v72.go similarity index 91% rename from models/migrations/v72.go rename to models/migrations/v1_6/v72.go index 2be4233863ff..275512c4d006 100644 --- a/models/migrations/v72.go +++ b/models/migrations/v1_6/v72.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_6 // nolint import ( "fmt" @@ -12,7 +12,7 @@ import ( "xorm.io/xorm" ) -func addReview(x *xorm.Engine) error { +func AddReview(x *xorm.Engine) error { // Review see models/review.go type Review struct { ID int64 `xorm:"pk autoincr"` diff --git a/models/migrations/v73.go b/models/migrations/v1_7/v73.go similarity index 83% rename from models/migrations/v73.go rename to models/migrations/v1_7/v73.go index 0c06e2ba5cfd..aa2cbba88afd 100644 --- a/models/migrations/v73.go +++ b/models/migrations/v1_7/v73.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_7 // nolint import ( "xorm.io/xorm" ) -func addMustChangePassword(x *xorm.Engine) error { +func AddMustChangePassword(x *xorm.Engine) error { // User see models/user.go type User struct { ID int64 `xorm:"pk autoincr"` diff --git a/models/migrations/v74.go b/models/migrations/v1_7/v74.go similarity index 83% rename from models/migrations/v74.go rename to models/migrations/v1_7/v74.go index f3b38418b752..3694d68d310a 100644 --- a/models/migrations/v74.go +++ b/models/migrations/v1_7/v74.go @@ -2,11 +2,11 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_7 // nolint import "xorm.io/xorm" -func addApprovalWhitelistsToProtectedBranches(x *xorm.Engine) error { +func AddApprovalWhitelistsToProtectedBranches(x *xorm.Engine) error { type ProtectedBranch struct { ApprovalsWhitelistUserIDs []int64 `xorm:"JSON TEXT"` ApprovalsWhitelistTeamIDs []int64 `xorm:"JSON TEXT"` diff --git a/models/migrations/v75.go b/models/migrations/v1_7/v75.go similarity index 91% rename from models/migrations/v75.go rename to models/migrations/v1_7/v75.go index 208153b9b0df..df2666735115 100644 --- a/models/migrations/v75.go +++ b/models/migrations/v1_7/v75.go @@ -2,14 +2,14 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_7 // nolint import ( "xorm.io/builder" "xorm.io/xorm" ) -func clearNonusedData(x *xorm.Engine) error { +func ClearNonusedData(x *xorm.Engine) error { condDelete := func(colName string) builder.Cond { return builder.NotIn(colName, builder.Select("id").From("`user`")) } diff --git a/models/migrations/v76.go b/models/migrations/v1_8/v76.go similarity index 96% rename from models/migrations/v76.go rename to models/migrations/v1_8/v76.go index 2686422723f2..ef60eb726050 100644 --- a/models/migrations/v76.go +++ b/models/migrations/v1_8/v76.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_8 // nolint import ( "fmt" @@ -12,7 +12,7 @@ import ( "xorm.io/xorm" ) -func addPullRequestRebaseWithMerge(x *xorm.Engine) error { +func AddPullRequestRebaseWithMerge(x *xorm.Engine) error { // RepoUnit describes all units of a repository type RepoUnit struct { ID int64 diff --git a/models/migrations/v77.go b/models/migrations/v1_8/v77.go similarity index 80% rename from models/migrations/v77.go rename to models/migrations/v1_8/v77.go index d62fbe7fb6f0..7d5dccc9b639 100644 --- a/models/migrations/v77.go +++ b/models/migrations/v1_8/v77.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_8 // nolint import ( "xorm.io/xorm" ) -func addUserDefaultTheme(x *xorm.Engine) error { +func AddUserDefaultTheme(x *xorm.Engine) error { type User struct { Theme string `xorm:"VARCHAR(30) NOT NULL DEFAULT ''"` } diff --git a/models/migrations/v78.go b/models/migrations/v1_8/v78.go similarity index 78% rename from models/migrations/v78.go rename to models/migrations/v1_8/v78.go index e4274ca60576..d7943fb0aa40 100644 --- a/models/migrations/v78.go +++ b/models/migrations/v1_8/v78.go @@ -2,13 +2,15 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_8 // nolint import ( + "code.gitea.io/gitea/models/migrations/base" + "xorm.io/xorm" ) -func renameRepoIsBareToIsEmpty(x *xorm.Engine) error { +func RenameRepoIsBareToIsEmpty(x *xorm.Engine) error { type Repository struct { ID int64 `xorm:"pk autoincr"` IsBare bool @@ -34,7 +36,7 @@ func renameRepoIsBareToIsEmpty(x *xorm.Engine) error { if err := sess.Begin(); err != nil { return err } - if err := dropTableColumns(sess, "repository", "is_bare"); err != nil { + if err := base.DropTableColumns(sess, "repository", "is_bare"); err != nil { return err } diff --git a/models/migrations/v79.go b/models/migrations/v1_8/v79.go similarity index 87% rename from models/migrations/v79.go rename to models/migrations/v1_8/v79.go index 818bfa4a0dc5..6a867f50552f 100644 --- a/models/migrations/v79.go +++ b/models/migrations/v1_8/v79.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_8 // nolint import ( "code.gitea.io/gitea/modules/setting" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addCanCloseIssuesViaCommitInAnyBranch(x *xorm.Engine) error { +func AddCanCloseIssuesViaCommitInAnyBranch(x *xorm.Engine) error { type Repository struct { ID int64 `xorm:"pk autoincr"` CloseIssuesViaCommitInAnyBranch bool `xorm:"NOT NULL DEFAULT false"` diff --git a/models/migrations/v80.go b/models/migrations/v1_8/v80.go similarity index 83% rename from models/migrations/v80.go rename to models/migrations/v1_8/v80.go index 3c1b3315cf6f..2e1b0631e1d9 100644 --- a/models/migrations/v80.go +++ b/models/migrations/v1_8/v80.go @@ -2,11 +2,11 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_8 // nolint import "xorm.io/xorm" -func addIsLockedToIssues(x *xorm.Engine) error { +func AddIsLockedToIssues(x *xorm.Engine) error { // Issue see models/issue.go type Issue struct { ID int64 `xorm:"pk autoincr"` diff --git a/models/migrations/v81.go b/models/migrations/v1_8/v81.go similarity index 90% rename from models/migrations/v81.go rename to models/migrations/v1_8/v81.go index 5141f975764f..b06f879ef54c 100644 --- a/models/migrations/v81.go +++ b/models/migrations/v1_8/v81.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_8 // nolint import ( "fmt" @@ -11,7 +11,7 @@ import ( "xorm.io/xorm/schemas" ) -func changeU2FCounterType(x *xorm.Engine) error { +func ChangeU2FCounterType(x *xorm.Engine) error { var err error switch x.Dialect().URI().DBType { diff --git a/models/migrations/v82.go b/models/migrations/v1_9/v82.go similarity index 97% rename from models/migrations/v82.go rename to models/migrations/v1_9/v82.go index 8e07e633c934..82cb8b3ce1a4 100644 --- a/models/migrations/v82.go +++ b/models/migrations/v1_9/v82.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_9 // nolint import ( "fmt" @@ -15,7 +15,7 @@ import ( "xorm.io/xorm" ) -func fixReleaseSha1OnReleaseTable(x *xorm.Engine) error { +func FixReleaseSha1OnReleaseTable(x *xorm.Engine) error { type Release struct { ID int64 RepoID int64 diff --git a/models/migrations/v83.go b/models/migrations/v1_9/v83.go similarity index 90% rename from models/migrations/v83.go rename to models/migrations/v1_9/v83.go index 6707dbdf812b..31cce268eb82 100644 --- a/models/migrations/v83.go +++ b/models/migrations/v1_9/v83.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_9 //nolint import ( "code.gitea.io/gitea/modules/timeutil" @@ -10,7 +10,7 @@ import ( "xorm.io/xorm" ) -func addUploaderIDForAttachment(x *xorm.Engine) error { +func AddUploaderIDForAttachment(x *xorm.Engine) error { type Attachment struct { ID int64 `xorm:"pk autoincr"` UUID string `xorm:"uuid UNIQUE"` diff --git a/models/migrations/v84.go b/models/migrations/v1_9/v84.go similarity index 83% rename from models/migrations/v84.go rename to models/migrations/v1_9/v84.go index baab29fcd706..8aa7fbc07a9a 100644 --- a/models/migrations/v84.go +++ b/models/migrations/v1_9/v84.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_9 //nolint import ( "xorm.io/xorm" ) -func addGPGKeyImport(x *xorm.Engine) error { +func AddGPGKeyImport(x *xorm.Engine) error { type GPGKeyImport struct { KeyID string `xorm:"pk CHAR(16) NOT NULL"` Content string `xorm:"TEXT NOT NULL"` diff --git a/models/migrations/v85.go b/models/migrations/v1_9/v85.go similarity index 92% rename from models/migrations/v85.go rename to models/migrations/v1_9/v85.go index 317660eb6f04..0cd32c3829d4 100644 --- a/models/migrations/v85.go +++ b/models/migrations/v1_9/v85.go @@ -2,11 +2,12 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_9 //nolint import ( "fmt" + "code.gitea.io/gitea/models/migrations/base" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/timeutil" "code.gitea.io/gitea/modules/util" @@ -14,7 +15,7 @@ import ( "xorm.io/xorm" ) -func hashAppToken(x *xorm.Engine) error { +func HashAppToken(x *xorm.Engine) error { // AccessToken see models/token.go type AccessToken struct { ID int64 `xorm:"pk autoincr"` @@ -70,7 +71,7 @@ func hashAppToken(x *xorm.Engine) error { return err } token.TokenSalt = salt - token.TokenHash = hashToken(token.Sha1, salt) + token.TokenHash = base.HashToken(token.Sha1, salt) if len(token.Sha1) < 8 { log.Warn("Unable to transform token %s with name %s belonging to user ID %d, skipping transformation", token.Sha1, token.Name, token.UID) continue @@ -93,7 +94,7 @@ func hashAppToken(x *xorm.Engine) error { return err } - if err := dropTableColumns(sess, "access_token", "sha1"); err != nil { + if err := base.DropTableColumns(sess, "access_token", "sha1"); err != nil { return err } if err := sess.Commit(); err != nil { diff --git a/models/migrations/v86.go b/models/migrations/v1_9/v86.go similarity index 80% rename from models/migrations/v86.go rename to models/migrations/v1_9/v86.go index 39c196ca6a37..416e4fad93cf 100644 --- a/models/migrations/v86.go +++ b/models/migrations/v1_9/v86.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_9 //nolint import ( "xorm.io/xorm" ) -func addHTTPMethodToWebhook(x *xorm.Engine) error { +func AddHTTPMethodToWebhook(x *xorm.Engine) error { type Webhook struct { HTTPMethod string `xorm:"http_method DEFAULT 'POST'"` } diff --git a/models/migrations/v87.go b/models/migrations/v1_9/v87.go similarity index 81% rename from models/migrations/v87.go rename to models/migrations/v1_9/v87.go index 6b5af5be3367..97c8f621c682 100644 --- a/models/migrations/v87.go +++ b/models/migrations/v1_9/v87.go @@ -2,13 +2,13 @@ // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. -package migrations +package v1_9 //nolint import ( "xorm.io/xorm" ) -func addAvatarFieldToRepository(x *xorm.Engine) error { +func AddAvatarFieldToRepository(x *xorm.Engine) error { type Repository struct { // ID(10-20)-md5(32) - must fit into 64 symbols Avatar string `xorm:"VARCHAR(64)"` diff --git a/tests/integration/migration-test/migration_test.go b/tests/integration/migration-test/migration_test.go index b631168340a7..0159fb4f3c79 100644 --- a/tests/integration/migration-test/migration_test.go +++ b/tests/integration/migration-test/migration_test.go @@ -20,6 +20,7 @@ import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/migrations" + migrate_base "code.gitea.io/gitea/models/migrations/base" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/charset" @@ -302,7 +303,7 @@ func doMigrationTest(t *testing.T, version string) { err = db.InitEngineWithMigration(context.Background(), func(x *xorm.Engine) error { currentEngine = x - return migrations.RecreateTables(beans...)(x) + return migrate_base.RecreateTables(beans...)(x) }) assert.NoError(t, err) currentEngine.Close() @@ -310,7 +311,7 @@ func doMigrationTest(t *testing.T, version string) { // We do this a second time to ensure that there is not a problem with retained indices err = db.InitEngineWithMigration(context.Background(), func(x *xorm.Engine) error { currentEngine = x - return migrations.RecreateTables(beans...)(x) + return migrate_base.RecreateTables(beans...)(x) }) assert.NoError(t, err)