-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmigration_bootloader.lua
More file actions
152 lines (132 loc) · 4.53 KB
/
migration_bootloader.lua
File metadata and controls
152 lines (132 loc) · 4.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
local time = require("time")
local sql = require("sql")
local logger = require("logger")
local migration_registry = require("migration_registry")
local runner = require("runner")
local log = logger:named("boot.migrations")
local function wait_for_database(db_id, max_attempts, sleep_ms)
for attempt = 1, max_attempts do
local db, err = sql.get(db_id)
if not err then
db:release()
if attempt > 1 then
log:info("Database connection established", {
database = db_id,
attempts = attempt
})
end
return true, nil
end
if attempt < max_attempts then
log:warn("Database not ready, retrying...", {
database = db_id,
attempt = attempt,
max_attempts = max_attempts,
error = err
})
time.sleep(sleep_ms .. "ms")
else
log:error("Database connection failed after max attempts", {
database = db_id,
attempts = max_attempts,
error = err
})
return false, err
end
end
return false, "Max retry attempts reached"
end
local function run(options)
log:info("Starting migration bootloader")
-- Find target databases
local target_dbs, err = migration_registry.get_target_dbs()
if err then
return {
status = "error",
message = "Failed to discover target databases: " .. tostring(err)
}
end
if not target_dbs or #target_dbs == 0 then
log:info("No target databases found")
return {
status = "skipped",
message = "No migrations to apply"
}
end
log:info("Discovered target databases", {
count = #target_dbs,
databases = target_dbs
})
local total_applied = 0
local total_failed = 0
local total_skipped = 0
local databases_processed = {}
-- Execute migrations for each target database
for _, db_resource in ipairs(target_dbs) do
log:info("Processing migrations for database", { database = db_resource })
local db_ready, db_err = wait_for_database(db_resource, 20, 500)
if not db_ready then
log:error("Database unavailable, skipping migrations", {
database = db_resource,
error = db_err
})
return {
status = "error",
message = "Database unavailable: " .. db_err,
details = {
database = db_resource,
databases_processed = databases_processed
}
}
end
local db_runner = runner.setup(db_resource)
local result = db_runner:run()
table.insert(databases_processed, {
database = db_resource,
applied = result.migrations_applied or 0,
failed = result.migrations_failed or 0,
skipped = result.migrations_skipped or 0,
status = result.status
})
total_applied = total_applied + (result.migrations_applied or 0)
total_failed = total_failed + (result.migrations_failed or 0)
total_skipped = total_skipped + (result.migrations_skipped or 0)
if result.status == "error" then
log:error("Migration failed for database", {
database = db_resource,
error = result.error
})
return {
status = "error",
message = "Migration failed: " .. result.error,
details = {
databases_processed = databases_processed,
total_applied = total_applied,
total_failed = total_failed,
total_skipped = total_skipped
}
}
end
log:info("Completed migrations for database", {
database = db_resource,
applied = result.migrations_applied,
skipped = result.migrations_skipped
})
end
return {
status = "success",
message = string.format(
"Processed %d database(s): %d applied, %d skipped",
#target_dbs,
total_applied,
total_skipped
),
details = {
databases_processed = databases_processed,
total_applied = total_applied,
total_failed = total_failed,
total_skipped = total_skipped
}
}
end
return { run = run }