feat: refactor db calls to url service

This commit is contained in:
2025-07-23 02:58:46 +00:00
parent ee67589393
commit d2d045a89d
15 changed files with 88 additions and 54 deletions

View File

@@ -1 +1 @@
from .encoder import encoder
from .url_service import UrlService

View File

@@ -1,27 +0,0 @@
from app.config import settings
from hashids import Hashids
class ShortCodeEncoder:
def __init__(self, salt=None, alphabet=None, min_length=6):
self.salt = salt or settings.hashids_salt
self.alphabet = alphabet or settings.encoder_alphabet
self.hashids = Hashids(salt=self.salt, min_length=min_length, alphabet=self.alphabet)
self.min_length = min_length
def encode(self, id: int) -> str:
return self.hashids.encode(id)
def decode(self, shortcode: str) -> int:
decoded = self.hashids.decode(shortcode)
return decoded[0] if decoded else None
def is_valid(self, shortcode: str) -> bool:
if len(shortcode) < self.min_length:
return False
if any(char not in self.alphabet for char in shortcode):
return False
return True
# Singleton instance of encoder
encoder = ShortCodeEncoder()

View File

@@ -0,0 +1,36 @@
from sqlalchemy import select, insert
from sqlalchemy.exc import IntegrityError
from app.utils import encoder
from app.models import Url
from app.exceptions import ShortcodeConflict, ShortcodeNotFound
class UrlService:
def __init__(self, db):
self.db = db
async def get_url_by_shortcode(self, shortcode: str) -> str:
query = select(Url.url).where(Url.shortcode == shortcode)
result = await self.db.fetch_val(query)
if result is None:
raise ShortcodeNotFound(f"Shortcode '{shortcode}' not found")
return result
async def generate_shortcode_and_save(self, url: str):
try:
# Get the next ID from the sequence
next_id = await self.db.fetch_val("SELECT nextval('urls_id_seq')")
shortcode = encoder.encode(next_id)
# Insert the new URL entry
insert_stmt = insert(Url).values(id=next_id, url=url, shortcode=shortcode)
await self.db.execute(insert_stmt)
return {"shortcode": shortcode, "url": url}
except IntegrityError as e:
if 'shortcode' in str(e):
raise ShortcodeConflict(f"Shortcode '{shortcode}' already in use") from None
raise