mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
Add order column to bw_selects and update migration scripts for version 1.6.0-rc2
This commit is contained in:
parent
51f6cf570d
commit
87fdcb2ece
12 changed files with 391 additions and 61 deletions
|
|
@ -75,6 +75,7 @@ jq -r 'to_entries[] | "\(.key) \(.value)"' databases.json | while read -r databa
|
|||
# Start the database stack if not SQLite
|
||||
if [[ "$database" != "sqlite" ]]; then
|
||||
log "🚀 Starting Docker stack for $database"
|
||||
docker compose -f "$database.yml" pull || true
|
||||
if ! docker compose -f "$database.yml" up -d; then
|
||||
log "❌ Failed to start the Docker stack for $database"
|
||||
docker compose down -v --remove-orphans
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
{
|
||||
"sqlite": "sqlite:////var/lib/bunkerweb/db.sqlite3",
|
||||
"mariadb": "mariadb+pymysql://bunkerweb:secret@bw-db:3306/db",
|
||||
"mysql": "mysql+pymysql://bunkerweb:secret@bw-db:3306/db",
|
||||
"postgresql": "postgresql+psycopg://bunkerweb:secret@bw-db:5432/db"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ from re import Match, compile as re_compile, escape, error as RegexError, search
|
|||
from sys import argv, path as sys_path
|
||||
from tarfile import open as tar_open
|
||||
from threading import Lock
|
||||
from traceback import format_exc
|
||||
from typing import Any, Dict, List, Literal, Optional, Set, Tuple, Union
|
||||
from time import sleep
|
||||
from uuid import uuid4
|
||||
|
|
@ -605,7 +606,7 @@ class Database:
|
|||
# For selects:
|
||||
old_selects = {}
|
||||
for sel in old_data.get("bw_selects", []):
|
||||
old_selects[(sel.setting_id, sel.value)] = sel
|
||||
old_selects[(sel.setting_id, sel.value, sel.order)] = sel
|
||||
|
||||
# For jobs:
|
||||
old_jobs = {}
|
||||
|
|
@ -628,11 +629,11 @@ class Database:
|
|||
|
||||
old_template_settings = {}
|
||||
for ts in old_data.get("bw_template_settings", []):
|
||||
old_template_settings[(ts.template_id, ts.setting_id, ts.suffix, ts.step_id)] = ts
|
||||
old_template_settings[(ts.template_id, ts.setting_id, ts.suffix, ts.step_id, ts.order)] = ts.default
|
||||
|
||||
old_template_configs = {}
|
||||
for tc in old_data.get("bw_template_custom_configs", []):
|
||||
old_template_configs[(tc.template_id, tc.type, tc.name, tc.step_id)] = tc
|
||||
old_template_configs[(tc.template_id, tc.type, tc.name, tc.step_id, ts.order)] = tc
|
||||
|
||||
# Build desired data from default_plugins
|
||||
# The following logic is similar to the original code but uses dicts/sets for comparisons.
|
||||
|
|
@ -833,6 +834,7 @@ class Database:
|
|||
suffix = 0
|
||||
if hasattr(self, "suffix_rx") and self.suffix_rx.search(setting):
|
||||
setting_id, suffix = setting.rsplit("_", 1)
|
||||
suffix = int(suffix) # noqa: FURB123
|
||||
if setting_id not in saved_settings:
|
||||
self.logger.error(
|
||||
f'{base_plugin.get("type", "core").title()} Plugin "{base_plugin["id"]}"\'s Template {template_id} has invalid setting "{setting}", skipping'
|
||||
|
|
@ -840,19 +842,19 @@ class Database:
|
|||
continue
|
||||
|
||||
# Check if belongs to a step
|
||||
step_for_setting = None
|
||||
step_id = None
|
||||
for sid, step_set_list in steps_settings.items():
|
||||
if setting in step_set_list:
|
||||
step_for_setting = sid
|
||||
step_id = sid
|
||||
break
|
||||
|
||||
if not step_for_setting:
|
||||
if not step_id:
|
||||
self.logger.error(
|
||||
f'{base_plugin.get("type", "core").title()} Plugin "{base_plugin["id"]}"\'s Template {template_id}`s setting "{setting}" doesn\'t belong to a step, skipping'
|
||||
)
|
||||
continue
|
||||
|
||||
desired_template_settings[(template_id, setting_id, suffix, step_for_setting)] = {"default": default, "order": order}
|
||||
desired_template_settings[(template_id, setting_id, suffix, step_id, order)] = default
|
||||
order += 1
|
||||
|
||||
# Template-level configs
|
||||
|
|
@ -883,22 +885,21 @@ class Database:
|
|||
config_name_clean = config_name.replace(".conf", "")
|
||||
|
||||
# Check if belongs to a step
|
||||
step_for_config = None
|
||||
step_id = None
|
||||
for sid, step_conf_list in steps_configs.items():
|
||||
if config in step_conf_list:
|
||||
step_for_config = sid
|
||||
step_id = sid
|
||||
break
|
||||
|
||||
if not step_for_config:
|
||||
if not step_id:
|
||||
self.logger.error(
|
||||
f'{base_plugin.get("type", "core").title()} Plugin "{base_plugin["id"]}"\'s Template {template_id}`s config "{config}" doesn\'t belong to a step, skipping'
|
||||
)
|
||||
continue
|
||||
|
||||
desired_template_configs[(template_id, config_type, config_name_clean, step_for_config)] = {
|
||||
desired_template_configs[(template_id, config_type, config_name_clean, step_id, order)] = {
|
||||
"data": content,
|
||||
"checksum": checksum,
|
||||
"order": order,
|
||||
}
|
||||
order += 1
|
||||
|
||||
|
|
@ -944,7 +945,7 @@ class Database:
|
|||
to_delete.append({"type": "setting", "filter": {"plugin_id": sk[0], "id": sk[1]}})
|
||||
|
||||
# SELECTS
|
||||
old_select_keys = set((s.setting_id, s.value, s.order) for s in old_selects.values())
|
||||
old_select_keys = set(old_selects.keys())
|
||||
# desired_selects is a set of (setting_id, value, order)
|
||||
# We must correlate with known settings. If setting_id belongs to a plugin_id?
|
||||
# Original code just handled removing selects not present. We'll trust that logic:
|
||||
|
|
@ -1057,32 +1058,39 @@ class Database:
|
|||
new_ts_keys = set(desired_template_settings.keys())
|
||||
|
||||
for tsk in new_ts_keys - old_ts_keys:
|
||||
template_id, setting_id, suffix, step_id = tsk
|
||||
default = desired_template_settings[tsk]["default"]
|
||||
order = desired_template_settings[tsk]["order"]
|
||||
to_put.append(Template_settings(template_id=template_id, setting_id=setting_id, suffix=suffix, step_id=step_id, default=default, order=order))
|
||||
template_id, setting_id, suffix, step_id, order = tsk
|
||||
default = desired_template_settings[tsk]
|
||||
to_put.append(
|
||||
Template_settings(
|
||||
template_id=template_id,
|
||||
setting_id=setting_id,
|
||||
suffix=suffix,
|
||||
step_id=step_id,
|
||||
default=default,
|
||||
order=order,
|
||||
)
|
||||
)
|
||||
|
||||
for tsk in old_ts_keys & new_ts_keys:
|
||||
old_ts_val = old_template_settings[tsk]
|
||||
new_default = desired_template_settings[tsk]["default"]
|
||||
new_order = desired_template_settings[tsk]["order"]
|
||||
if old_ts_val.default != new_default or old_ts_val.order != new_order:
|
||||
template_id, setting_id, suffix, step_id = tsk
|
||||
filter_data = {"template_id": template_id, "id": setting_id}
|
||||
if step_id is not None:
|
||||
filter_data["step_id"] = step_id
|
||||
new_default = desired_template_settings[tsk]
|
||||
if old_ts_val != new_default:
|
||||
template_id, setting_id, suffix, step_id, order = tsk
|
||||
filter_data = {"template_id": template_id, "setting_id": setting_id, "step_id": step_id}
|
||||
if suffix is not None:
|
||||
# Not all queries handle suffix well. If suffix is defined, add to filter:
|
||||
filter_data["suffix"] = suffix
|
||||
to_update.append(
|
||||
{"type": "template_setting", "filter": filter_data, "data": {"default": new_default, "suffix": suffix, "order": new_order}}
|
||||
{
|
||||
"type": "template_setting",
|
||||
"filter": filter_data,
|
||||
"data": {"default": new_default, "suffix": suffix},
|
||||
}
|
||||
)
|
||||
|
||||
for tsk in old_ts_keys - new_ts_keys:
|
||||
template_id, setting_id, suffix, step_id = tsk
|
||||
filter_data = {"template_id": template_id, "id": setting_id}
|
||||
if step_id is not None:
|
||||
filter_data["step_id"] = step_id
|
||||
template_id, setting_id, suffix, step_id, order = tsk
|
||||
filter_data = {"template_id": template_id, "setting_id": setting_id, "step_id": step_id}
|
||||
if suffix is not None:
|
||||
filter_data["suffix"] = suffix
|
||||
to_delete.append({"type": "template_setting", "filter": filter_data})
|
||||
|
|
@ -1092,11 +1100,17 @@ class Database:
|
|||
new_tc_keys = set(desired_template_configs.keys())
|
||||
|
||||
for tck in new_tc_keys - old_tc_keys:
|
||||
template_id, ctype, cname, step_id = tck
|
||||
template_id, ctype, cname, step_id, order = tck
|
||||
conf_data = desired_template_configs[tck]
|
||||
to_put.append(
|
||||
Template_custom_configs(
|
||||
template_id=template_id, type=ctype, name=cname, data=conf_data["data"], checksum=conf_data["checksum"], step_id=step_id
|
||||
template_id=template_id,
|
||||
type=ctype,
|
||||
name=cname,
|
||||
data=conf_data["data"],
|
||||
checksum=conf_data["checksum"],
|
||||
step_id=step_id,
|
||||
order=order,
|
||||
)
|
||||
)
|
||||
|
||||
|
|
@ -1104,19 +1118,19 @@ class Database:
|
|||
old_tc_obj = old_template_configs[tck]
|
||||
new_tc_obj = desired_template_configs[tck]
|
||||
if old_tc_obj.checksum != new_tc_obj["checksum"]:
|
||||
template_id, ctype, cname, step_id = tck
|
||||
filter_data = {"template_id": template_id, "name": cname, "type": ctype}
|
||||
if step_id is not None:
|
||||
filter_data["step_id"] = step_id
|
||||
template_id, ctype, cname, step_id, order = tck
|
||||
filter_data = {"template_id": template_id, "name": cname, "type": ctype, "step_id": step_id}
|
||||
to_update.append(
|
||||
{"type": "template_config", "filter": filter_data, "data": {"data": new_tc_obj["data"], "checksum": new_tc_obj["checksum"]}}
|
||||
{
|
||||
"type": "template_config",
|
||||
"filter": filter_data,
|
||||
"data": {"data": new_tc_obj["data"], "checksum": new_tc_obj["checksum"]},
|
||||
}
|
||||
)
|
||||
|
||||
for tck in old_tc_keys - new_tc_keys:
|
||||
template_id, ctype, cname, step_id = tck
|
||||
filter_data = {"template_id": template_id, "name": cname, "type": ctype}
|
||||
if step_id is not None:
|
||||
filter_data["step_id"] = step_id
|
||||
template_id, ctype, cname, step_id, order = tck
|
||||
filter_data = {"template_id": template_id, "name": cname, "type": ctype, "step_id": step_id}
|
||||
to_delete.append({"type": "template_config", "filter": filter_data})
|
||||
|
||||
# APPLY CHANGES
|
||||
|
|
@ -1178,6 +1192,7 @@ class Database:
|
|||
session.add_all(to_put)
|
||||
session.commit()
|
||||
except SQLAlchemyError as e:
|
||||
self.logger.debug(format_exc())
|
||||
session.rollback()
|
||||
return False, str(e)
|
||||
|
||||
|
|
@ -2723,6 +2738,8 @@ class Database:
|
|||
order = 0
|
||||
for setting, default in template.get("settings", {}).items():
|
||||
setting_id, suffix = setting.rsplit("_", 1) if self.suffix_rx.search(setting) else (setting, None)
|
||||
if suffix is not None:
|
||||
suffix = int(suffix)
|
||||
|
||||
if setting_id in self.RESTRICTED_TEMPLATE_SETTINGS:
|
||||
self.logger.error(
|
||||
|
|
@ -3004,6 +3021,8 @@ class Database:
|
|||
order = 0
|
||||
for setting, default in template_data.get("settings", {}).items():
|
||||
setting_id, suffix = setting.rsplit("_", 1) if self.suffix_rx.search(setting) else (setting, None)
|
||||
if suffix is not None:
|
||||
suffix = int(suffix)
|
||||
|
||||
if setting_id in self.RESTRICTED_TEMPLATE_SETTINGS:
|
||||
self.logger.error(
|
||||
|
|
|
|||
|
|
@ -62,11 +62,29 @@ def upgrade() -> None:
|
|||
if "id" in [c["name"] for c in batch_op.impl.dialect.get_columns(op.get_bind(), "bw_ui_users")]:
|
||||
batch_op.drop_column("id")
|
||||
|
||||
# Add the new order column to bw_template_settings
|
||||
op.add_column("bw_template_settings", sa.Column("order", sa.Integer(), nullable=False))
|
||||
# Add the new order column to bw_template_settings and set initial values
|
||||
op.add_column("bw_template_settings", sa.Column("order", sa.Integer(), nullable=False, server_default="0"))
|
||||
op.execute("SET @row_number = 0")
|
||||
op.execute(
|
||||
"""
|
||||
UPDATE bw_template_settings
|
||||
SET `order` = (@row_number:=@row_number + 1)
|
||||
ORDER BY template_id, setting_id
|
||||
"""
|
||||
)
|
||||
op.create_unique_constraint(None, "bw_template_settings", ["template_id", "setting_id", "order"])
|
||||
|
||||
# Add the new order column to bw_template_custom_configs
|
||||
op.add_column("bw_template_custom_configs", sa.Column("order", sa.Integer(), nullable=False))
|
||||
op.execute("SET @row_number = 0")
|
||||
op.execute(
|
||||
"""
|
||||
UPDATE bw_template_settings
|
||||
SET `order` = (@row_number:=@row_number + 1)
|
||||
ORDER BY template_id, setting_id
|
||||
"""
|
||||
)
|
||||
op.create_unique_constraint(None, "bw_template_custom_configs", ["template_id", "order"])
|
||||
|
||||
# Update version in bw_metadata
|
||||
op.execute("UPDATE bw_metadata SET version = '1.6.0-rc1' WHERE id = 1")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
"""Upgrade to version 1.6.0-rc2
|
||||
|
||||
Revision ID: cb5750a9d1f7
|
||||
Revises: 8a37fed772e9
|
||||
Create Date: 2025-01-15 16:06:07.679683
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "cb5750a9d1f7"
|
||||
down_revision: Union[str, None] = "8a37fed772e9"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.add_column("bw_selects", sa.Column("order", sa.Integer(), nullable=False))
|
||||
op.execute("SET @row_number = 0")
|
||||
op.execute(
|
||||
"""
|
||||
UPDATE bw_selects
|
||||
SET `order` = (@row_number:=@row_number + 1)
|
||||
ORDER BY setting_id
|
||||
"""
|
||||
)
|
||||
op.create_unique_constraint(None, "bw_selects", ["setting_id", "order"])
|
||||
|
||||
# Update version in bw_metadata
|
||||
op.execute("UPDATE bw_metadata SET version = '1.6.0-rc2' WHERE id = 1")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_constraint(None, "bw_selects", type_="unique")
|
||||
op.drop_column("bw_selects", "order")
|
||||
|
||||
# Revert the version in bw_metadata
|
||||
op.execute("UPDATE bw_metadata SET version = '1.6.0-rc1' WHERE id = 1")
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
"""Upgrade to version 1.6.0-rc2
|
||||
|
||||
Revision ID: 2f9f7600c78d
|
||||
Revises: 6307fa627563
|
||||
Create Date: 2025-01-15 16:18:37.077420
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "2f9f7600c78d"
|
||||
down_revision: Union[str, None] = "6307fa627563"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.add_column("bw_selects", sa.Column("order", sa.Integer(), nullable=False))
|
||||
op.execute("SET @row_number = 0")
|
||||
op.execute(
|
||||
"""
|
||||
UPDATE bw_selects
|
||||
SET `order` = (@row_number:=@row_number + 1)
|
||||
ORDER BY setting_id
|
||||
"""
|
||||
)
|
||||
op.create_unique_constraint(None, "bw_selects", ["setting_id", "order"])
|
||||
|
||||
# Update version in bw_metadata
|
||||
op.execute("UPDATE bw_metadata SET version = '1.6.0-rc2' WHERE id = 1")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_constraint(None, "bw_selects", type_="unique")
|
||||
op.drop_column("bw_selects", "order")
|
||||
|
||||
# Revert the version in bw_metadata
|
||||
op.execute("UPDATE bw_metadata SET version = '1.6.0-rc1' WHERE id = 1")
|
||||
|
|
@ -62,11 +62,29 @@ def upgrade() -> None:
|
|||
if "id" in [c["name"] for c in batch_op.impl.dialect.get_columns(op.get_bind(), "bw_ui_users")]:
|
||||
batch_op.drop_column("id")
|
||||
|
||||
# Add the new order column to bw_template_settings
|
||||
op.add_column("bw_template_settings", sa.Column("order", sa.Integer(), nullable=False))
|
||||
# Add the new order column to bw_template_settings and set initial values
|
||||
op.add_column("bw_template_settings", sa.Column("order", sa.Integer(), nullable=False, server_default="0"))
|
||||
op.execute("SET @row_number = 0")
|
||||
op.execute(
|
||||
"""
|
||||
UPDATE bw_template_settings
|
||||
SET `order` = (@row_number:=@row_number + 1)
|
||||
ORDER BY template_id, setting_id
|
||||
"""
|
||||
)
|
||||
op.create_unique_constraint(None, "bw_template_settings", ["template_id", "setting_id", "order"])
|
||||
|
||||
# Add the new order column to bw_template_custom_configs
|
||||
op.add_column("bw_template_custom_configs", sa.Column("order", sa.Integer(), nullable=False))
|
||||
op.execute("SET @row_number = 0")
|
||||
op.execute(
|
||||
"""
|
||||
UPDATE bw_template_settings
|
||||
SET `order` = (@row_number:=@row_number + 1)
|
||||
ORDER BY template_id, setting_id
|
||||
"""
|
||||
)
|
||||
op.create_unique_constraint(None, "bw_template_custom_configs", ["template_id", "order"])
|
||||
|
||||
# Update version in bw_metadata
|
||||
op.execute("UPDATE bw_metadata SET version = '1.6.0-rc1' WHERE id = 1")
|
||||
|
|
|
|||
|
|
@ -159,30 +159,56 @@ def upgrade() -> None:
|
|||
# Copy data to new column
|
||||
op.execute("UPDATE bw_instances SET status_new = status::text::instance_status_enum")
|
||||
# Drop old column
|
||||
batch_op.drop_column("status")
|
||||
op.drop_column("bw_instances", "status")
|
||||
# Rename new column to status
|
||||
batch_op.alter_column("status_new", new_column_name="status", nullable=False)
|
||||
op.alter_column("bw_instances", "status_new", new_column_name="status", nullable=False)
|
||||
|
||||
# Add the new order column to bw_template_settings
|
||||
# Step 1: Add column as nullable
|
||||
op.add_column("bw_template_settings", sa.Column("order", sa.Integer(), nullable=True))
|
||||
|
||||
# Step 2: Populate default values
|
||||
op.execute('UPDATE bw_template_settings SET "order" = 0')
|
||||
op.execute(
|
||||
"""
|
||||
UPDATE bw_template_settings
|
||||
SET "order" = subquery.row_number
|
||||
FROM (
|
||||
SELECT id, ROW_NUMBER() OVER (ORDER BY template_id, setting_id) as row_number
|
||||
FROM bw_template_settings
|
||||
) as subquery
|
||||
WHERE bw_template_settings.id = subquery.id
|
||||
"""
|
||||
)
|
||||
|
||||
# Step 3: Alter column to NOT NULL
|
||||
op.alter_column("bw_template_settings", "order", nullable=False)
|
||||
|
||||
# Step 4: Add unique constraint
|
||||
op.create_unique_constraint(None, "bw_template_settings", ["template_id", "setting_id", "order"])
|
||||
|
||||
# Add the new order column to bw_template_custom_configs
|
||||
# Step 1: Add column as nullable
|
||||
op.add_column("bw_template_custom_configs", sa.Column("order", sa.Integer(), nullable=True))
|
||||
|
||||
# Step 2: Populate default values
|
||||
op.execute('UPDATE bw_template_custom_configs SET "order" = 0')
|
||||
op.execute(
|
||||
"""
|
||||
UPDATE bw_template_custom_configs
|
||||
SET "order" = subquery.row_number
|
||||
FROM (
|
||||
SELECT id, ROW_NUMBER() OVER (ORDER BY template_id) as row_number
|
||||
FROM bw_template_custom_configs
|
||||
) as subquery
|
||||
WHERE bw_template_custom_configs.id = subquery.id
|
||||
"""
|
||||
)
|
||||
|
||||
# Step 3: Alter column to NOT NULL
|
||||
op.alter_column("bw_template_custom_configs", "order", nullable=False)
|
||||
|
||||
# Step 4: Add unique constraint
|
||||
op.create_unique_constraint(None, "bw_template_custom_configs", ["template_id", "order"])
|
||||
|
||||
# First drop Identity properties
|
||||
op.execute(
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
"""Upgrade to version 1.6.0-rc2
|
||||
|
||||
Revision ID: b56eb8d8dbf2
|
||||
Revises: 940350925f36
|
||||
Create Date: 2025-01-15 16:26:12.567104
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "b56eb8d8dbf2"
|
||||
down_revision: Union[str, None] = "940350925f36"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# Add the new order column to bw_selects
|
||||
# Step 1: Add column as nullable
|
||||
op.add_column("bw_selects", sa.Column("order", sa.Integer(), nullable=True))
|
||||
|
||||
# Step 2: Populate default values
|
||||
op.execute(
|
||||
"""
|
||||
UPDATE bw_selects
|
||||
SET "order" = subquery.row_number
|
||||
FROM (
|
||||
SELECT value, ROW_NUMBER() OVER (ORDER BY setting_id) as row_number
|
||||
FROM bw_selects
|
||||
) as subquery
|
||||
WHERE bw_selects.value = subquery.value
|
||||
"""
|
||||
)
|
||||
|
||||
# Step 3: Alter column to NOT NULL
|
||||
op.alter_column("bw_selects", "order", nullable=False)
|
||||
|
||||
# Step 4: Add unique constraint
|
||||
op.create_unique_constraint(None, "bw_selects", ["setting_id", "order"])
|
||||
|
||||
# Check if status_new exists before renaming
|
||||
conn = op.get_bind()
|
||||
inspector = sa.inspect(conn)
|
||||
if "status_new" in [col["name"] for col in inspector.get_columns("bw_instances")]:
|
||||
op.alter_column("bw_instances", "status_new", new_column_name="status")
|
||||
|
||||
# Update version in bw_metadata
|
||||
op.execute("UPDATE bw_metadata SET version = '1.6.0-rc2' WHERE id = 1")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.drop_constraint(None, "bw_selects", type_="unique")
|
||||
op.drop_column("bw_selects", "order")
|
||||
|
||||
# Revert the version in bw_metadata
|
||||
op.execute("UPDATE bw_metadata SET version = '1.6.0-rc1' WHERE id = 1")
|
||||
|
|
@ -176,21 +176,73 @@ def upgrade() -> None:
|
|||
op.drop_table("bw_instances")
|
||||
op.rename_table("bw_instances_new", "bw_instances")
|
||||
|
||||
# Step 1: Add 'order' column as nullable with a default
|
||||
with op.batch_alter_table("bw_template_settings") as batch_op:
|
||||
batch_op.add_column(sa.Column("order", sa.Integer(), nullable=False, server_default="0"))
|
||||
with op.batch_alter_table("bw_template_custom_configs") as batch_op:
|
||||
batch_op.add_column(sa.Column("order", sa.Integer(), nullable=False, server_default="0"))
|
||||
# Create new tables with order column and constraints
|
||||
op.create_table(
|
||||
"bw_template_settings_new",
|
||||
sa.Column("id", sa.Integer, sa.Identity(start=1, increment=1), primary_key=True),
|
||||
sa.Column("template_id", sa.String(256), nullable=False),
|
||||
sa.Column("setting_id", sa.String(256), nullable=False),
|
||||
sa.Column("step_id", sa.Integer, nullable=False),
|
||||
sa.Column("default", sa.TEXT, nullable=False),
|
||||
sa.Column("suffix", sa.Integer, nullable=True, default=0),
|
||||
sa.Column("order", sa.Integer, nullable=False, default=0),
|
||||
sa.UniqueConstraint("template_id", "setting_id", "step_id", "suffix"),
|
||||
sa.UniqueConstraint("template_id", "setting_id", "order"),
|
||||
sa.ForeignKeyConstraint(["template_id"], ["bw_templates.id"], onupdate="CASCADE", ondelete="CASCADE"),
|
||||
sa.ForeignKeyConstraint(["setting_id"], ["bw_settings.id"], onupdate="CASCADE", ondelete="CASCADE"),
|
||||
)
|
||||
|
||||
# Step 2: Set default value for existing rows
|
||||
op.execute("UPDATE bw_template_settings SET `order` = 0")
|
||||
op.execute("UPDATE bw_template_custom_configs SET `order` = 0")
|
||||
op.create_table(
|
||||
"bw_template_custom_configs_new",
|
||||
sa.Column("id", sa.Integer, sa.Identity(start=1, increment=1), primary_key=True),
|
||||
sa.Column("template_id", sa.String(256), nullable=False),
|
||||
sa.Column("step_id", sa.Integer, nullable=False),
|
||||
sa.Column(
|
||||
"type",
|
||||
sa.Enum(
|
||||
"http",
|
||||
"stream",
|
||||
"server_http",
|
||||
"server_stream",
|
||||
"default_server_http",
|
||||
"default_server_stream",
|
||||
"modsec",
|
||||
"modsec_crs",
|
||||
"crs_plugins_before",
|
||||
"crs_plugins_after",
|
||||
name="custom_configs_types_enum",
|
||||
),
|
||||
nullable=False,
|
||||
),
|
||||
sa.Column("name", sa.String(256), nullable=False),
|
||||
sa.Column("data", sa.LargeBinary(length=(2**32) - 1), nullable=False),
|
||||
sa.Column("checksum", sa.String(128), nullable=False),
|
||||
sa.Column("order", sa.Integer, nullable=False, default=0),
|
||||
sa.UniqueConstraint("template_id", "step_id", "type", "name"),
|
||||
sa.UniqueConstraint("template_id", "order"),
|
||||
sa.ForeignKeyConstraint(["template_id"], ["bw_templates.id"], onupdate="CASCADE", ondelete="CASCADE"),
|
||||
)
|
||||
|
||||
# Step 3: Alter 'order' column to NOT NULL
|
||||
with op.batch_alter_table("bw_template_settings") as batch_op:
|
||||
batch_op.alter_column("order", nullable=False)
|
||||
with op.batch_alter_table("bw_template_custom_configs") as batch_op:
|
||||
batch_op.alter_column("order", nullable=False)
|
||||
# Copy data to new tables with default order=0
|
||||
op.execute(
|
||||
"""
|
||||
INSERT INTO bw_template_settings_new (template_id, setting_id, step_id, "default", suffix, "order")
|
||||
SELECT template_id, setting_id, step_id, "default", suffix, 0 FROM bw_template_settings
|
||||
"""
|
||||
)
|
||||
|
||||
op.execute(
|
||||
"""
|
||||
INSERT INTO bw_template_custom_configs_new (template_id, step_id, type, name, data, checksum, "order")
|
||||
SELECT template_id, step_id, type, name, data, checksum, 0 FROM bw_template_custom_configs
|
||||
"""
|
||||
)
|
||||
|
||||
# Drop old tables and rename new ones
|
||||
op.drop_table("bw_template_settings")
|
||||
op.drop_table("bw_template_custom_configs")
|
||||
op.rename_table("bw_template_settings_new", "bw_template_settings")
|
||||
op.rename_table("bw_template_custom_configs_new", "bw_template_custom_configs")
|
||||
|
||||
# Re-enable foreign keys
|
||||
op.execute("PRAGMA foreign_keys=ON;")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
"""Upgrade to version 1.6.0-rc2
|
||||
|
||||
Revision ID: 92038d1e365e
|
||||
Revises: 5b0ea031ccfc
|
||||
Create Date: 2025-01-15 15:55:16.757661
|
||||
|
||||
"""
|
||||
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "92038d1e365e"
|
||||
down_revision: Union[str, None] = "5b0ea031ccfc"
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
with op.batch_alter_table("bw_selects") as batch_op:
|
||||
batch_op.add_column(sa.Column("order", sa.Integer(), nullable=False, server_default="0"))
|
||||
# Assign unique order values within each setting_id group
|
||||
op.execute(
|
||||
"""
|
||||
UPDATE bw_selects SET "order" = (
|
||||
SELECT COUNT(*) - 1
|
||||
FROM bw_selects s2
|
||||
WHERE s2.setting_id = bw_selects.setting_id
|
||||
AND s2.rowid <= bw_selects.rowid
|
||||
)
|
||||
"""
|
||||
)
|
||||
with op.batch_alter_table("bw_selects") as batch_op:
|
||||
batch_op.create_unique_constraint("uq_setting_order", ["setting_id", "order"])
|
||||
|
||||
# Update the version in bw_metadata
|
||||
op.execute("UPDATE bw_metadata SET version = '1.6.0-rc2' WHERE id = 1")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
with op.batch_alter_table("bw_selects") as batch_op:
|
||||
batch_op.drop_constraint("uq_setting_order", type_="unique")
|
||||
batch_op.drop_column("order")
|
||||
# Revert the version in bw_metadata
|
||||
op.execute("UPDATE bw_metadata SET version = '1.6.0-rc1' WHERE id = 1")
|
||||
|
|
@ -87,6 +87,7 @@ class Settings(Base):
|
|||
|
||||
class Selects(Base):
|
||||
__tablename__ = "bw_selects"
|
||||
__table_args__ = (UniqueConstraint("setting_id", "order"),)
|
||||
|
||||
setting_id = Column(String(256), ForeignKey("bw_settings.id", onupdate="cascade", ondelete="cascade"), primary_key=True)
|
||||
value = Column(String(256), primary_key=True)
|
||||
|
|
|
|||
Loading…
Reference in a new issue