96 lines
3.6 KiB
Python
96 lines
3.6 KiB
Python
"""Merge the second audit-retention setting into the one that is actually read.
|
|
|
|
Two keys existed for one setting. shopdb/core/services/auditretention.py reads
|
|
`audit_retentiondays` (seeded under category 'site', default 0). A second key
|
|
`audit_retention_days` was seeded under category 'audit' with a default of 90,
|
|
and the Audit & Logging settings page wrote to that one - so an administrator
|
|
set a retention period, reloaded, saw it persisted, and nothing ever consulted
|
|
it. Retention stayed off while the page said otherwise.
|
|
|
|
The page now writes the key that is read, and the duplicate is out of the seed
|
|
list. This handles the sites that already have it: if an operator set a real
|
|
value on the dead key and never set the live one, that intent is carried over
|
|
rather than dropped. Their intent was "keep 30 days", and the fix should not
|
|
silently discard it.
|
|
|
|
Not carried over when the live key already holds a non-default value - that one
|
|
was set through the page that worked, and it wins.
|
|
|
|
The dead key is then deleted. Leaving it would preserve the ambiguity that
|
|
caused this, and nothing reads it.
|
|
|
|
Revision ID: 7d39_audit_retention_key_merge
|
|
Revises: 7d38_widen_importbatch_status
|
|
"""
|
|
from alembic import op
|
|
|
|
import sqlalchemy as sa
|
|
|
|
|
|
revision = '7d39_audit_retention_key_merge'
|
|
down_revision = '7d38_widen_importbatch_status'
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
DEAD = 'audit_retention_days'
|
|
LIVE = 'audit_retentiondays'
|
|
|
|
|
|
def _value(bind, key):
|
|
return bind.execute(
|
|
sa.text('SELECT value FROM settings WHERE `key` = :key'
|
|
if bind.dialect.name == 'mysql'
|
|
else 'SELECT value FROM settings WHERE "key" = :key'),
|
|
{'key': key}).scalar()
|
|
|
|
|
|
def upgrade():
|
|
bind = op.get_bind()
|
|
if not sa.inspect(bind).has_table('settings'):
|
|
return
|
|
|
|
dead = _value(bind, DEAD)
|
|
if dead is None:
|
|
return
|
|
|
|
live = _value(bind, LIVE)
|
|
# '90' was the dead key's seeded default, so it is not evidence of intent.
|
|
operator_set_dead = dead not in (None, '', '90')
|
|
live_is_default = live in (None, '', '0')
|
|
|
|
if operator_set_dead and live_is_default:
|
|
if live is None:
|
|
bind.execute(sa.text(
|
|
'INSERT INTO settings (`key`, value, valuetype, category, '
|
|
'description, createddate, modifieddate, isactive) VALUES '
|
|
'(:key, :value, :valuetype, :category, :description, '
|
|
'NOW(), NOW(), 1)'
|
|
if bind.dialect.name == 'mysql' else
|
|
'INSERT INTO settings ("key", value, valuetype, category, '
|
|
'description, createddate, modifieddate, isactive) VALUES '
|
|
'(:key, :value, :valuetype, :category, :description, '
|
|
"datetime('now'), datetime('now'), 1)"),
|
|
{'key': LIVE, 'value': dead, 'valuetype': 'integer',
|
|
'category': 'site',
|
|
'description': 'Delete audit log entries older than this many '
|
|
'days. 0 keeps everything forever.'})
|
|
else:
|
|
bind.execute(sa.text(
|
|
'UPDATE settings SET value = :value WHERE `key` = :key'
|
|
if bind.dialect.name == 'mysql' else
|
|
'UPDATE settings SET value = :value WHERE "key" = :key'),
|
|
{'value': dead, 'key': LIVE})
|
|
|
|
bind.execute(sa.text(
|
|
'DELETE FROM settings WHERE `key` = :key'
|
|
if bind.dialect.name == 'mysql' else
|
|
'DELETE FROM settings WHERE "key" = :key'), {'key': DEAD})
|
|
|
|
|
|
def downgrade():
|
|
"""Deliberately a no-op.
|
|
|
|
Re-creating a key that nothing reads, to sit beside the one that works,
|
|
would restore the defect. The live setting keeps whatever value it holds.
|
|
"""
|