use r2d2 pool, update rusqlite version

This commit is contained in:
yggverse 2025-03-14 12:27:09 +02:00
parent c3f63dfbdc
commit 33369e31ea
17 changed files with 171 additions and 197 deletions

View file

@ -22,7 +22,7 @@ features = ["gnome_46"]
[dependencies.sqlite]
package = "rusqlite"
version = "0.32.1"
version = "0.34.0"
[dependencies.sourceview]
package = "sourceview5"
@ -38,6 +38,8 @@ itertools = "0.14.0"
libspelling = "0.3.0"
openssl = "0.10.70"
plurify = "0.2.0"
r2d2 = "0.8.10"
r2d2_sqlite = "0.27.0"
syntect = "5.2.0"
# development

View file

@ -42,7 +42,7 @@ impl App {
let profile = profile.clone();
move |this| {
// Init readable connection
match profile.database.connection.read() {
match profile.database.pool.get() {
Ok(connection) => {
// Create transaction
match connection.unchecked_transaction() {
@ -77,7 +77,7 @@ impl App {
let profile = profile.clone();
move |_| {
match profile.save() {
Ok(_) => match profile.database.connection.write() {
Ok(_) => match profile.database.pool.get() {
Ok(mut connection) => {
// Create transaction
match connection.transaction() {
@ -266,7 +266,7 @@ impl App {
pub fn run(&self) -> Result<ExitCode> {
// Begin database migration @TODO
{
let mut connection = self.profile.database.connection.write().unwrap();
let mut connection = self.profile.database.pool.get()?;
let transaction = connection.transaction()?;
migrate(&transaction)?;
transaction.commit()?;

View file

@ -46,7 +46,7 @@ impl Save {
button.set_sensitive(false);
// Create PEM file based on option ID selected
match Certificate::new(profile.clone(), profile_identity_id) {
match Certificate::build(profile.clone(), profile_identity_id) {
Ok(certificate) => {
// Init file filters related with PEM extension
let filters = ListStore::new::<FileFilter>();

View file

@ -1,5 +1,4 @@
mod error;
pub use error::Error;
use anyhow::{bail, Result};
use crate::profile::Profile;
use gtk::{gio::TlsCertificate, prelude::TlsCertificateExt};
@ -15,19 +14,17 @@ impl Certificate {
// Constructors
/// Create new `Self`
pub fn new(profile: Rc<Profile>, profile_identity_id: i64) -> Result<Self, Error> {
match profile.identity.database.record(profile_identity_id) {
Ok(record) => match record {
Some(identity) => match TlsCertificate::from_pem(&identity.pem) {
Ok(certificate) => Ok(Self {
data: identity.pem,
name: certificate.subject_name().unwrap().replace("CN=", ""),
}),
Err(e) => Err(Error::TlsCertificate(e)),
},
None => Err(Error::NotFound(profile_identity_id)),
},
Err(e) => Err(Error::Database(e)),
pub fn build(profile: Rc<Profile>, profile_identity_id: i64) -> Result<Self> {
let record = profile.identity.database.record(profile_identity_id)?;
match record {
Some(identity) => Ok(Self {
name: TlsCertificate::from_pem(&identity.pem)?
.subject_name()
.unwrap_or_default()
.replace("CN=", ""),
data: identity.pem,
}),
None => bail!("Identity not found!"),
}
}
}

View file

@ -1,25 +0,0 @@
use gtk::glib;
use std::fmt::{Display, Formatter, Result};
#[derive(Debug)]
pub enum Error {
Database(sqlite::Error),
NotFound(i64),
TlsCertificate(glib::Error),
}
impl Display for Error {
fn fmt(&self, f: &mut Formatter) -> Result {
match self {
Self::Database(e) => {
write!(f, "Database error: {e}")
}
Self::NotFound(profile_identity_id) => {
write!(f, "Record for `{profile_identity_id}` not found")
}
Self::TlsCertificate(e) => {
write!(f, "TLS certificate error: {e}")
}
}
}
}

View file

@ -4,16 +4,17 @@ mod history;
mod identity;
mod search;
use anyhow::Result;
use bookmark::Bookmark;
use database::Database;
use gtk::glib::{user_config_dir, DateTime};
use history::History;
use identity::Identity;
use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager;
use search::Search;
use anyhow::Result;
use gtk::glib::{user_config_dir, DateTime};
use sqlite::{Connection, Transaction};
use std::{fs::create_dir_all, path::PathBuf, rc::Rc, sync::RwLock};
use sqlite::Transaction;
use std::{fs::create_dir_all, path::PathBuf};
const VENDOR: &str = "YGGverse";
const APP_ID: &str = "Yoda";
@ -53,23 +54,24 @@ impl Profile {
database_path.push(DB_NAME);
// Init database connection
let connection = Rc::new(RwLock::new(Connection::open(database_path.as_path())?));
let database_pool =
Pool::new(SqliteConnectionManager::file(database_path.as_path())).unwrap();
// Init profile components
{
// Init writable connection
let mut connection = connection.write().unwrap(); // @TODO handle
let mut connection = database_pool.get()?;
// Init new transaction
let transaction = connection.transaction()?;
let tx = connection.transaction()?;
// Begin migration
migrate(&transaction)?;
transaction.commit()?;
migrate(&tx)?;
tx.commit()?;
} // unlock database
// Init model
let database = Database::build(&connection);
let database = Database::build(&database_pool);
// Get active profile or create new one
let profile_id = match database.active()? {
@ -78,10 +80,10 @@ impl Profile {
};
// Init components
let bookmark = Bookmark::build(&connection, profile_id)?;
let history = History::build(&connection, profile_id)?;
let search = Search::build(&connection, profile_id)?;
let identity = Identity::build(&connection, profile_id)?;
let bookmark = Bookmark::build(&database_pool, profile_id)?;
let history = History::build(&database_pool, profile_id)?;
let search = Search::build(&database_pool, profile_id)?;
let identity = Identity::build(&database_pool, profile_id)?;
// Result
Ok(Self {

View file

@ -7,11 +7,10 @@ use database::Database;
use gtk::glib::DateTime;
use item::Item;
use memory::Memory;
use sqlite::{Connection, Transaction};
use std::{
rc::Rc,
sync::{Arc, RwLock},
};
use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager;
use sqlite::Transaction;
use std::sync::{Arc, RwLock};
pub struct Bookmark {
database: Database, // permanent storage
@ -22,9 +21,9 @@ impl Bookmark {
// Constructors
/// Create new `Self`
pub fn build(connection: &Rc<RwLock<Connection>>, profile_id: i64) -> Result<Self> {
pub fn build(database_pool: &Pool<SqliteConnectionManager>, profile_id: i64) -> Result<Self> {
// Init children components
let database = Database::new(connection, profile_id);
let database = Database::new(database_pool, profile_id);
let memory = Arc::new(RwLock::new(Memory::new()));
// Build initial index

View file

@ -1,11 +1,12 @@
use super::Item;
use anyhow::Result;
use gtk::glib::DateTime;
use sqlite::{Connection, Transaction};
use std::{rc::Rc, sync::RwLock};
use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager;
use sqlite::Transaction;
pub struct Database {
connection: Rc<RwLock<Connection>>,
pool: Pool<SqliteConnectionManager>,
profile_id: i64,
}
@ -13,9 +14,9 @@ impl Database {
// Constructors
/// Create new `Self`
pub fn new(connection: &Rc<RwLock<Connection>>, profile_id: i64) -> Self {
pub fn new(pool: &Pool<SqliteConnectionManager>, profile_id: i64) -> Self {
Self {
connection: connection.clone(),
pool: pool.clone(),
profile_id,
}
}
@ -24,9 +25,12 @@ impl Database {
/// Get bookmark records from database with optional filter by `request`
pub fn records(&self, request: Option<&str>, title: Option<&str>) -> Result<Vec<Item>> {
let readable = self.connection.read().unwrap(); // @TODO
let tx = readable.unchecked_transaction()?;
select(&tx, self.profile_id, request, title)
select(
&self.pool.get()?.unchecked_transaction()?,
self.profile_id,
request,
title,
)
}
// Setters
@ -34,8 +38,8 @@ impl Database {
/// Create new bookmark record in database
/// * return last insert ID on success
pub fn add(&self, time: DateTime, request: &str, title: Option<&str>) -> Result<i64> {
let mut writable = self.connection.write().unwrap(); // @TODO
let tx = writable.transaction()?;
let mut connection = self.pool.get()?;
let tx = connection.transaction()?;
let id = insert(&tx, self.profile_id, time, request, title)?;
tx.commit()?;
Ok(id)
@ -43,8 +47,8 @@ impl Database {
/// Delete bookmark record from database
pub fn delete(&self, id: i64) -> Result<usize> {
let mut writable = self.connection.write().unwrap(); // @TODO
let tx = writable.transaction()?;
let mut connection = self.pool.get()?;
let tx = connection.transaction()?;
let usize = delete(&tx, id)?;
tx.commit()?;
Ok(usize)

View file

@ -1,7 +1,8 @@
use anyhow::Result;
use gtk::glib::DateTime;
use sqlite::{Connection, Transaction};
use std::{rc::Rc, sync::RwLock};
use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager;
use sqlite::Transaction;
pub struct Table {
pub id: i64,
@ -11,26 +12,22 @@ pub struct Table {
}
pub struct Database {
pub connection: Rc<RwLock<Connection>>,
pub pool: Pool<SqliteConnectionManager>,
}
impl Database {
// Constructors
/// Create new `Self`
pub fn build(connection: &Rc<RwLock<Connection>>) -> Self {
Self {
connection: connection.clone(),
}
pub fn build(pool: &Pool<SqliteConnectionManager>) -> Self {
Self { pool: pool.clone() }
}
// Getters
/// Get all records
pub fn records(&self) -> Result<Vec<Table>> {
let readable = self.connection.read().unwrap();
let tx = readable.unchecked_transaction()?;
select(&tx)
select(&self.pool.get()?.unchecked_transaction()?)
}
/// Get active profile record if exist
@ -43,8 +40,8 @@ impl Database {
/// Create new record in `Self` database connected
pub fn add(&self, is_active: bool, time: DateTime, name: Option<String>) -> Result<i64> {
let mut writable = self.connection.write().unwrap();
let tx = writable.transaction()?;
let mut connection = self.pool.get()?;
let tx = connection.transaction()?;
if is_active {
for record in select(&tx)? {
update(&tx, record.id, false, record.time, record.name)?;

View file

@ -7,11 +7,10 @@ use database::Database;
use gtk::glib::GString;
use item::{Event, Item};
use memory::Memory;
use sqlite::{Connection, Transaction};
use std::{
rc::Rc,
sync::{Arc, RwLock},
};
use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager;
use sqlite::Transaction;
use std::sync::{Arc, RwLock};
pub struct History {
database: Database, // permanent storage
@ -22,9 +21,9 @@ impl History {
// Constructors
/// Create new `Self`
pub fn build(connection: &Rc<RwLock<Connection>>, profile_id: i64) -> Result<Self> {
pub fn build(database_pool: &Pool<SqliteConnectionManager>, profile_id: i64) -> Result<Self> {
// Init children components
let database = Database::build(connection, profile_id);
let database = Database::build(database_pool, profile_id);
let memory = Arc::new(RwLock::new(Memory::new()));
for item in database.records(None, None)? {

View file

@ -1,11 +1,12 @@
use super::{item::Event, Item};
use anyhow::Result;
use gtk::glib::DateTime;
use sqlite::{Connection, Transaction};
use std::{rc::Rc, sync::RwLock};
use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager;
use sqlite::Transaction;
pub struct Database {
connection: Rc<RwLock<Connection>>,
pool: Pool<SqliteConnectionManager>,
profile_id: i64,
}
@ -13,9 +14,9 @@ impl Database {
// Constructors
/// Create new `Self`
pub fn build(connection: &Rc<RwLock<Connection>>, profile_id: i64) -> Self {
pub fn build(pool: &Pool<SqliteConnectionManager>, profile_id: i64) -> Self {
Self {
connection: connection.clone(),
pool: pool.clone(),
profile_id,
}
}
@ -24,9 +25,12 @@ impl Database {
/// Get history records from database with optional filter by `request`
pub fn records(&self, request: Option<&str>, title: Option<&str>) -> Result<Vec<Item>> {
let readable = self.connection.read().unwrap(); // @TODO
let tx = readable.unchecked_transaction()?;
select(&tx, self.profile_id, request, title)
select(
&self.pool.get()?.unchecked_transaction()?,
self.profile_id,
request,
title,
)
}
// Actions
@ -34,16 +38,16 @@ impl Database {
/// Create new history record in database
/// * return last insert ID on success
pub fn add(&self, item: &Item) -> Result<i64> {
let mut writable = self.connection.write().unwrap(); // @TODO
let tx = writable.transaction()?;
let mut connection = self.pool.get()?;
let tx = connection.transaction()?;
let id = insert(&tx, self.profile_id, item)?;
tx.commit()?;
Ok(id)
}
pub fn update(&self, item: &Item) -> Result<usize> {
let mut writable = self.connection.write().unwrap(); // @TODO
let tx = writable.transaction()?;
let mut connection = self.pool.get()?;
let tx = connection.transaction()?;
let affected = update(&tx, self.profile_id, item)?;
tx.commit()?;
Ok(affected)

View file

@ -10,8 +10,9 @@ use database::Database;
use gtk::glib::DateTime;
use item::Item;
use memory::Memory;
use sqlite::{Connection, Transaction};
use std::{rc::Rc, sync::RwLock};
use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager;
use sqlite::Transaction;
/// Authorization wrapper for Gemini protocol
///
@ -26,10 +27,13 @@ impl Identity {
// Constructors
/// Create new `Self`
pub fn build(connection: &Rc<RwLock<Connection>>, profile_identity_id: i64) -> Result<Self> {
pub fn build(
database_pool: &Pool<SqliteConnectionManager>,
profile_identity_id: i64,
) -> Result<Self> {
// Init components
let auth = Auth::build(connection)?;
let database = Database::build(connection, profile_identity_id);
let auth = Auth::build(database_pool)?;
let database = Database::build(database_pool, profile_identity_id);
let memory = Memory::new();
// Init `Self`

View file

@ -6,24 +6,25 @@ mod memory;
use anyhow::Result;
use database::Database;
use memory::Memory;
use sqlite::{Connection, Transaction};
use std::{rc::Rc, sync::RwLock};
use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager;
use sqlite::Transaction;
/// Auth pair operations
pub struct Auth {
database: Rc<Database>,
memory: Rc<Memory>,
database: Database,
memory: Memory,
}
impl Auth {
// Constructors
/// Create new `Self`
pub fn build(connection: &Rc<RwLock<Connection>>) -> Result<Self> {
pub fn build(database_pool: &Pool<SqliteConnectionManager>) -> Result<Self> {
// Init `Self`
let this = Self {
database: Rc::new(Database::build(connection)),
memory: Rc::new(Memory::new()),
database: Database::build(database_pool),
memory: Memory::new(),
};
// Build initial index

View file

@ -1,6 +1,7 @@
use anyhow::Result;
use sqlite::{Connection, Transaction};
use std::{rc::Rc, sync::RwLock};
use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager;
use sqlite::Transaction;
pub struct Table {
pub id: i64,
@ -10,25 +11,23 @@ pub struct Table {
/// Storage for `profile_identity_id` + `scope` auth pairs
pub struct Database {
connection: Rc<RwLock<Connection>>,
pool: Pool<SqliteConnectionManager>,
}
impl Database {
// Constructors
/// Create new `Self`
pub fn build(connection: &Rc<RwLock<Connection>>) -> Self {
Self {
connection: connection.clone(),
}
pub fn build(pool: &Pool<SqliteConnectionManager>) -> Self {
Self { pool: pool.clone() }
}
// Actions
/// Create new record in database
pub fn add(&self, profile_identity_id: i64, scope: &str) -> Result<i64> {
let mut writable = self.connection.write().unwrap(); // @TODO
let tx = writable.transaction()?;
let mut connection = self.pool.get()?;
let tx = connection.transaction()?;
let id = insert(&tx, profile_identity_id, scope)?;
tx.commit()?;
Ok(id)
@ -36,8 +35,8 @@ impl Database {
/// Delete record with given `id` from database
pub fn delete(&self, id: i64) -> Result<()> {
let mut writable = self.connection.write().unwrap(); // @TODO
let tx = writable.transaction()?;
let mut connection = self.pool.get()?;
let tx = connection.transaction()?;
delete(&tx, id)?;
tx.commit()?;
Ok(())
@ -47,16 +46,15 @@ impl Database {
/// Get records from database match current `profile_id` optionally filtered by `scope`
pub fn records_scope(&self, scope: Option<&str>) -> Result<Vec<Table>> {
let readable = self.connection.read().unwrap(); // @TODO
let tx = readable.unchecked_transaction()?;
select_scope(&tx, scope)
select_scope(&self.pool.get()?.unchecked_transaction()?, scope)
}
/// Get records from database match current `profile_id` optionally filtered by `scope`
pub fn records_ref(&self, profile_identity_id: i64) -> Result<Vec<Table>> {
let readable = self.connection.read().unwrap(); // @TODO
let tx = readable.unchecked_transaction()?;
select_ref(&tx, profile_identity_id)
select_ref(
&self.pool.get()?.unchecked_transaction()?,
profile_identity_id,
)
}
}

View file

@ -1,5 +1,7 @@
use sqlite::{Connection, Error, Transaction};
use std::{rc::Rc, sync::RwLock};
use anyhow::Result;
use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager;
use sqlite::Transaction;
pub struct Table {
pub id: i64,
@ -9,7 +11,7 @@ pub struct Table {
/// Storage for Gemini auth certificates
pub struct Database {
connection: Rc<RwLock<Connection>>,
pool: Pool<SqliteConnectionManager>,
profile_id: i64,
}
@ -17,9 +19,9 @@ impl Database {
// Constructors
/// Create new `Self`
pub fn build(connection: &Rc<RwLock<Connection>>, profile_id: i64) -> Self {
pub fn build(pool: &Pool<SqliteConnectionManager>, profile_id: i64) -> Self {
Self {
connection: connection.clone(),
pool: pool.clone(),
profile_id,
}
}
@ -27,10 +29,10 @@ impl Database {
// Actions
/// Create new record in database
pub fn add(&self, pem: &str) -> Result<i64, Error> {
pub fn add(&self, pem: &str) -> Result<i64> {
// Begin new transaction
let mut writable = self.connection.write().unwrap(); // @TODO
let tx = writable.transaction()?;
let mut connection = self.pool.get()?;
let tx = connection.transaction()?;
// Create new record
insert(&tx, self.profile_id, pem)?;
@ -39,55 +41,45 @@ impl Database {
let id = last_insert_id(&tx);
// Done
match tx.commit() {
Ok(_) => Ok(id),
Err(e) => Err(e),
}
tx.commit()?;
Ok(id)
}
/// Delete record with given `id` from database
pub fn delete(&self, id: i64) -> Result<(), Error> {
pub fn delete(&self, id: i64) -> Result<()> {
// Begin new transaction
let mut writable = self.connection.write().unwrap(); // @TODO
let tx = writable.transaction()?;
let mut connection = self.pool.get()?;
let tx = connection.transaction()?;
// Create new record
delete(&tx, id)?;
// Done
match tx.commit() {
Ok(_) => Ok(()),
Err(e) => Err(e),
}
tx.commit()?;
Ok(())
}
/// Get single record match `id`
pub fn record(&self, id: i64) -> Result<Option<Table>, Error> {
let readable = self.connection.read().unwrap();
let tx = readable.unchecked_transaction()?;
let records = select(&tx, self.profile_id)?; // @TODO single record query
pub fn record(&self, id: i64) -> Result<Option<Table>> {
let records = select(&self.pool.get()?.unchecked_transaction()?, self.profile_id)?; // @TODO single record query
for record in records {
if record.id == id {
return Ok(Some(record));
}
}
Ok(None)
}
/// Get all records match current `profile_id`
pub fn records(&self) -> Result<Vec<Table>, Error> {
let readable = self.connection.read().unwrap(); // @TODO
let tx = readable.unchecked_transaction()?;
select(&tx, self.profile_id)
pub fn records(&self) -> Result<Vec<Table>> {
select(&self.pool.get()?.unchecked_transaction()?, self.profile_id)
}
}
// Low-level DB API
pub fn init(tx: &Transaction) -> Result<usize, Error> {
tx.execute(
pub fn init(tx: &Transaction) -> Result<usize> {
Ok(tx.execute(
"CREATE TABLE IF NOT EXISTS `profile_identity`
(
`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
@ -97,24 +89,24 @@ pub fn init(tx: &Transaction) -> Result<usize, Error> {
FOREIGN KEY (`profile_id`) REFERENCES `profile`(`id`)
)",
[],
)
)?)
}
pub fn insert(tx: &Transaction, profile_id: i64, pem: &str) -> Result<usize, Error> {
tx.execute(
pub fn insert(tx: &Transaction, profile_id: i64, pem: &str) -> Result<usize> {
Ok(tx.execute(
"INSERT INTO `profile_identity` (
`profile_id`,
`pem`
) VALUES (?, ?)",
(profile_id, pem),
)
)?)
}
pub fn delete(tx: &Transaction, id: i64) -> Result<usize, Error> {
tx.execute("DELETE FROM `profile_identity` WHERE `id` = ?", [id])
pub fn delete(tx: &Transaction, id: i64) -> Result<usize> {
Ok(tx.execute("DELETE FROM `profile_identity` WHERE `id` = ?", [id])?)
}
pub fn select(tx: &Transaction, profile_id: i64) -> Result<Vec<Table>, Error> {
pub fn select(tx: &Transaction, profile_id: i64) -> Result<Vec<Table>> {
let mut stmt = tx.prepare(
"SELECT `id`,
`profile_id`,

View file

@ -5,8 +5,9 @@ use anyhow::Result;
use database::Database;
use gtk::glib::Uri;
use memory::Memory;
use sqlite::{Connection, Transaction};
use std::{rc::Rc, sync::RwLock};
use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager;
use sqlite::Transaction;
pub struct Search {
database: Database, // permanent storage
@ -17,8 +18,8 @@ impl Search {
// Constructors
/// Create new `Self`
pub fn build(connection: &Rc<RwLock<Connection>>, profile_id: i64) -> Result<Self> {
let database = Database::init(connection, profile_id)?;
pub fn build(database_pool: &Pool<SqliteConnectionManager>, profile_id: i64) -> Result<Self> {
let database = Database::init(database_pool, profile_id)?;
// Init fast search index
let memory = Memory::init();
// Build initial index

View file

@ -1,6 +1,7 @@
use anyhow::Result;
use sqlite::{Connection, Transaction};
use std::{rc::Rc, sync::RwLock};
use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager;
use sqlite::Transaction;
#[derive(Clone)]
pub struct Row {
@ -11,7 +12,7 @@ pub struct Row {
}
pub struct Database {
connection: Rc<RwLock<Connection>>,
pool: Pool<SqliteConnectionManager>,
profile_id: i64,
}
@ -19,9 +20,9 @@ impl Database {
// Constructors
/// Create new `Self`
pub fn init(connection: &Rc<RwLock<Connection>>, profile_id: i64) -> Result<Self> {
let mut writable = connection.write().unwrap(); // @TODO handle
let tx = writable.transaction()?;
pub fn init(pool: &Pool<SqliteConnectionManager>, profile_id: i64) -> Result<Self> {
let mut connection = pool.get()?;
let tx = connection.transaction()?;
let records = select(&tx, profile_id)?;
@ -31,7 +32,7 @@ impl Database {
}
Ok(Self {
connection: connection.clone(),
pool: pool.clone(),
profile_id,
})
}
@ -40,9 +41,7 @@ impl Database {
/// Get records from database
pub fn records(&self) -> Result<Vec<Row>> {
let readable = self.connection.read().unwrap(); // @TODO handle
let tx = readable.unchecked_transaction()?;
select(&tx, self.profile_id)
select(&self.pool.get()?.unchecked_transaction()?, self.profile_id)
}
// Setters
@ -50,8 +49,8 @@ impl Database {
/// Create new record in database
/// * return last insert ID on success
pub fn add(&self, query: String, is_default: bool) -> Result<i64> {
let mut writable = self.connection.write().unwrap(); // @TODO handle
let tx = writable.transaction()?;
let mut connection = self.pool.get()?;
let tx = connection.transaction()?;
if is_default {
reset(&tx, self.profile_id, !is_default)?;
}
@ -63,8 +62,8 @@ impl Database {
/// Delete record from database
pub fn delete(&self, id: i64) -> Result<()> {
// Begin new transaction
let mut writable = self.connection.write().unwrap(); // @TODO
let tx = writable.transaction()?;
let mut connection = self.pool.get()?;
let tx = connection.transaction()?;
// Delete record by ID
delete(&tx, id)?;
@ -97,8 +96,8 @@ impl Database {
/// Delete record from database
pub fn set_default(&self, id: i64) -> Result<()> {
// Begin new transaction
let mut writable = self.connection.write().unwrap(); // @TODO
let tx = writable.transaction()?;
let mut connection = self.pool.get()?;
let tx = connection.transaction()?;
// Make sure only one default provider in set
reset(&tx, self.profile_id, false)?;