Skip to content

Writing/SQLite

Două baze de date și o graniță pe care n-o treci niciodată

O aplicație care își livrează propriul conținut are o problemă: fiecare actualizare înlocuiește conținutul acela, iar notițele utilizatorului stau în același fișier.

ISIonuț Sandu06 aug 2026 · 6 min de cititSQLiteArhitecturăOffline-first

Construiesc un cititor offline-first care își livrează textul în interiorul aplicației. Fără conturi, fără rețea, fără reclame. Ceea ce ridică o întrebare la care majoritatea aplicațiilor nu trebuie să răspundă niciodată: ce se întâmplă cu evidențierile și notițele cuiva atunci când textul de care sunt legate e înlocuit de o actualizare?

Răspunsul comod e o singură bază de date și o migrare care duce notițele dincolo. Răspunsul corect e două baze de date și o regulă că nimic nu are voie să treacă între ele.

Una e de aruncat, cealaltă e de neînlocuit

Baza de date cu conținut e doar de citit, livrată în binar și înlocuită în întregime la fiecare actualizare. E de aruncat prin construcție. Dacă un build o corupe, următorul o repară și nu pierde nimeni nimic.

Baza de date a utilizatorului stă în documentele aplicației, nu se livrează niciodată și nu se înlocuiește niciodată. Ține evidențieri, notițe, semne de carte și poziția în lectură. E singurul lucru din aplicație care nu poate fi regenerat și aparține unui om, nu unei versiuni.

“O actualizare care poate ajunge la notițele utilizatorului nu e o actualizare. E un risc pe care îl livrezi după program.”

Regula care face lucrul ăsta să țină e că nicio migrare nu are voie să copieze peste graniță. În clipa în care una o face, cele două fișiere sunt cuplate, iar o actualizare devine capabilă să distrugă ani de adnotări. Notițele fac referire la conținut printr-un identificator stabil, nu printr-un rând, așa că textul de dedesubt poate fi înlocuit fără ca referința să însemne altceva.

Testarea SQL-ului prin rularea lui

Repository-urile primesc o interfață mică de bază de date, în loc să apeleze direct biblioteca SQLite a platformei. Nu e stratificare de dragul stratificării. Înseamnă că SQL-ul real, exact așa cum e scris, rulează în teste pe un SQLite în proces, în loc să fie înlocuit cu un mock.

Un mock de bază de date testează că ți-ai apelat corect propriul wrapper. Nu-ți poate spune că o interogare e greșită, iar o interogare greșită e tot riscul. Așa, testele sunt cu câteva milisecunde mai lente și testează lucrul care chiar se poate strica.

Un detaliu care merită furat: căutarea în tot textul e configurată cu diacriticele eliminate, pentru că un cititor român va tasta un cuvânt fără semne diacritice și se așteaptă să-l găsească. Genul ăsta de lucru se verifică empiric pe text real, nu se presupune din documentație, iar de aceea verificarea căutării a existat înaintea oricărui ecran.

Ionuț Sandu — 06 aug 2026Copiază linkul

URMĂTORUL · 05 AUG 2026 · 6 MIN DE CITIT

Pornește de la ce ai deja în baie

De ce Rhovie începe cu raftul din baia ta, nu cu o listă de cumpărături.

Preiau proiecte noi

Spune-mi ce construiești.Un plan scris și un preț fix înainte să se miște vreun ban.

Răspund la tot într-o zi lucrătoare. Dacă nu sunt omul potrivit pentru proiect, ți-o spun din start, nu după trei săptămâni.