···5566## [Unreleased]
7788+## [0.4.6] - 2026-03-30
99+1010+### Added
1111+- Added P2P chat sync in [#109](https://github.com/tilesprivacy/tiles/pull/109)
1212+ - Commands for chat syncing
1313+ - `tiles sync` - Starts listening for a sync request from the linked peers.
1414+ - `tiles sync <DID>` - Initiates the syncing with the peer using the peer's linked DID (which one can get from `tiles link list-peers`).
1515+- Added at rest encryption for local databases in [#110](https://github.com/tilesprivacy/tiles/pull/110)
1616+1717+### Fixed
1818+- Fixed the loading issue of qwen 3.5 series in [#111](https://github.com/tilesprivacy/tiles/pull/111)
1919+820## [0.4.5] - 2026-03-23
9211022### Added
···1212use uuid::Uuid;
13131414use crate::{
1515- core::storage::db::{DBTYPE, get_db_conn},
1515+ core::storage::db::Dbconn,
1616 utils::config::{get_app_name, get_or_create_config, save_config},
1717};
1818const ROOT_USER_CONFIG_KEY: &str = "root-user";
···249249 .map_err(<rusqlite::Error as Into<anyhow::Error>>::into)
250250}
251251252252-pub fn save_root_account_db() -> Result<()> {
253253- let conn = get_db_conn(&DBTYPE::COMMON)?;
252252+pub fn save_root_account_db(db_conn: &Dbconn) -> Result<()> {
254253 let config = get_or_create_config()?;
255254 let root_user = get_root_user_details(&config)?;
256255 let user = User {
···270269 .as_secs(),
271270 };
272271273273- let mut fetch_root_user = conn.prepare("select id from users where root = true")?;
272272+ let mut fetch_root_user = db_conn
273273+ .common
274274+ .prepare("select id from users where root = true")?;
274275275276 match fetch_root_user.query_one([], |_row| Ok(())) {
276277 Err(rusqlite::Error::QueryReturnedNoRows) => {
277277- conn.execute("insert into users (id, user_id, username, active_profile, account_type, root) values
278278+ db_conn.common.execute("insert into users (id, user_id, username, active_profile, account_type, root) values
278279 (?1, ?2, ?3,?4, ?5, ?6)", (&user.id.to_string(), &user.user_id, &user.username, &user.active_profile,
279280 user.account_type.to_string(), &user.root))?;
280281 Ok(())
+12-1
tiles/src/core/chats.rs
···180180 // TODO: Handle primary key conflict, for now reject it (in a way its impossible to have this scenario, and if its occuring then that means
181181 // some issue in syncing, so ignore it, by rejecting it), later
182182 // do LWW based on issuer of UCAN
183183+ //
184184+183185 let txn = chat_conn.transaction()?;
184186 {
185187 let mut stmt = txn.prepare("insert into chats(id, user_id, content, resp_id, role, context_id, created_at, updated_at, row_counter) values (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9)")?;
···204206 &chat.id
205207 );
206208 }
207207- Err(err) => log::error!("err in writing row due to {:?}", err),
209209+ // NOTE: If any other error occurs and write failed we abort the sync, so the the row_counter doesn't get skipped.
210210+ // use RUST_LOG=error tiles to debug the issue
211211+ Err(err) => {
212212+ log::error!(
213213+ "err in writing row due to {:?}, Aborting the sync ....",
214214+ err
215215+ );
216216+ break;
217217+ }
218218+208219 Ok(_) => (),
209220 }
210221 }
+3-4
tiles/src/core/mod.rs
···5566use anyhow::Result;
7788-use crate::core::{accounts::save_root_account_db, storage::db::init_db};
88+use crate::core::{accounts::save_root_account_db, storage::db::Dbconn};
991010pub mod accounts;
1111pub mod chats;
···1414pub mod storage;
15151616// Entrypoint of the core
1717-pub fn init() -> Result<()> {
1818- init_db()?;
1919- save_root_account_db()
1717+pub fn init(db_conn: &Dbconn) -> Result<()> {
1818+ save_root_account_db(db_conn)
2019}