Skip to content

Commit

Permalink
تحديث هيكلة البيانات وبرمجة أجزاء من وظيفة الاستعادة في نموذج قواعد ا…
Browse files Browse the repository at this point in the history
…لبيانات
  • Loading branch information
vzool committed Oct 15, 2024
1 parent 28ecdfc commit 160ea6b
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 24 deletions.
Binary file modified analysis/database/zakat-pony.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified analysis/database/zakat.pdf
Binary file not shown.
Binary file modified analysis/database/zakat.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion analysis/database/zakat.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
177 changes: 154 additions & 23 deletions zakat/zakat_tracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ def load(self, path: str = None) -> bool:
"""

@abstractmethod
def recall(self, dry=True, debug=False) -> bool:
def recall(self, dry: bool = True, debug: bool = False) -> bool:
"""
Revert the last operation.
Expand Down Expand Up @@ -1917,10 +1917,8 @@ def daily_logs(self, weekday: WeekDay = WeekDay.Friday, debug: bool = False):
print('y', y)
return y

def recall(self, dry=True, debug=False) -> bool:
if not self.nolock() or len(self._vault['history']) == 0:
return False
if len(self._vault['history']) <= 0:
def recall(self, dry: bool = True, debug: bool = False) -> bool:
if not self.nolock() or len(self._vault['history']) <= 0:
return False
ref = sorted(self._vault['history'].keys())[-1]
if debug:
Expand Down Expand Up @@ -1966,7 +1964,7 @@ def recall(self, dry=True, debug=False) -> bool:
self._vault['account'][x['account']]['count'] -= 1
sub_positive_log_negative = 0
box_ref = self._vault['account'][x['account']]['log'][x['ref']]['ref']
if not box_ref is None:
if box_ref is not None:
assert self.box_exists(x['account'], box_ref)
box_value = self._vault['account'][x['account']]['log'][x['ref']]['value']
assert box_value < 0
Expand Down Expand Up @@ -2611,7 +2609,7 @@ class Account(db.Entity):
class Box(db.Entity):
_table_ = 'box'
id = pony.PrimaryKey(int, auto=True)
account_id = pony.Required(Account)
account = pony.Required(Account, column='account_id')
time = pony.Required(int, size=64, unique=True)
record_date = pony.Required(datetime.datetime)
capital = pony.Required(int, size=64)
Expand All @@ -2626,7 +2624,7 @@ class Box(db.Entity):
class Log(db.Entity):
_table_ = 'log'
id = pony.PrimaryKey(int, auto=True)
account_id = pony.Required(Account)
account = pony.Required(Account, column='account_id')
time = pony.Required(int, size=64, unique=True)
record_date = pony.Required(datetime.datetime)
value = pony.Required(int, size=64)
Expand All @@ -2639,7 +2637,7 @@ class Log(db.Entity):
class File(db.Entity):
_table_ = 'file'
id = pony.PrimaryKey(int, auto=True)
log_id = pony.Required(Log)
log = pony.Required(Log, column='log_id')
time = pony.Required(int, size=64, unique=True)
record_date = pony.Required(datetime.datetime)
path = pony.Required(pony.LongStr)
Expand All @@ -2651,7 +2649,7 @@ class File(db.Entity):
class Exchange(db.Entity):
_table_ = 'exchange'
id = pony.PrimaryKey(int, auto=True)
account_id = pony.Required(Account)
account = pony.Required(Account, column='account_id')
time = pony.Required(int, size=64, unique=True)
rate = pony.Required(Decimal)
desc = pony.Required(pony.LongStr)
Expand All @@ -2678,14 +2676,14 @@ class History(db.Entity):
_table_ = 'history'
id = pony.PrimaryKey(int, auto=True)
lock = pony.Required(int, size=64)
action_id = pony.Required(Action)
account_id = pony.Required(Account)
action = pony.Required(Action, column='action_id')
account = pony.Required(Account, column='account_id')
ref = pony.Optional(int, size=64)
file = pony.Optional(int, size=64)
key = pony.Optional(str)
value = pony.Optional(str)
value_type = pony.Optional(str)
math_id = pony.Optional(Math)
math = pony.Optional(Math, column='math_id')
created_at = pony.Required(datetime.datetime, default=lambda: datetime.datetime.now())


Expand Down Expand Up @@ -2873,7 +2871,7 @@ def track(self, unscaled_value: float | int | Decimal = 0, desc: str = '', accou
if self.box_exists(account, created):
raise ValueError(f"The box transaction happened again in the same nanosecond time({created}).")
Box(
account_id=account,
account=account,
time=created,
record_date=datetime.datetime.now(),
capital=value,
Expand All @@ -2896,7 +2894,7 @@ def add_file(self, account: int, ref: int, path: str) -> int:
if log:
file_ref = Helper.time()
File(
log_id=log.id,
log=log.id,
time=file_ref,
record_date=datetime.datetime.now(),
path=path,
Expand Down Expand Up @@ -3087,8 +3085,141 @@ def load(self, path: str = None) -> bool:
return True
return False

def recall(self, dry=True, debug=False) -> bool:
pass
@pony.db_session()
def recall(self, dry: bool = True, debug: bool = False) -> bool:
# return False
if not self.nolock() or pony.count(History.select()) <= 0:
return False
memory = History.select(
lambda h: h.lock == pony.max(hh.lock for hh in History)
).order_by(pony.desc(History.id))[:]
if debug:
print('memories', type(memory), memory)
sub_positive_log_negative = 0
for x in memory:
if debug:
print('memory', type(x), x.to_dict())
account = Account.get(id=x.account.id)
if debug:
print(account)
match x.action.id:
case ActionEnum.CREATE.value:
assert pony.count(Box.select(lambda b: b.account.id == x.account.id)) == 0
assert account.balance == 0
assert account.count == 0
if dry:
continue
account.delete()

case ActionEnum.TRACK.value:
if dry:
continue
account.balance -= int(x.value)
account.count -= 1
Box.get(time=x.ref).delete()

case ActionEnum.LOG.value:
if dry:
continue
if sub_positive_log_negative == -int(x.value):
account.count -= 1
sub_positive_log_negative = 0
log = Log.get(time=x.ref)
if log.ref:
box = Box.get(time=x.ref)
print('box', box)
assert box
assert box.value < 0

try:
box.rest += -box.value
except TypeError:
box.rest += Decimal(-box.value)

try:
account.balance += -box.value
except TypeError:
account.balance += Decimal(-box.value)

account.count -= 1
log.delete()

case ActionEnum.SUB.value:
box = Box.get(time=x.ref)
if box:
if dry:
continue
box.rest += int(x.value)
account.balance += int(x.value)
sub_positive_log_negative = int(x.value)

case ActionEnum.ADD_FILE.value:
file = File.get(time=x.file)
if file:
if dry:
continue
file.delete()

case ActionEnum.REMOVE_FILE.value:
log = Log.get(time=x.ref)
File(
log=log.id,
time=x.ref,
record_date=Helper.time_to_datetime(x.file),
path=x.value,
)

# case ActionEnum.BOX_TRANSFER.value:
# if x['account'] is not None:
# if self.account_exists(x['account']):
# if x['ref'] in self._vault['account'][x['account']]['box']:
# if dry:
# continue
# self._vault['account'][x['account']]['box'][x['ref']]['rest'] -= x['value']
#
# case ActionEnum.EXCHANGE.value:
# if x['account'] is not None:
# if self.account_exists(x['account']):
# if x['ref'] in self._vault['account'][x['account']]['exchange']:
# if dry:
# continue
# del self._vault['account'][x['account']]['exchange'][x['ref']]
#
# case ActionEnum.REPORT.value:
# if x['ref'] in self._vault['report']:
# if dry:
# continue
# del self._vault['report'][x['ref']]
#
# case ActionEnum.ZAKAT.value:
# if x['account'] is not None:
# if self.account_exists(x['account']):
# if x['ref'] in self._vault['account'][x['account']]['box']:
# if x['key'] in self._vault['account'][x['account']]['box'][x['ref']]:
# if dry:
# continue
# match x['math']:
# case MathOperationEnum.ADDITION:
# self._vault['account'][x['account']]['box'][x['ref']][x['key']] -= x[
# 'value']
# case MathOperationEnum.EQUAL:
# self._vault['account'][x['account']]['box'][x['ref']][x['key']] = x['value']
# case MathOperationEnum.SUBTRACTION:
# self._vault['account'][x['account']]['box'][x['ref']][x['key']] += x[
# 'value']
#
# case ActionEnum.NAME_ACCOUNT.value:
# if x['account'] is not None:
# if self.account_exists(x['account']):
# if dry:
# continue
# match x['math']:
# case MathOperationEnum.EQUAL:
# self._vault['account'][x['account']][x['key']] = x['value']
#
if not dry:
self.clean_history(memory[0].lock)
return True

def reset(self) -> None:
db.drop_all_tables(with_all_data=True)
Expand Down Expand Up @@ -3213,7 +3344,7 @@ def log(self, value: float, desc: str = '', account_id: int = 1, created: int =
if debug:
print('created-log', created)
Log(
account_id=account_id,
account=account_id,
time=created,
record_date=datetime.datetime.now(),
value=value,
Expand All @@ -3238,15 +3369,15 @@ def step(self, action: ActionEnum = None, account_id: int = None, ref: int = Non
raise ValueError(f'lock({lock}) is empty')
with pony.db_session:
History(
action_id=action.value,
account_id=account_id,
action=action.value,
account=account_id,
lock=lock,
ref=ref,
file=file,
key=key if key else '',
value=str(value) if value else '',
value_type=value.__class__.__name__ if value else '',
math_id=math_operation.value if math_operation else None,
math=math_operation.value if math_operation else None,
)
return lock

Expand All @@ -3255,9 +3386,9 @@ def ref_exists(self, account_id: int, ref_type: str, ref: int) -> bool:
raise ValueError(f'The account_id must be an integer, {type(account_id)} was provided.')
match ref_type:
case 'box':
return Box.exists(account_id=account_id, time=ref)
return Box.exists(account=account_id, time=ref)
case 'log':
return Log.exists(account_id=account_id, time=ref)
return Log.exists(account=account_id, time=ref)
return False

@pony.db_session()
Expand Down

0 comments on commit 160ea6b

Please sign in to comment.