Skip to content

Commit 3451756

Browse files
committed
POC: cache media id
1 parent 805a070 commit 3451756

4 files changed

Lines changed: 1109 additions & 96 deletions

File tree

src/core/database.py

Lines changed: 138 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
"""Database storage layer for Flow2API"""
2+
from pathlib import Path
3+
24
import aiosqlite
35
import json
4-
from datetime import datetime
56
from typing import Optional, List, Dict, Any
6-
from pathlib import Path
7-
from .models import Token, TokenStats, Task, RequestLog, AdminConfig, ProxyConfig, GenerationConfig, CacheConfig, Project, CaptchaConfig, PluginConfig, CallLogicConfig
7+
8+
from .models import Token, TokenStats, Task, RequestLog, AdminConfig, ProxyConfig, GenerationConfig, CacheConfig, \
9+
Project, CaptchaConfig, PluginConfig, CallLogicConfig
810

911

1012
class Database:
@@ -325,6 +327,25 @@ async def check_and_migrate_db(self, config_dict: dict = None):
325327
)
326328
""")
327329

330+
# Check and create uploaded_image_cache table if missing
331+
if not await self._table_exists(db, "uploaded_image_cache"):
332+
print(" ✓ Creating missing table: uploaded_image_cache")
333+
await db.execute("""
334+
CREATE TABLE uploaded_image_cache
335+
(
336+
id INTEGER PRIMARY KEY AUTOINCREMENT,
337+
email TEXT NOT NULL,
338+
project_id TEXT NOT NULL,
339+
image_hash TEXT NOT NULL,
340+
aspect_ratio TEXT NOT NULL,
341+
media_id TEXT NOT NULL,
342+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
343+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
344+
last_used_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
345+
UNIQUE (email, project_id, image_hash, aspect_ratio)
346+
)
347+
""")
348+
328349
# ========== Step 2: Add missing columns to existing tables ==========
329350
# Check and add missing columns to tokens table
330351
if await self._table_exists(db, "tokens"):
@@ -543,6 +564,23 @@ async def init_db(self):
543564
)
544565
""")
545566

567+
# Uploaded image media cache table
568+
await db.execute("""
569+
CREATE TABLE IF NOT EXISTS uploaded_image_cache
570+
(
571+
id INTEGER PRIMARY KEY AUTOINCREMENT,
572+
email TEXT NOT NULL,
573+
project_id TEXT NOT NULL,
574+
image_hash TEXT NOT NULL,
575+
aspect_ratio TEXT NOT NULL,
576+
media_id TEXT NOT NULL,
577+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
578+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
579+
last_used_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
580+
UNIQUE (email, project_id, image_hash, aspect_ratio)
581+
)
582+
""")
583+
546584
# Admin config table
547585
await db.execute("""
548586
CREATE TABLE IF NOT EXISTS admin_config (
@@ -656,6 +694,8 @@ async def init_db(self):
656694
await db.execute("CREATE INDEX IF NOT EXISTS idx_project_id ON projects(project_id)")
657695
await db.execute("CREATE INDEX IF NOT EXISTS idx_tokens_email ON tokens(email)")
658696
await db.execute("CREATE INDEX IF NOT EXISTS idx_tokens_is_active_last_used_at ON tokens(is_active, last_used_at)")
697+
await db.execute(
698+
"CREATE INDEX IF NOT EXISTS idx_uploaded_image_cache_lookup ON uploaded_image_cache(email, project_id, image_hash, aspect_ratio)")
659699

660700
# Migrate request_logs table if needed
661701
await self._migrate_request_logs(db)
@@ -944,6 +984,101 @@ async def delete_project(self, project_id: str):
944984
await db.execute("DELETE FROM projects WHERE project_id = ?", (project_id,))
945985
await db.commit()
946986

987+
# Uploaded image cache operations
988+
async def get_uploaded_image_cache(
989+
self,
990+
email: str,
991+
project_id: str,
992+
image_hash: str,
993+
aspect_ratio: str,
994+
) -> Optional[Dict[str, Any]]:
995+
"""Get cached uploaded media metadata by cache key."""
996+
async with aiosqlite.connect(self.db_path) as db:
997+
db.row_factory = aiosqlite.Row
998+
cursor = await db.execute(
999+
"""
1000+
SELECT *
1001+
FROM uploaded_image_cache
1002+
WHERE email = ?
1003+
AND project_id = ?
1004+
AND image_hash = ?
1005+
AND aspect_ratio = ?
1006+
""",
1007+
(email, project_id, image_hash, aspect_ratio),
1008+
)
1009+
row = await cursor.fetchone()
1010+
if row:
1011+
return dict(row)
1012+
return None
1013+
1014+
async def upsert_uploaded_image_cache(
1015+
self,
1016+
email: str,
1017+
project_id: str,
1018+
image_hash: str,
1019+
aspect_ratio: str,
1020+
media_id: str,
1021+
):
1022+
"""Insert or update cached uploaded media metadata."""
1023+
async with aiosqlite.connect(self.db_path) as db:
1024+
await db.execute(
1025+
"""
1026+
INSERT INTO uploaded_image_cache (email, project_id, image_hash, aspect_ratio, media_id)
1027+
VALUES (?, ?, ?, ?, ?)
1028+
ON CONFLICT(email, project_id, image_hash, aspect_ratio)
1029+
DO UPDATE SET media_id = excluded.media_id,
1030+
updated_at = CURRENT_TIMESTAMP,
1031+
last_used_at = CURRENT_TIMESTAMP
1032+
""",
1033+
(email, project_id, image_hash, aspect_ratio, media_id),
1034+
)
1035+
await db.commit()
1036+
1037+
async def touch_uploaded_image_cache(
1038+
self,
1039+
email: str,
1040+
project_id: str,
1041+
image_hash: str,
1042+
aspect_ratio: str,
1043+
):
1044+
"""Update cache entry usage timestamps."""
1045+
async with aiosqlite.connect(self.db_path) as db:
1046+
await db.execute(
1047+
"""
1048+
UPDATE uploaded_image_cache
1049+
SET updated_at = CURRENT_TIMESTAMP,
1050+
last_used_at = CURRENT_TIMESTAMP
1051+
WHERE email = ?
1052+
AND project_id = ?
1053+
AND image_hash = ?
1054+
AND aspect_ratio = ?
1055+
""",
1056+
(email, project_id, image_hash, aspect_ratio),
1057+
)
1058+
await db.commit()
1059+
1060+
async def delete_uploaded_image_cache(
1061+
self,
1062+
email: str,
1063+
project_id: str,
1064+
image_hash: str,
1065+
aspect_ratio: str,
1066+
):
1067+
"""Delete cached uploaded media metadata by cache key."""
1068+
async with aiosqlite.connect(self.db_path) as db:
1069+
await db.execute(
1070+
"""
1071+
DELETE
1072+
FROM uploaded_image_cache
1073+
WHERE email = ?
1074+
AND project_id = ?
1075+
AND image_hash = ?
1076+
AND aspect_ratio = ?
1077+
""",
1078+
(email, project_id, image_hash, aspect_ratio),
1079+
)
1080+
await db.commit()
1081+
9471082
# Task operations
9481083
async def create_task(self, task: Task) -> int:
9491084
"""Create a new task"""

0 commit comments

Comments
 (0)