Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make it possible to get the state of the Rules table at a point in time #977

Merged
merged 14 commits into from Aug 12, 2019
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
29 changes: 29 additions & 0 deletions auslib/db.py
Expand Up @@ -14,6 +14,7 @@

from sqlalchemy.interfaces import PoolListener
from sqlalchemy.sql.expression import null
from sqlalchemy.sql.functions import max as sql_max

import migrate.versioning.api
import migrate.versioning.schema
Expand Down Expand Up @@ -760,6 +761,34 @@ def __init__(self, db, dialect, metadata, baseTable):
self.table.append_column(newcol)
AUSTable.__init__(self, db, dialect, historyClass=None, versioned=False)

def getPointInTime(self, timestamp, transaction=None):
# The inner query here gets one change id for every unique object in
# the base table. Filtering by timestamp < provided timestamp means
# we won't get any results most recent than the requested timestamp.
# Grouping by the primary key and selecting the max change_id means
# we'll get the most recent change_id (after applying the timestamp
# filter) for every unique object.
# The outer query simply retrieves the actual row data for each
# change_id that the inner query found
q = select(self.table.get_children()).where(
self.change_id.in_(select([sql_max(self.change_id)]).where(self.timestamp <= timestamp).group_by(*self.base_primary_key))
)
bhearsum marked this conversation as resolved.
Show resolved Hide resolved
if transaction:
result = transaction.execute(q).fetchall()
else:
with AUSTransaction(self.getEngine()) as trans:
result = trans.execute(q).fetchall()

rows = []
# Filter out any rows who have no non-primary key data, because this
# means the row has been deleted.
non_primary_key_columns = [col.name for col in self.baseTable.t.get_children() if not col.primary_key]
for row in result:
if any([row[col] for col in non_primary_key_columns]):
rows.append(row)

return rows_to_dicts(rows)

def forInsert(self, insertedKeys, columns, changed_by, trans):
"""Inserts cause two rows in the History table to be created. The first
one records the primary key data and NULLs for other row data. This
Expand Down
168 changes: 168 additions & 0 deletions auslib/test/admin/views/base.py
Expand Up @@ -197,8 +197,39 @@ def my_userinfo(*args, **kwargs):
update_type="minor",
product="a",
channel="a",
data_version=2,
)
dbo.rules.history.t.insert().execute(change_id=1, timestamp=50, changed_by="bill", rule_id=1)
dbo.rules.history.t.insert().execute(
change_id=2,
timestamp=51,
changed_by="bill",
rule_id=1,
priority=100,
version="3.5",
buildTarget="d",
backgroundRate=50,
mapping="c",
update_type="minor",
product="a",
channel="a",
data_version=1,
)
dbo.rules.history.t.insert().execute(
change_id=3,
timestamp=65,
changed_by="bill",
rule_id=1,
priority=100,
version="3.5",
buildTarget="d",
backgroundRate=100,
mapping="c",
update_type="minor",
product="a",
channel="a",
data_version=2,
)
dbo.rules.t.insert().execute(
rule_id=2,
alias="frodo",
Expand All @@ -212,6 +243,23 @@ def my_userinfo(*args, **kwargs):
channel="a",
data_version=1,
)
dbo.rules.history.t.insert().execute(change_id=4, timestamp=60, changed_by="bill", rule_id=2)
dbo.rules.history.t.insert().execute(
change_id=5,
timestamp=60,
bhearsum marked this conversation as resolved.
Show resolved Hide resolved
changed_by="bill",
rule_id=2,
alias="frodo",
priority=100,
version="3.3",
buildTarget="d",
backgroundRate=100,
mapping="b",
update_type="minor",
product="a",
channel="a",
data_version=1,
)
dbo.rules.t.insert().execute(
rule_id=3,
product="a",
Expand All @@ -222,22 +270,142 @@ def my_userinfo(*args, **kwargs):
mapping="a",
update_type="minor",
channel="a",
data_version=2,
)
dbo.rules.history.t.insert().execute(change_id=6, timestamp=72, changed_by="bill", rule_id=3)
dbo.rules.history.t.insert().execute(
change_id=7,
timestamp=73,
changed_by="bill",
rule_id=3,
product="a",
priority=50,
version="3.5",
buildTarget="a",
backgroundRate=100,
mapping="a",
update_type="minor",
channel="a",
data_version=1,
)
dbo.rules.history.t.insert().execute(
change_id=8,
timestamp=105,
changed_by="bill",
rule_id=3,
product="a",
priority=100,
version="3.5",
buildTarget="a",
backgroundRate=100,
mapping="a",
update_type="minor",
channel="a",
data_version=2,
)
dbo.rules.t.insert().execute(
rule_id=4, product="fake", priority=80, buildTarget="d", backgroundRate=100, mapping="a", update_type="minor", channel="a", data_version=1
)
dbo.rules.history.t.insert().execute(change_id=9, timestamp=80, changed_by="bill", rule_id=4)
dbo.rules.history.t.insert().execute(
change_id=10,
timestamp=81,
changed_by="bill",
rule_id=4,
product="fake",
priority=80,
buildTarget="d",
backgroundRate=100,
mapping="a",
update_type="minor",
channel="a",
data_version=1,
)
dbo.rules.t.insert().execute(
rule_id=5, priority=80, buildTarget="d", version="3.3", backgroundRate=0, mapping="c", update_type="minor", product="a", channel="a", data_version=1
)
dbo.rules.history.t.insert().execute(change_id=11, timestamp=90, changed_by="bill", rule_id=5)
dbo.rules.history.t.insert().execute(
change_id=12,
timestamp=91,
changed_by="bill",
rule_id=5,
priority=80,
buildTarget="d",
version="3.3",
backgroundRate=0,
mapping="c",
update_type="minor",
product="a",
channel="a",
data_version=1,
)
dbo.rules.t.insert().execute(rule_id=6, product="fake", priority=40, backgroundRate=50, mapping="a", update_type="minor", channel="e", data_version=1)
dbo.rules.history.t.insert().execute(change_id=13, timestamp=110, changed_by="bill", rule_id=6)
dbo.rules.history.t.insert().execute(
change_id=14,
timestamp=111,
changed_by="bill",
rule_id=6,
product="fake",
priority=40,
backgroundRate=50,
mapping="a",
update_type="minor",
channel="e",
data_version=1,
)
dbo.rules.t.insert().execute(rule_id=7, product="fake", priority=30, backgroundRate=85, mapping="a", update_type="minor", channel="c", data_version=1)
dbo.rules.history.t.insert().execute(change_id=15, timestamp=115, changed_by="bill", rule_id=7)
dbo.rules.history.t.insert().execute(
change_id=16,
timestamp=116,
changed_by="bill",
rule_id=7,
product="fake",
priority=30,
backgroundRate=85,
mapping="a",
update_type="minor",
channel="c",
data_version=1,
)
dbo.rules.t.insert().execute(
rule_id=8, product="fake2", priority=25, backgroundRate=100, mapping="a", update_type="minor", channel="c", mig64=True, data_version=1
)
dbo.rules.history.t.insert().execute(change_id=17, timestamp=150, changed_by="bill", rule_id=8)
dbo.rules.history.t.insert().execute(
change_id=18,
timestamp=151,
changed_by="bill",
rule_id=8,
product="fake2",
priority=25,
backgroundRate=100,
mapping="a",
update_type="minor",
channel="c",
mig64=True,
data_version=1,
)
dbo.rules.t.insert().execute(
rule_id=9, product="fake3", priority=25, backgroundRate=100, mapping="a", update_type="minor", channel="c", jaws=True, data_version=1
)
dbo.rules.history.t.insert().execute(change_id=19, timestamp=160, changed_by="bill", rule_id=9)
dbo.rules.history.t.insert().execute(
change_id=20,
timestamp=161,
changed_by="bill",
rule_id=9,
product="fake3",
priority=25,
backgroundRate=100,
mapping="a",
update_type="minor",
channel="c",
jaws=True,
data_version=1,
)
self.client = app.test_client()

def tearDown(self):
Expand Down