Skip to content

Commit

Permalink
fix(migrations) stop depending on the order as recorded
Browse files Browse the repository at this point in the history
Migrations are recorded in the datastore and then the order in which
they appear there is relevant for determining if they should run.

Once something goes out-of-sync on every start/restart it will keep
running migrations over and over again.

From #2869
  • Loading branch information
Tieske authored and thibaultcha committed Sep 8, 2017
1 parent 81da4f1 commit deb1fed
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 3 deletions.
10 changes: 7 additions & 3 deletions kong/dao/factory.lua
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,14 @@ end

local function migrate(self, identifier, migrations_modules, cur_migrations, on_migrate, on_success)
local migrations = migrations_modules[identifier]
local recorded = cur_migrations[identifier] or {}
local recorded = {}
for _, name in ipairs(cur_migrations[identifier] or {}) do
recorded[name] = true
end

local to_run = {}
for i, mig in ipairs(migrations) do
if mig.name ~= recorded[i] then
for _, mig in ipairs(migrations) do
if not recorded[mig.name] then
to_run[#to_run + 1] = mig
end
end
Expand Down
23 changes: 23 additions & 0 deletions spec/02-integration/03-dao/02-migrations_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,29 @@ helpers.for_each_dao(function(kong_config)
assert.falsy(err)
assert.True(ok)

assert.spy(on_migration).was_not_called()
assert.spy(on_success).was_not_called()
end)
it("should not depend on order of the migration entries", function()
local old_fetcher = factory.current_migrations
finally(function()
factory.current_migrations = old_fetcher
end)

factory.current_migrations = function(...)
local mig = old_fetcher(...)
local core = mig.core
core[#core], core[#core-1] = core[#core-1], core[#core]
return mig
end

local on_migration = spy.new(function() end)
local on_success = spy.new(function() end)

local ok, err = factory:run_migrations(on_migration, on_success)
assert.falsy(err)
assert.True(ok)

assert.spy(on_migration).was_not_called()
assert.spy(on_success).was_not_called()
end)
Expand Down

0 comments on commit deb1fed

Please sign in to comment.