File size: 2,736 Bytes
8da2481 | 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 | defmodule Plausible.DataMigration.PrefixTrackerScriptConfigurationId do
@moduledoc """
Migration to update tracker script configuration IDs to use the new prefixed format.
This migration:
1. Processes tracker configurations in batches to avoid memory issues
2. Uses batch updates for better performance
3. Handles the case where tracker configurations might not exist for all sites
4. Provides progress logging
"""
import Ecto.Query
alias Plausible.Repo
alias Plausible.Site.TrackerScriptConfiguration
def run(batch_size \\ 100) do
total_configs = count_total_configurations()
IO.puts("Found #{total_configs} total tracker configurations to process")
process_batch(nil, total_configs, batch_size, 0)
end
defp count_total_configurations do
Repo.aggregate(
from(config in TrackerScriptConfiguration,
where: not like(config.id, "pa-%")
),
:count,
:id
)
end
defp process_batch(last_id, total_configs, batch_size, processed_count) do
configs = get_configurations_batch(last_id, batch_size)
if length(configs) > 0 do
batch_num = div(processed_count, batch_size) + 1
start_pos = processed_count + 1
end_pos = processed_count + length(configs)
IO.puts("Processing batch #{batch_num} (#{start_pos}-#{end_pos} of #{total_configs})")
process_configurations_batch(configs, batch_num)
process_batch(
List.last(configs).id,
total_configs,
batch_size,
processed_count + length(configs)
)
else
IO.puts("Migration completed!")
end
end
defp get_configurations_batch(last_id, batch_size) do
query =
from(config in TrackerScriptConfiguration,
where: not like(config.id, "pa-%"),
order_by: [asc: config.id],
limit: ^batch_size,
select: %{
id: config.id
}
)
query =
if last_id do
from(config in query, where: config.id > ^last_id)
else
query
end
Repo.all(query)
end
defp process_configurations_batch(configs, batch_num) do
config_ids = Enum.map(configs, & &1.id)
case Repo.query(
"UPDATE tracker_script_configuration SET id = 'pa-' || id WHERE id = ANY($1)",
[config_ids]
) do
{:ok, %{num_rows: updated_count}} ->
if updated_count != length(configs) do
IO.puts(
"Warning: Batch #{batch_num} - Expected to update #{length(configs)} configurations, but updated #{updated_count}"
)
end
{:error, error} ->
IO.puts("Error updating batch #{batch_num}: #{inspect(error)}")
# Continue with next batch instead of crashing
end
end
end
|