Skip to content

Commit 2a5a4e0

Browse files
author
SM_SAYEED
committed
route level guard added for handling missing columns
1 parent 1f4cb63 commit 2a5a4e0

File tree

1 file changed

+121
-79
lines changed

1 file changed

+121
-79
lines changed

app.py

Lines changed: 121 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -253,78 +253,91 @@ def make_file_public(file_id: str):
253253
#==================================================#
254254

255255
def ensure_uploads_log_schema():
256-
"""Public catalog (uploads_log) + audit history (uploads_audit) with triggers."""
256+
"""
257+
Create/upgrade:
258+
- uploads_log (public catalog)
259+
- uploads_audit (history)
260+
- audit triggers (insert/update/delete on uploads_log)
261+
Never let a UNIQUE index error block creating the audit bits.
262+
"""
257263
with sqlite3.connect(DB_NAME) as conn:
258264
c = conn.cursor()
259265

260-
# Public catalog (what public pages read)
266+
# 1) Public catalog (Drive-era columns included)
261267
c.execute("""
262-
CREATE TABLE IF NOT EXISTS uploads_log (
263-
id INTEGER PRIMARY KEY AUTOINCREMENT,
264-
property TEXT NOT NULL,
265-
tab TEXT NOT NULL, -- 'dataset' | 'results'
266-
filename TEXT NOT NULL, -- human-visible label
267-
uploaded_at TEXT, -- first/last touch, maintained by app
268-
-- Drive-first metadata
269-
storage TEXT, -- 'drive' | 'local' (legacy)
270-
drive_id TEXT,
271-
preview_url TEXT,
272-
download_url TEXT,
273-
source TEXT,
274-
description TEXT,
275-
UNIQUE(property, tab, filename)
276-
)
268+
CREATE TABLE IF NOT EXISTS uploads_log (
269+
id INTEGER PRIMARY KEY AUTOINCREMENT,
270+
property TEXT NOT NULL,
271+
tab TEXT NOT NULL, -- 'dataset' | 'results'
272+
filename TEXT NOT NULL, -- human-visible label
273+
uploaded_at TEXT, -- first/last touch, maintained by app
274+
-- Drive-first metadata
275+
storage TEXT, -- 'drive' | 'local' (legacy)
276+
drive_id TEXT,
277+
preview_url TEXT,
278+
download_url TEXT,
279+
source TEXT,
280+
description TEXT,
281+
UNIQUE(property, tab, filename)
282+
)
277283
""")
278284

279-
# Ensure index exists even on old DBs
280-
c.execute("""
281-
CREATE UNIQUE INDEX IF NOT EXISTS idx_uploads_unique
282-
ON uploads_log(property, tab, filename)
283-
""")
285+
# 2) Unique index: wrap so it never blocks later steps
286+
try:
287+
c.execute("""
288+
CREATE UNIQUE INDEX IF NOT EXISTS idx_uploads_unique
289+
ON uploads_log(property, tab, filename)
290+
""")
291+
except sqlite3.OperationalError as e:
292+
# e.g., duplicates present -> index creation fails. Log and continue.
293+
app.logger.warning("ensure_uploads_log_schema: unique index creation skipped: %s", e)
284294

285-
# ---- Audit table
295+
# 3) Audit table (history)
286296
c.execute("""
287-
CREATE TABLE IF NOT EXISTS uploads_audit (
288-
id INTEGER PRIMARY KEY AUTOINCREMENT,
289-
property TEXT NOT NULL,
290-
tab TEXT NOT NULL,
291-
filename TEXT NOT NULL,
292-
action TEXT NOT NULL, -- add | update | delete
293-
at TEXT NOT NULL
294-
)
297+
CREATE TABLE IF NOT EXISTS uploads_audit (
298+
id INTEGER PRIMARY KEY AUTOINCREMENT,
299+
property TEXT NOT NULL,
300+
tab TEXT NOT NULL,
301+
filename TEXT NOT NULL,
302+
action TEXT NOT NULL, -- add | update | delete
303+
at TEXT NOT NULL
304+
)
295305
""")
296306

297-
# Helper to create triggers idempotently
298-
def ensure_trigger(name, ddl):
307+
# 4) Triggers (create only if missing)
308+
def ensure_trigger(name: str, ddl: str):
299309
c.execute("SELECT 1 FROM sqlite_master WHERE type='trigger' AND name=?", (name,))
300310
if not c.fetchone():
301311
c.execute(ddl)
302312

303313
ensure_trigger("trg_ul_insert_audit", """
304-
CREATE TRIGGER trg_ul_insert_audit
305-
AFTER INSERT ON uploads_log
306-
BEGIN
307-
INSERT INTO uploads_audit(property, tab, filename, action, at)
308-
VALUES (NEW.property, NEW.tab, NEW.filename, 'add',
309-
COALESCE(NEW.uploaded_at, CURRENT_TIMESTAMP));
310-
END;""")
314+
CREATE TRIGGER trg_ul_insert_audit
315+
AFTER INSERT ON uploads_log
316+
BEGIN
317+
INSERT INTO uploads_audit(property, tab, filename, action, at)
318+
VALUES (NEW.property, NEW.tab, NEW.filename, 'add',
319+
COALESCE(NEW.uploaded_at, CURRENT_TIMESTAMP));
320+
END;
321+
""")
311322

312323
ensure_trigger("trg_ul_update_audit", """
313-
CREATE TRIGGER trg_ul_update_audit
314-
AFTER UPDATE ON uploads_log
315-
BEGIN
316-
INSERT INTO uploads_audit(property, tab, filename, action, at)
317-
VALUES (NEW.property, NEW.tab, NEW.filename, 'update',
318-
COALESCE(NEW.uploaded_at, CURRENT_TIMESTAMP));
319-
END;""")
324+
CREATE TRIGGER trg_ul_update_audit
325+
AFTER UPDATE ON uploads_log
326+
BEGIN
327+
INSERT INTO uploads_audit(property, tab, filename, action, at)
328+
VALUES (NEW.property, NEW.tab, NEW.filename, 'update',
329+
COALESCE(NEW.uploaded_at, CURRENT_TIMESTAMP));
330+
END;
331+
""")
320332

321333
ensure_trigger("trg_ul_delete_audit", """
322-
CREATE TRIGGER trg_ul_delete_audit
323-
AFTER DELETE ON uploads_log
324-
BEGIN
325-
INSERT INTO uploads_audit(property, tab, filename, action, at)
326-
VALUES (OLD.property, OLD.tab, OLD.filename, 'delete', CURRENT_TIMESTAMP);
327-
END;""")
334+
CREATE TRIGGER trg_ul_delete_audit
335+
AFTER DELETE ON uploads_log
336+
BEGIN
337+
INSERT INTO uploads_audit(property, tab, filename, action, at)
338+
VALUES (OLD.property, OLD.tab, OLD.filename, 'delete', CURRENT_TIMESTAMP);
339+
END;
340+
""")
328341

329342
conn.commit()
330343
#==================================================#
@@ -730,37 +743,66 @@ def admin_home():
730743
if not session.get('admin'):
731744
return redirect(url_for('login'))
732745

733-
# Make sure catalog + audit schema exist (triggers are created here too)
734-
ensure_uploads_log_schema()
746+
# Ensure base schema exists (tables + triggers), but never crash this page
735747
try:
736-
ensure_uploads_log_columns() # Add Drive-era columns if missing
748+
ensure_uploads_log_schema()
737749
except Exception as e:
738-
app.logger.warning("ensure_uploads_log_columns : %s", e)
750+
app.logger.warning("ensure_uploads_log_schema raised: %s", e)
739751

740-
# Build the history table: when first added, and whether still present publicly
741-
with sqlite3.connect(DB_NAME) as conn:
742-
c = conn.cursor()
743-
c.execute("""
744-
WITH hist AS (
745-
SELECT property, tab, filename,
746-
MIN(CASE WHEN action='add' THEN at END) AS first_added,
747-
MAX(at) AS last_event
748-
FROM uploads_audit
749-
GROUP BY property, tab, filename
750-
)
751-
SELECT
752-
h.filename AS file_name,
753-
COALESCE(h.first_added, h.last_event) AS uploaded_at,
754-
CASE WHEN u.rowid IS NULL THEN 'Absent' ELSE 'Present' END AS public_view_status
755-
FROM hist h
756-
LEFT JOIN uploads_log u
757-
ON u.property=h.property AND u.tab=h.tab AND u.filename=h.filename
758-
ORDER BY uploaded_at DESC, h.filename;
759-
""")
760-
audit_rows = c.fetchall()
752+
# Best effort: make sure Drive-era columns exist (storage, drive_id, etc.)
753+
try:
754+
ensure_uploads_log_columns() # your existing helper that ALTER TABLE as needed
755+
except Exception as e:
756+
app.logger.warning("ensure_uploads_log_columns raised: %s", e)
761757

762-
return render_template('admin_home.html', audit_rows=audit_rows)
758+
# Guard: if audit table still missing (older DBs), create it quickly so page works
759+
try:
760+
with sqlite3.connect(DB_NAME) as conn:
761+
c = conn.cursor()
762+
c.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='uploads_audit'")
763+
if not c.fetchone():
764+
c.execute("""
765+
CREATE TABLE IF NOT EXISTS uploads_audit (
766+
id INTEGER PRIMARY KEY AUTOINCREMENT,
767+
property TEXT NOT NULL,
768+
tab TEXT NOT NULL,
769+
filename TEXT NOT NULL,
770+
action TEXT NOT NULL, -- add | update | delete
771+
at TEXT NOT NULL
772+
)
773+
""")
774+
conn.commit()
775+
except Exception as e:
776+
app.logger.warning("guard-create uploads_audit failed: %s", e)
777+
778+
# Build the history table (don’t crash page if something’s off)
779+
audit_rows = []
780+
try:
781+
with sqlite3.connect(DB_NAME) as conn:
782+
c = conn.cursor()
783+
c.execute("""
784+
WITH hist AS (
785+
SELECT property, tab, filename,
786+
MIN(CASE WHEN action='add' THEN at END) AS first_added,
787+
MAX(at) AS last_event
788+
FROM uploads_audit
789+
GROUP BY property, tab, filename
790+
)
791+
SELECT
792+
h.filename AS file_name,
793+
COALESCE(h.first_added, h.last_event) AS uploaded_at,
794+
CASE WHEN u.rowid IS NULL THEN 'Absent' ELSE 'Present' END AS public_view_status
795+
FROM hist h
796+
LEFT JOIN uploads_log u
797+
ON u.property=h.property AND u.tab=h.tab AND u.filename=h.filename
798+
ORDER BY uploaded_at DESC, h.filename;
799+
""")
800+
audit_rows = c.fetchall()
801+
except Exception as e:
802+
app.logger.warning("admin_home query failed: %s", e)
803+
audit_rows = []
763804

805+
return render_template('admin_home.html', audit_rows=audit_rows)
764806
#########################################################
765807

766808
@app.route("/admin/fix_uploads_uniqueness", methods=["GET", "POST"])

0 commit comments

Comments
 (0)