MetiMiester commited on
Commit
8a1e549
·
verified ·
1 Parent(s): aa9e4d5

Update src/utils/sqlite_retry.py

Browse files
Files changed (1) hide show
  1. src/utils/sqlite_retry.py +67 -33
src/utils/sqlite_retry.py CHANGED
@@ -1,33 +1,67 @@
1
- import sqlite3
2
- import time
3
- from typing import Callable, TypeVar
4
-
5
- T = TypeVar("T")
6
-
7
-
8
- def run_tx(
9
- conn: sqlite3.Connection,
10
- fn: Callable[[sqlite3.Connection], T],
11
- retries: int = 5,
12
- delay: float = 0.2,
13
- ) -> T:
14
- """
15
- Runs a SQLite transaction with retry logic.
16
- Handles 'database is locked' errors safely.
17
- """
18
- last_exc = None
19
-
20
- for attempt in range(retries):
21
- try:
22
- result = fn(conn)
23
- conn.commit()
24
- return result
25
- except sqlite3.OperationalError as e:
26
- conn.rollback()
27
- last_exc = e
28
- if "locked" in str(e).lower():
29
- time.sleep(delay * (attempt + 1))
30
- continue
31
- raise
32
-
33
- raise last_exc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import datetime, timedelta
2
+ import pytz
3
+
4
+ # Hotel timezone
5
+ OMAN_TZ = pytz.timezone("Asia/Muscat")
6
+
7
+
8
+ # -------------------------------------------------
9
+ # Core time helpers
10
+ # -------------------------------------------------
11
+
12
+ def utc_now_iso() -> str:
13
+ """
14
+ Returns current UTC time in ISO-8601 format.
15
+ Used for all audit-safe timestamps.
16
+ """
17
+ return datetime.utcnow().replace(microsecond=0).isoformat() + "Z"
18
+
19
+
20
+ def muscat_now() -> datetime:
21
+ """
22
+ Returns current time in Asia/Muscat timezone.
23
+ """
24
+ return datetime.now(OMAN_TZ)
25
+
26
+
27
+ # Backward-compatible alias
28
+ local_now = muscat_now
29
+
30
+
31
+ def local_date_str() -> str:
32
+ """
33
+ Returns local date (Asia/Muscat) as YYYY-MM-DD.
34
+ """
35
+ return muscat_now().strftime("%Y-%m-%d")
36
+
37
+
38
+ # -------------------------------------------------
39
+ # Business day & closing logic
40
+ # -------------------------------------------------
41
+
42
+ def business_day_for_close(now: datetime | None = None) -> str:
43
+ """
44
+ Business day closes at 06:00 Asia/Muscat.
45
+
46
+ - Before 06:00 → business day = yesterday
47
+ - After 06:00 → business day = today
48
+ """
49
+ if now is None:
50
+ now = muscat_now()
51
+
52
+ if now.hour < 6:
53
+ return (now.date() - timedelta(days=1)).isoformat()
54
+ return now.date().isoformat()
55
+
56
+
57
+ # Backward-compatible alias
58
+ business_date_for_closing = business_day_for_close
59
+
60
+
61
+ def should_auto_close(now: datetime | None = None) -> bool:
62
+ """
63
+ Returns True if auto-closing logic should run.
64
+ """
65
+ if now is None:
66
+ now = muscat_now()
67
+ return now.hour >= 6