nishtha711 commited on
Commit
418d117
·
verified ·
1 Parent(s): 364b60a

Delete database.py

Browse files
Files changed (1) hide show
  1. database.py +0 -260
database.py DELETED
@@ -1,260 +0,0 @@
1
- """
2
- database.py — Tiny Civilization persistent storage layer.
3
- All simulation state lives in a SQLite file. Functions are designed to be
4
- safe for concurrent Gradio calls (each call opens its own short-lived connection).
5
- """
6
-
7
- import sqlite3
8
- import json
9
- import os
10
- from datetime import datetime
11
- from typing import Optional
12
-
13
- # ──────────────────────────────────────────────────────────────
14
- # Database path — prefer HF Spaces /data (persistent volume),
15
- # then fall back gracefully to a local file.
16
- # ──────────────────────────────────────────────────────────────
17
- _DATA_DIRS = ["/data", "."]
18
- DB_PATH = os.getenv("TINY_DB_PATH", "")
19
- if not DB_PATH:
20
- for _d in _DATA_DIRS:
21
- try:
22
- os.makedirs(_d, exist_ok=True)
23
- _test = os.path.join(_d, ".write_test")
24
- with open(_test, "w") as f:
25
- f.write("ok")
26
- os.remove(_test)
27
- DB_PATH = os.path.join(_d, "tiny_civilization.db")
28
- break
29
- except Exception:
30
- continue
31
- if not DB_PATH:
32
- DB_PATH = "tiny_civilization.db"
33
-
34
-
35
- def _conn() -> sqlite3.Connection:
36
- """Open a SQLite connection with row_factory for dict-style access."""
37
- c = sqlite3.connect(DB_PATH, check_same_thread=False, timeout=10)
38
- c.row_factory = sqlite3.Row
39
- return c
40
-
41
-
42
- # ──────────────────────────────────────────────────────────────
43
- # Schema
44
- # ──────────────────────────────────────────────────────────────
45
-
46
- def init_db() -> None:
47
- """Create tables and seed starting creature state if absent."""
48
- with _conn() as con:
49
- cur = con.cursor()
50
-
51
- cur.execute("""
52
- CREATE TABLE IF NOT EXISTS days (
53
- day_number INTEGER PRIMARY KEY,
54
- headline TEXT NOT NULL,
55
- full_newspaper_text TEXT NOT NULL,
56
- timestamp TEXT NOT NULL
57
- )
58
- """)
59
-
60
- cur.execute("""
61
- CREATE TABLE IF NOT EXISTS events (
62
- id INTEGER PRIMARY KEY AUTOINCREMENT,
63
- day_number INTEGER NOT NULL,
64
- actor TEXT NOT NULL,
65
- action TEXT NOT NULL,
66
- target TEXT NOT NULL,
67
- description TEXT NOT NULL
68
- )
69
- """)
70
-
71
- cur.execute("""
72
- CREATE TABLE IF NOT EXISTS creatures (
73
- name TEXT PRIMARY KEY,
74
- relationship_scores TEXT NOT NULL DEFAULT '{}',
75
- inventory TEXT NOT NULL DEFAULT '[]'
76
- )
77
- """)
78
-
79
- cur.execute("""
80
- CREATE TABLE IF NOT EXISTS nudges (
81
- id INTEGER PRIMARY KEY AUTOINCREMENT,
82
- day_number INTEGER NOT NULL,
83
- nudge_type TEXT NOT NULL,
84
- nudge_value TEXT NOT NULL
85
- )
86
- """)
87
-
88
- con.commit()
89
-
90
- # ── Seed creatures if the table is empty ──────────────
91
- _SEED = {
92
- "fox": {
93
- "relationships": {"badger": 42, "squirrel": 61, "mole": 55},
94
- "inventory": ["forged certificate of merit", "silk scarf (suspect origin)"],
95
- },
96
- "badger": {
97
- "relationships": {"fox": 28, "squirrel": 67, "mole": 72},
98
- "inventory": ["ancient grudge (well-preserved)", "favourite grey stone"],
99
- },
100
- "squirrel": {
101
- "relationships": {"fox": 63, "badger": 70, "mole": 48},
102
- "inventory": ["seven-and-a-half acorns", "borrowed umbrella (decade old)"],
103
- },
104
- "mole": {
105
- "relationships": {"fox": 51, "badger": 76, "squirrel": 53},
106
- "inventory": ["map of secret tunnels", "crystal monocle", "lost button"],
107
- },
108
- }
109
-
110
- for name, data in _SEED.items():
111
- exists = cur.execute(
112
- "SELECT 1 FROM creatures WHERE name = ?", (name,)
113
- ).fetchone()
114
- if not exists:
115
- cur.execute(
116
- "INSERT INTO creatures (name, relationship_scores, inventory) VALUES (?,?,?)",
117
- (name, json.dumps(data["relationships"]), json.dumps(data["inventory"])),
118
- )
119
-
120
- con.commit()
121
-
122
-
123
- # ──────────────────────────────────────────────────────────────
124
- # Days
125
- # ──────────────────────────────────────────────────────────────
126
-
127
- def save_day(day_number: int, headline: str, full_newspaper_text: str) -> None:
128
- with _conn() as con:
129
- con.execute(
130
- "INSERT OR REPLACE INTO days (day_number, headline, full_newspaper_text, timestamp) "
131
- "VALUES (?,?,?,?)",
132
- (day_number, headline, full_newspaper_text, datetime.now().isoformat()),
133
- )
134
- con.commit()
135
-
136
-
137
- def get_latest_day() -> Optional[dict]:
138
- with _conn() as con:
139
- row = con.execute(
140
- "SELECT * FROM days ORDER BY day_number DESC LIMIT 1"
141
- ).fetchone()
142
- return dict(row) if row else None
143
-
144
-
145
- def get_day(day_number: int) -> Optional[dict]:
146
- with _conn() as con:
147
- row = con.execute(
148
- "SELECT * FROM days WHERE day_number = ?", (day_number,)
149
- ).fetchone()
150
- return dict(row) if row else None
151
-
152
-
153
- def get_all_headlines() -> list[tuple[int, str]]:
154
- with _conn() as con:
155
- rows = con.execute(
156
- "SELECT day_number, headline FROM days ORDER BY day_number DESC"
157
- ).fetchall()
158
- return [(r["day_number"], r["headline"]) for r in rows]
159
-
160
-
161
- def get_next_day_number() -> int:
162
- with _conn() as con:
163
- row = con.execute("SELECT MAX(day_number) AS m FROM days").fetchone()
164
- return (row["m"] or 0) + 1
165
-
166
-
167
- # ──────────────────────────────────────────────────────────────
168
- # Events
169
- # ──────────────────────────────────────────────────────────────
170
-
171
- def save_event(
172
- day_number: int, actor: str, action: str, target: str, description: str
173
- ) -> None:
174
- with _conn() as con:
175
- con.execute(
176
- "INSERT INTO events (day_number, actor, action, target, description) "
177
- "VALUES (?,?,?,?,?)",
178
- (day_number, actor, action, target, description),
179
- )
180
- con.commit()
181
-
182
-
183
- def get_events_for_day(day_number: int) -> list[dict]:
184
- with _conn() as con:
185
- rows = con.execute(
186
- "SELECT actor, action, target, description FROM events WHERE day_number = ?",
187
- (day_number,),
188
- ).fetchall()
189
- return [dict(r) for r in rows]
190
-
191
-
192
- # ──────────────────────────────────────────────────────────────
193
- # Nudges
194
- # ──────────────────────────────────────────────────────────────
195
-
196
- def save_nudge(day_number: int, nudge_type: str, nudge_value: str) -> None:
197
- with _conn() as con:
198
- con.execute(
199
- "INSERT INTO nudges (day_number, nudge_type, nudge_value) VALUES (?,?,?)",
200
- (day_number, nudge_type, nudge_value),
201
- )
202
- con.commit()
203
-
204
-
205
- def get_recent_nudges(limit: int = 4) -> list[dict]:
206
- with _conn() as con:
207
- rows = con.execute(
208
- "SELECT day_number, nudge_type, nudge_value FROM nudges ORDER BY id DESC LIMIT ?",
209
- (limit,),
210
- ).fetchall()
211
- return [dict(r) for r in rows]
212
-
213
-
214
- # ──────────────────────────────────────────────────────────────
215
- # Creatures
216
- # ──────────────────────────────────────────────────────────────
217
-
218
- def _parse_creature(row: sqlite3.Row) -> dict:
219
- d = dict(row)
220
- d["relationship_scores"] = json.loads(d["relationship_scores"])
221
- d["inventory"] = json.loads(d["inventory"])
222
- return d
223
-
224
-
225
- def get_creature(name: str) -> Optional[dict]:
226
- with _conn() as con:
227
- row = con.execute(
228
- "SELECT * FROM creatures WHERE name = ?", (name,)
229
- ).fetchone()
230
- return _parse_creature(row) if row else None
231
-
232
-
233
- def get_all_creatures() -> list[dict]:
234
- with _conn() as con:
235
- rows = con.execute("SELECT * FROM creatures").fetchall()
236
- return [_parse_creature(r) for r in rows]
237
-
238
-
239
- def update_creature(
240
- name: str,
241
- relationship_scores: Optional[dict] = None,
242
- inventory: Optional[list] = None,
243
- ) -> None:
244
- with _conn() as con:
245
- if relationship_scores is not None and inventory is not None:
246
- con.execute(
247
- "UPDATE creatures SET relationship_scores=?, inventory=? WHERE name=?",
248
- (json.dumps(relationship_scores), json.dumps(inventory), name),
249
- )
250
- elif relationship_scores is not None:
251
- con.execute(
252
- "UPDATE creatures SET relationship_scores=? WHERE name=?",
253
- (json.dumps(relationship_scores), name),
254
- )
255
- elif inventory is not None:
256
- con.execute(
257
- "UPDATE creatures SET inventory=? WHERE name=?",
258
- (json.dumps(inventory), name),
259
- )
260
- con.commit()