-
-
Save elliotchance/b13f765700fc5f40acaabfd23d1f42b1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Transaction: | |
def __init__(self, table, xid): | |
self.table = table | |
self.xid = xid | |
self.rollback_actions = [] | |
def add_record(self, id, name): | |
record = { | |
'id': id, | |
'name': name, | |
'created_xid': self.xid, | |
'expired_xid': 0 | |
} | |
self.rollback_actions.append(["delete", len(self.table.records)]) | |
self.table.records.append(record) | |
def delete_record(self, id): | |
for i, record in enumerate(self.table.records): | |
if self.record_is_visible(record) and record['id'] == id: | |
if self.record_is_locked(record): | |
raise RollbackException("Row locked by another transaction.") | |
else: | |
record['expired_xid'] = self.xid | |
self.rollback_actions.append(["add", i]) | |
def update_record(self, id, name): | |
self.delete_record(id) | |
self.add_record(id, name) | |
def fetch_record(self, id): | |
for record in self.table.records: | |
if self.record_is_visible(record) and record['id'] is id: | |
return record | |
return None | |
def count_records(self, min_id, max_id): | |
count = 0 | |
for record in self.table.records: | |
if self.record_is_visible(record) and \ | |
min_id <= record['id'] <= max_id: | |
count += 1 | |
return count | |
def fetch_all_records(self): | |
visible_records = [] | |
for record in self.table.records: | |
if self.record_is_visible(record): | |
visible_records.append(record) | |
return visible_records | |
def fetch(self, expr): | |
visible_records = [] | |
for record in self.table.records: | |
if self.record_is_visible(record) and expr(record): | |
visible_records.append(record) | |
return visible_records | |
def commit(self): | |
self.table.active_xids.discard(self.xid) | |
def rollback(self): | |
for action in reversed(self.rollback_actions): | |
if action[0] == 'add': | |
self.table.records[action[1]]['expired_xid'] = 0 | |
elif action[0] == 'delete': | |
self.table.records[action[1]]['expired_xid'] = self.xid | |
self.table.active_xids.discard(self.xid) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment