mirror of
https://github.com/kanidm/kanidm.git
synced 2025-05-23 01:13:54 +02:00
Remove r2d2 - sad beep noises (#1766)
This commit is contained in:
parent
f25bd5bb65
commit
a20dd3b113
34
Cargo.lock
generated
34
Cargo.lock
generated
|
@ -2593,8 +2593,6 @@ dependencies = [
|
|||
"lru 0.8.1",
|
||||
"notify-debouncer-full",
|
||||
"profiles",
|
||||
"r2d2",
|
||||
"r2d2_sqlite",
|
||||
"reqwest",
|
||||
"rpassword 7.2.0",
|
||||
"rusqlite",
|
||||
|
@ -2674,8 +2672,6 @@ dependencies = [
|
|||
"openssl",
|
||||
"openssl-sys",
|
||||
"profiles",
|
||||
"r2d2",
|
||||
"r2d2_sqlite",
|
||||
"rand 0.8.5",
|
||||
"regex",
|
||||
"rusqlite",
|
||||
|
@ -3837,27 +3833,6 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r2d2"
|
||||
version = "0.8.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93"
|
||||
dependencies = [
|
||||
"log",
|
||||
"parking_lot",
|
||||
"scheduled-thread-pool",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r2d2_sqlite"
|
||||
version = "0.21.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4f5d0337e99cd5cacd91ffc326c6cc9d8078def459df560c4f9bf9ba4a51034"
|
||||
dependencies = [
|
||||
"r2d2",
|
||||
"rusqlite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
|
@ -4199,15 +4174,6 @@ dependencies = [
|
|||
"windows-sys 0.42.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scheduled-thread-pool"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19"
|
||||
dependencies = [
|
||||
"parking_lot",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scim_proto"
|
||||
version = "0.2.1"
|
||||
|
|
|
@ -111,8 +111,6 @@ proc-macro2 = "1.0.60"
|
|||
profiles = { path = "./libs/profiles" }
|
||||
qrcode = "^0.12.0"
|
||||
quote = "1"
|
||||
r2d2 = "^0.8.9"
|
||||
r2d2_sqlite = "^0.21.0"
|
||||
rand = "^0.8.5"
|
||||
regex = "1.8.4"
|
||||
reqwest = { version = "0.11.18", default-features = false, features=["cookies", "json", "gzip", "native-tls"] }
|
||||
|
|
|
@ -74,6 +74,7 @@ pub enum CryptoError {
|
|||
Argon2Parameters,
|
||||
}
|
||||
|
||||
#[allow(clippy::from_over_into)]
|
||||
impl Into<OperationError> for CryptoError {
|
||||
fn into(self) -> OperationError {
|
||||
OperationError::CryptographyError
|
||||
|
@ -301,7 +302,7 @@ impl CryptoPolicy {
|
|||
// here though, just to give a little window under that for adjustment.
|
||||
//
|
||||
// Similar, once we hit t=4 we just need to have max ram.
|
||||
let m_adjust = (t_cost.checked_sub(ARGON2_MIN_T_COST).unwrap_or(0)
|
||||
let m_adjust = (t_cost.saturating_sub(ARGON2_MIN_T_COST)
|
||||
* ARGON2_MIN_RAM_KIB)
|
||||
+ ARGON2_MAX_RAM_KIB;
|
||||
m_cost = if m_adjust > ARGON2_MAX_RAM_KIB {
|
||||
|
@ -852,10 +853,10 @@ impl Password {
|
|||
self.verify_ctx(cleartext, None)
|
||||
}
|
||||
|
||||
pub fn verify_ctx<'a>(
|
||||
pub fn verify_ctx(
|
||||
&self,
|
||||
cleartext: &str,
|
||||
tpm: Option<(&'a mut TpmContext, TpmHandle)>,
|
||||
tpm: Option<(&mut TpmContext, TpmHandle)>,
|
||||
) -> Result<bool, CryptoError> {
|
||||
match (&self.material, tpm) {
|
||||
(
|
||||
|
@ -1234,6 +1235,7 @@ fn do_tpm_hmac(
|
|||
}
|
||||
|
||||
#[cfg(not(feature = "tpm"))]
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
fn do_tpm_hmac(
|
||||
_data: Vec<u8>,
|
||||
_ctx: &mut TpmContext,
|
||||
|
|
|
@ -253,6 +253,7 @@ pub enum OperationError {
|
|||
ReplInvalidRUVState,
|
||||
ReplDomainLevelUnsatisfiable,
|
||||
ReplDomainUuidMismatch,
|
||||
TransactionAlreadyCommitted,
|
||||
}
|
||||
|
||||
impl PartialEq for OperationError {
|
||||
|
|
|
@ -42,8 +42,6 @@ num_enum.workspace = true
|
|||
# into the build.rs for legacy feature checks.
|
||||
openssl-sys.workspace = true
|
||||
openssl.workspace = true
|
||||
r2d2.workspace = true
|
||||
r2d2_sqlite.workspace = true
|
||||
rand.workspace = true
|
||||
regex = { workspace = true, features = ["std", "perf", "perf-inline", "unicode", "unicode-gencat"] }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use std::collections::VecDeque;
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
use std::time::Duration;
|
||||
|
||||
// use crate::valueset;
|
||||
use hashbrown::HashMap;
|
||||
use idlset::v2::IDLBitRange;
|
||||
use kanidm_proto::v1::{ConsistencyError, OperationError};
|
||||
use r2d2::Pool;
|
||||
use r2d2_sqlite::SqliteConnectionManager;
|
||||
use rusqlite::{Connection, OpenFlags, OptionalExtension};
|
||||
use uuid::Uuid;
|
||||
|
||||
|
@ -34,6 +34,8 @@ fn serde_json_error(e: serde_json::Error) -> OperationError {
|
|||
OperationError::SerdeJsonError
|
||||
}
|
||||
|
||||
type ConnPool = Arc<Mutex<VecDeque<Connection>>>;
|
||||
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum FsType {
|
||||
|
@ -98,26 +100,26 @@ impl TryFrom<IdRawEntry> for IdSqliteEntry {
|
|||
|
||||
#[derive(Clone)]
|
||||
pub struct IdlSqlite {
|
||||
pool: Pool<SqliteConnectionManager>,
|
||||
pool: ConnPool,
|
||||
db_name: &'static str,
|
||||
}
|
||||
|
||||
pub struct IdlSqliteReadTransaction {
|
||||
committed: bool,
|
||||
conn: r2d2::PooledConnection<SqliteConnectionManager>,
|
||||
pool: ConnPool,
|
||||
conn: Option<Connection>,
|
||||
db_name: &'static str,
|
||||
}
|
||||
|
||||
pub struct IdlSqliteWriteTransaction {
|
||||
committed: bool,
|
||||
conn: r2d2::PooledConnection<SqliteConnectionManager>,
|
||||
pool: ConnPool,
|
||||
conn: Option<Connection>,
|
||||
db_name: &'static str,
|
||||
}
|
||||
|
||||
pub trait IdlSqliteTransaction {
|
||||
fn get_db_name(&self) -> &str;
|
||||
|
||||
fn get_conn(&self) -> &r2d2::PooledConnection<r2d2_sqlite::SqliteConnectionManager>;
|
||||
fn get_conn(&self) -> Result<&Connection, OperationError>;
|
||||
|
||||
fn get_identry(&self, idl: &IdList) -> Result<Vec<Arc<EntrySealedCommitted>>, OperationError> {
|
||||
self.get_identry_raw(idl)?
|
||||
|
@ -131,7 +133,7 @@ pub trait IdlSqliteTransaction {
|
|||
match idl {
|
||||
IdList::AllIds => {
|
||||
let mut stmt = self
|
||||
.get_conn()
|
||||
.get_conn()?
|
||||
.prepare(&format!(
|
||||
"SELECT id, data FROM {}.id2entry",
|
||||
self.get_db_name()
|
||||
|
@ -156,7 +158,7 @@ pub trait IdlSqliteTransaction {
|
|||
}
|
||||
IdList::Partial(idli) | IdList::PartialThreshold(idli) | IdList::Indexed(idli) => {
|
||||
let mut stmt = self
|
||||
.get_conn()
|
||||
.get_conn()?
|
||||
.prepare(&format!(
|
||||
"SELECT id, data FROM {}.id2entry WHERE id = :idl",
|
||||
self.get_db_name()
|
||||
|
@ -203,7 +205,7 @@ pub trait IdlSqliteTransaction {
|
|||
|
||||
fn exists_table(&self, tname: &str) -> Result<bool, OperationError> {
|
||||
let mut stmt = self
|
||||
.get_conn()
|
||||
.get_conn()?
|
||||
.prepare(&format!(
|
||||
"SELECT COUNT(name) from {}.sqlite_master where name = :tname",
|
||||
self.get_db_name()
|
||||
|
@ -247,7 +249,7 @@ pub trait IdlSqliteTransaction {
|
|||
attr
|
||||
);
|
||||
let mut stmt = self
|
||||
.get_conn()
|
||||
.get_conn()?
|
||||
.prepare(query.as_str())
|
||||
.map_err(sqlite_error)?;
|
||||
let idl_raw: Option<Vec<u8>> = stmt
|
||||
|
@ -274,7 +276,7 @@ pub trait IdlSqliteTransaction {
|
|||
fn name2uuid(&mut self, name: &str) -> Result<Option<Uuid>, OperationError> {
|
||||
// The table exists - lets now get the actual index itself.
|
||||
let mut stmt = self
|
||||
.get_conn()
|
||||
.get_conn()?
|
||||
.prepare(&format!(
|
||||
"SELECT uuid FROM {}.idx_name2uuid WHERE name = :name",
|
||||
self.get_db_name()
|
||||
|
@ -294,7 +296,7 @@ pub trait IdlSqliteTransaction {
|
|||
fn externalid2uuid(&mut self, name: &str) -> Result<Option<Uuid>, OperationError> {
|
||||
// The table exists - lets now get the actual index itself.
|
||||
let mut stmt = self
|
||||
.get_conn()
|
||||
.get_conn()?
|
||||
.prepare(&format!(
|
||||
"SELECT uuid FROM {}.idx_externalid2uuid WHERE eid = :eid",
|
||||
self.get_db_name()
|
||||
|
@ -315,7 +317,7 @@ pub trait IdlSqliteTransaction {
|
|||
let uuids = uuid.as_hyphenated().to_string();
|
||||
// The table exists - lets now get the actual index itself.
|
||||
let mut stmt = self
|
||||
.get_conn()
|
||||
.get_conn()?
|
||||
.prepare(&format!(
|
||||
"SELECT spn FROM {}.idx_uuid2spn WHERE uuid = :uuid",
|
||||
self.get_db_name()
|
||||
|
@ -344,7 +346,7 @@ pub trait IdlSqliteTransaction {
|
|||
let uuids = uuid.as_hyphenated().to_string();
|
||||
// The table exists - lets now get the actual index itself.
|
||||
let mut stmt = self
|
||||
.get_conn()
|
||||
.get_conn()?
|
||||
.prepare("SELECT rdn FROM idx_uuid2rdn WHERE uuid = :uuid")
|
||||
.map_err(sqlite_error)?;
|
||||
let rdn: Option<String> = stmt
|
||||
|
@ -359,7 +361,7 @@ pub trait IdlSqliteTransaction {
|
|||
fn get_db_s_uuid(&self) -> Result<Option<Uuid>, OperationError> {
|
||||
// Try to get a value.
|
||||
let data: Option<Vec<u8>> = self
|
||||
.get_conn()
|
||||
.get_conn()?
|
||||
.query_row("SELECT data FROM db_sid WHERE id = 2", [], |row| row.get(0))
|
||||
.optional()
|
||||
// this whole map call is useless
|
||||
|
@ -390,7 +392,7 @@ pub trait IdlSqliteTransaction {
|
|||
fn get_db_d_uuid(&self) -> Result<Option<Uuid>, OperationError> {
|
||||
// Try to get a value.
|
||||
let data: Option<Vec<u8>> = self
|
||||
.get_conn()
|
||||
.get_conn()?
|
||||
.query_row("SELECT data FROM db_did WHERE id = 2", [], |row| row.get(0))
|
||||
.optional()
|
||||
// this whole map call is useless
|
||||
|
@ -421,7 +423,7 @@ pub trait IdlSqliteTransaction {
|
|||
fn get_db_ts_max(&self) -> Result<Option<Duration>, OperationError> {
|
||||
// Try to get a value.
|
||||
let data: Option<Vec<u8>> = self
|
||||
.get_conn()
|
||||
.get_conn()?
|
||||
.query_row("SELECT data FROM db_op_ts WHERE id = 1", [], |row| {
|
||||
row.get(0)
|
||||
})
|
||||
|
@ -453,7 +455,7 @@ pub trait IdlSqliteTransaction {
|
|||
#[instrument(level = "debug", name = "idl_sqlite::get_allids", skip_all)]
|
||||
fn get_allids(&self) -> Result<IDLBitRange, OperationError> {
|
||||
let mut stmt = self
|
||||
.get_conn()
|
||||
.get_conn()?
|
||||
.prepare("SELECT id FROM id2entry")
|
||||
.map_err(sqlite_error)?;
|
||||
let res = stmt.query_map([], |row| row.get(0)).map_err(sqlite_error)?;
|
||||
|
@ -476,7 +478,7 @@ pub trait IdlSqliteTransaction {
|
|||
|
||||
fn list_idxs(&self) -> Result<Vec<String>, OperationError> {
|
||||
let mut stmt = self
|
||||
.get_conn()
|
||||
.get_conn()?
|
||||
.prepare("SELECT name from sqlite_master where type='table' and name GLOB 'idx_*'")
|
||||
.map_err(sqlite_error)?;
|
||||
let idx_table_iter = stmt.query_map([], |row| row.get(0)).map_err(sqlite_error)?;
|
||||
|
@ -513,7 +515,7 @@ pub trait IdlSqliteTransaction {
|
|||
|
||||
let query = format!("SELECT key, idl FROM {index_name}");
|
||||
let mut stmt = self
|
||||
.get_conn()
|
||||
.get_conn()?
|
||||
.prepare(query.as_str())
|
||||
.map_err(sqlite_error)?;
|
||||
|
||||
|
@ -539,7 +541,12 @@ pub trait IdlSqliteTransaction {
|
|||
// This allow is critical as it resolves a life time issue in stmt.
|
||||
#[allow(clippy::let_and_return)]
|
||||
fn verify(&self) -> Vec<Result<(), ConsistencyError>> {
|
||||
let mut stmt = match self.get_conn().prepare("PRAGMA integrity_check;") {
|
||||
let conn = match self.get_conn() {
|
||||
Ok(conn) => conn,
|
||||
Err(_) => return vec![Err(ConsistencyError::SqliteIntegrityFailure)],
|
||||
};
|
||||
|
||||
let mut stmt = match conn.prepare("PRAGMA integrity_check;") {
|
||||
Ok(r) => r,
|
||||
Err(_) => return vec![Err(ConsistencyError::SqliteIntegrityFailure)],
|
||||
};
|
||||
|
@ -567,31 +574,35 @@ impl IdlSqliteTransaction for IdlSqliteReadTransaction {
|
|||
self.db_name
|
||||
}
|
||||
|
||||
fn get_conn(&self) -> &r2d2::PooledConnection<r2d2_sqlite::SqliteConnectionManager> {
|
||||
&self.conn
|
||||
fn get_conn(&self) -> Result<&Connection, OperationError> {
|
||||
self.conn
|
||||
.as_ref()
|
||||
.ok_or(OperationError::TransactionAlreadyCommitted)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for IdlSqliteReadTransaction {
|
||||
// Abort - so far this has proven reliable to use drop here.
|
||||
fn drop(&mut self) {
|
||||
if !self.committed {
|
||||
let mut dropping = None;
|
||||
std::mem::swap(&mut dropping, &mut self.conn);
|
||||
|
||||
if let Some(conn) = dropping {
|
||||
#[allow(clippy::expect_used)]
|
||||
self.conn
|
||||
.execute("ROLLBACK TRANSACTION", [])
|
||||
// We can't do this without expect.
|
||||
// We may need to change how we do transactions to not rely on drop if
|
||||
// it becomes and issue :(
|
||||
conn.execute("ROLLBACK TRANSACTION", [])
|
||||
.expect("Unable to rollback transaction! Can not proceed!!!");
|
||||
|
||||
#[allow(clippy::expect_used)]
|
||||
self.pool
|
||||
.lock()
|
||||
.expect("Unable to access db pool")
|
||||
.push_back(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IdlSqliteReadTransaction {
|
||||
pub fn new(
|
||||
conn: r2d2::PooledConnection<SqliteConnectionManager>,
|
||||
db_name: &'static str,
|
||||
) -> Self {
|
||||
pub fn new(pool: ConnPool, conn: Connection, db_name: &'static str) -> Self {
|
||||
// Start the transaction
|
||||
//
|
||||
// I'm happy for this to be an expect, because this is a huge failure
|
||||
|
@ -603,8 +614,8 @@ impl IdlSqliteReadTransaction {
|
|||
conn.execute("BEGIN DEFERRED TRANSACTION", [])
|
||||
.expect("Unable to begin transaction!");
|
||||
IdlSqliteReadTransaction {
|
||||
committed: false,
|
||||
conn,
|
||||
pool,
|
||||
conn: Some(conn),
|
||||
db_name,
|
||||
}
|
||||
}
|
||||
|
@ -615,56 +626,77 @@ impl IdlSqliteTransaction for IdlSqliteWriteTransaction {
|
|||
self.db_name
|
||||
}
|
||||
|
||||
fn get_conn(&self) -> &r2d2::PooledConnection<r2d2_sqlite::SqliteConnectionManager> {
|
||||
&self.conn
|
||||
fn get_conn(&self) -> Result<&Connection, OperationError> {
|
||||
self.conn
|
||||
.as_ref()
|
||||
.ok_or(OperationError::TransactionAlreadyCommitted)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for IdlSqliteWriteTransaction {
|
||||
// Abort
|
||||
fn drop(&mut self) {
|
||||
if !self.committed {
|
||||
let mut dropping = None;
|
||||
std::mem::swap(&mut dropping, &mut self.conn);
|
||||
|
||||
if let Some(conn) = dropping {
|
||||
#[allow(clippy::expect_used)]
|
||||
self.conn
|
||||
.execute("ROLLBACK TRANSACTION", [])
|
||||
conn.execute("ROLLBACK TRANSACTION", [])
|
||||
.expect("Unable to rollback transaction! Can not proceed!!!");
|
||||
|
||||
#[allow(clippy::expect_used)]
|
||||
self.pool
|
||||
.lock()
|
||||
.expect("Unable to access db pool")
|
||||
.push_back(conn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IdlSqliteWriteTransaction {
|
||||
pub fn new(
|
||||
conn: r2d2::PooledConnection<SqliteConnectionManager>,
|
||||
db_name: &'static str,
|
||||
) -> Self {
|
||||
pub fn new(pool: ConnPool, conn: Connection, db_name: &'static str) -> Self {
|
||||
// Start the transaction
|
||||
#[allow(clippy::expect_used)]
|
||||
conn.execute("BEGIN EXCLUSIVE TRANSACTION", [])
|
||||
.expect("Unable to begin transaction!");
|
||||
IdlSqliteWriteTransaction {
|
||||
committed: false,
|
||||
conn,
|
||||
pool,
|
||||
conn: Some(conn),
|
||||
db_name,
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", name = "idl_sqlite::commit", skip_all)]
|
||||
pub fn commit(mut self) -> Result<(), OperationError> {
|
||||
assert!(!self.committed);
|
||||
self.committed = true;
|
||||
debug_assert!(self.conn.is_some());
|
||||
|
||||
self.conn
|
||||
.execute("COMMIT TRANSACTION", [])
|
||||
.map(|_| ())
|
||||
.map_err(|e| {
|
||||
admin_error!(?e, "CRITICAL: failed to commit sqlite txn");
|
||||
OperationError::BackendEngine
|
||||
})
|
||||
let mut dropping = None;
|
||||
std::mem::swap(&mut dropping, &mut self.conn);
|
||||
|
||||
if let Some(conn) = dropping {
|
||||
#[allow(clippy::expect_used)]
|
||||
conn.execute("COMMIT TRANSACTION", [])
|
||||
.map(|_| ())
|
||||
.map_err(|e| {
|
||||
admin_error!(?e, "CRITICAL: failed to commit sqlite txn");
|
||||
OperationError::BackendEngine
|
||||
})?;
|
||||
|
||||
#[allow(clippy::expect_used)]
|
||||
self.pool
|
||||
.lock()
|
||||
.expect("Unable to access db pool")
|
||||
.push_back(conn);
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
Err(OperationError::TransactionAlreadyCommitted)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_id2entry_max_id(&self) -> Result<u64, OperationError> {
|
||||
let mut stmt = self
|
||||
.conn
|
||||
.get_conn()?
|
||||
.prepare(&format!(
|
||||
"SELECT MAX(id) as id_max FROM {}.id2entry",
|
||||
self.get_db_name(),
|
||||
|
@ -686,32 +718,6 @@ impl IdlSqliteWriteTransaction {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn write_identries<'b, I>(
|
||||
&'b self,
|
||||
entries: I,
|
||||
) -> Result<(), OperationError>
|
||||
where
|
||||
I: Iterator<Item = &'b Entry<EntrySealed, EntryCommitted>>,
|
||||
{
|
||||
lperf_trace_segment!(au, "be::idl_sqlite::write_identries", || {
|
||||
let raw_entries: Result<Vec<_>, _> = entries
|
||||
.map(|e| {
|
||||
let dbe = e.to_dbentry();
|
||||
let data =
|
||||
serde_cbor::to_vec(&dbe).map_err(|_| OperationError::SerdeCborError)?;
|
||||
|
||||
Ok(IdRawEntry {
|
||||
id: e.get_id(),
|
||||
data,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
self.write_identries_raw(au, raw_entries?.into_iter())
|
||||
})
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn write_identry(
|
||||
&self,
|
||||
entry: &Entry<EntrySealed, EntryCommitted>,
|
||||
|
@ -732,7 +738,7 @@ impl IdlSqliteWriteTransaction {
|
|||
I: Iterator<Item = IdRawEntry>,
|
||||
{
|
||||
let mut stmt = self
|
||||
.conn
|
||||
.get_conn()?
|
||||
.prepare(&format!(
|
||||
"INSERT OR REPLACE INTO {}.id2entry (id, data) VALUES(:id, :data)",
|
||||
self.get_db_name()
|
||||
|
@ -752,46 +758,9 @@ impl IdlSqliteWriteTransaction {
|
|||
})
|
||||
}
|
||||
|
||||
/*
|
||||
pub fn delete_identries<I>(&self, mut idl: I) -> Result<(), OperationError>
|
||||
where
|
||||
I: Iterator<Item = u64>,
|
||||
{
|
||||
lperf_trace_segment!(au, "be::idl_sqlite::delete_identries", || {
|
||||
let mut stmt = self
|
||||
.conn
|
||||
.prepare("DELETE FROM id2entry WHERE id = :id")
|
||||
.map_err(|e| {
|
||||
ladmin_error!(au, "SQLite Error {:?}", e);
|
||||
OperationError::SqliteError
|
||||
})?;
|
||||
|
||||
idl.try_for_each(|id| {
|
||||
let iid: i64 = id
|
||||
.try_into()
|
||||
.map_err(|_| OperationError::InvalidEntryId)
|
||||
.and_then(|i| {
|
||||
if i > 0 {
|
||||
Ok(i)
|
||||
} else {
|
||||
Err(OperationError::InvalidEntryId)
|
||||
}
|
||||
})?;
|
||||
|
||||
debug_assert!(iid > 0);
|
||||
|
||||
stmt.execute(&[&iid]).map(|_| ()).map_err(|e| {
|
||||
ladmin_error!(au, "SQLite Error {:?}", e);
|
||||
OperationError::SqliteError
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn delete_identry(&self, id: u64) -> Result<(), OperationError> {
|
||||
let mut stmt = self
|
||||
.conn
|
||||
.get_conn()?
|
||||
.prepare(&format!(
|
||||
"DELETE FROM {}.id2entry WHERE id = :id",
|
||||
self.get_db_name()
|
||||
|
@ -831,7 +800,7 @@ impl IdlSqliteWriteTransaction {
|
|||
attr
|
||||
);
|
||||
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.prepare(query.as_str())
|
||||
.and_then(|mut stmt| stmt.execute(&[(":key", &idx_key)]))
|
||||
.map_err(sqlite_error)
|
||||
|
@ -847,7 +816,7 @@ impl IdlSqliteWriteTransaction {
|
|||
attr
|
||||
);
|
||||
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.prepare(query.as_str())
|
||||
.and_then(|mut stmt| {
|
||||
stmt.execute(named_params! {
|
||||
|
@ -862,7 +831,7 @@ impl IdlSqliteWriteTransaction {
|
|||
}
|
||||
|
||||
pub fn create_name2uuid(&self) -> Result<(), OperationError> {
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.execute(
|
||||
&format!("CREATE TABLE IF NOT EXISTS {}.idx_name2uuid (name TEXT PRIMARY KEY, uuid TEXT)", self.get_db_name()),
|
||||
[],
|
||||
|
@ -874,7 +843,7 @@ impl IdlSqliteWriteTransaction {
|
|||
pub fn write_name2uuid_add(&self, name: &str, uuid: Uuid) -> Result<(), OperationError> {
|
||||
let uuids = uuid.as_hyphenated().to_string();
|
||||
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.prepare(&format!(
|
||||
"INSERT OR REPLACE INTO {}.idx_name2uuid (name, uuid) VALUES(:name, :uuid)",
|
||||
self.get_db_name()
|
||||
|
@ -890,7 +859,7 @@ impl IdlSqliteWriteTransaction {
|
|||
}
|
||||
|
||||
pub fn write_name2uuid_rem(&self, name: &str) -> Result<(), OperationError> {
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.prepare(&format!(
|
||||
"DELETE FROM {}.idx_name2uuid WHERE name = :name",
|
||||
self.get_db_name()
|
||||
|
@ -901,7 +870,7 @@ impl IdlSqliteWriteTransaction {
|
|||
}
|
||||
|
||||
pub fn create_externalid2uuid(&self) -> Result<(), OperationError> {
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.execute(
|
||||
&format!("CREATE TABLE IF NOT EXISTS {}.idx_externalid2uuid (eid TEXT PRIMARY KEY, uuid TEXT)", self.get_db_name()),
|
||||
[],
|
||||
|
@ -913,7 +882,7 @@ impl IdlSqliteWriteTransaction {
|
|||
pub fn write_externalid2uuid_add(&self, name: &str, uuid: Uuid) -> Result<(), OperationError> {
|
||||
let uuids = uuid.as_hyphenated().to_string();
|
||||
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.prepare(&format!(
|
||||
"INSERT OR REPLACE INTO {}.idx_externalid2uuid (eid, uuid) VALUES(:eid, :uuid)",
|
||||
self.get_db_name()
|
||||
|
@ -929,7 +898,7 @@ impl IdlSqliteWriteTransaction {
|
|||
}
|
||||
|
||||
pub fn write_externalid2uuid_rem(&self, name: &str) -> Result<(), OperationError> {
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.prepare(&format!(
|
||||
"DELETE FROM {}.idx_externalid2uuid WHERE eid = :eid",
|
||||
self.get_db_name()
|
||||
|
@ -940,7 +909,7 @@ impl IdlSqliteWriteTransaction {
|
|||
}
|
||||
|
||||
pub fn create_uuid2spn(&self) -> Result<(), OperationError> {
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.execute(
|
||||
&format!(
|
||||
"CREATE TABLE IF NOT EXISTS {}.idx_uuid2spn (uuid TEXT PRIMARY KEY, spn BLOB)",
|
||||
|
@ -983,7 +952,7 @@ impl IdlSqliteWriteTransaction {
|
|||
Some(k) => {
|
||||
let dbv1: DbIdentSpn = k.to_db_ident_spn();
|
||||
let data = serde_json::to_vec(&dbv1).map_err(serde_json_error)?;
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.prepare(&format!(
|
||||
"INSERT OR REPLACE INTO {}.idx_uuid2spn (uuid, spn) VALUES(:uuid, :spn)",
|
||||
self.get_db_name()
|
||||
|
@ -998,7 +967,7 @@ impl IdlSqliteWriteTransaction {
|
|||
.map_err(sqlite_error)
|
||||
}
|
||||
None => self
|
||||
.conn
|
||||
.get_conn()?
|
||||
.prepare(&format!(
|
||||
"DELETE FROM {}.idx_uuid2spn WHERE uuid = :uuid",
|
||||
self.get_db_name()
|
||||
|
@ -1010,7 +979,7 @@ impl IdlSqliteWriteTransaction {
|
|||
}
|
||||
|
||||
pub fn create_uuid2rdn(&self) -> Result<(), OperationError> {
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.execute(
|
||||
&format!(
|
||||
"CREATE TABLE IF NOT EXISTS {}.idx_uuid2rdn (uuid TEXT PRIMARY KEY, rdn TEXT)",
|
||||
|
@ -1026,7 +995,7 @@ impl IdlSqliteWriteTransaction {
|
|||
let uuids = uuid.as_hyphenated().to_string();
|
||||
match k {
|
||||
Some(k) => self
|
||||
.conn
|
||||
.get_conn()?
|
||||
.prepare(&format!(
|
||||
"INSERT OR REPLACE INTO {}.idx_uuid2rdn (uuid, rdn) VALUES(:uuid, :rdn)",
|
||||
self.get_db_name()
|
||||
|
@ -1035,7 +1004,7 @@ impl IdlSqliteWriteTransaction {
|
|||
.map(|_| ())
|
||||
.map_err(sqlite_error),
|
||||
None => self
|
||||
.conn
|
||||
.get_conn()?
|
||||
.prepare(&format!(
|
||||
"DELETE FROM {}.idx_uuid2rdn WHERE uuid = :uuid",
|
||||
self.get_db_name()
|
||||
|
@ -1059,7 +1028,7 @@ impl IdlSqliteWriteTransaction {
|
|||
);
|
||||
trace!(idx = %idx_stmt, "creating index");
|
||||
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.execute(idx_stmt.as_str(), [])
|
||||
.map(|_| ())
|
||||
.map_err(sqlite_error)
|
||||
|
@ -1070,7 +1039,7 @@ impl IdlSqliteWriteTransaction {
|
|||
|
||||
idx_table_list.iter().try_for_each(|idx_table| {
|
||||
trace!(table = ?idx_table, "removing idx_table");
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.prepare(format!("DROP TABLE {}.{}", self.get_db_name(), idx_table).as_str())
|
||||
.and_then(|mut stmt| stmt.execute([]).map(|_| ()))
|
||||
.map_err(sqlite_error)
|
||||
|
@ -1081,7 +1050,7 @@ impl IdlSqliteWriteTransaction {
|
|||
&self,
|
||||
slopes: &HashMap<IdxKey, IdxSlope>,
|
||||
) -> Result<(), OperationError> {
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.execute(
|
||||
&format!(
|
||||
"CREATE TABLE IF NOT EXISTS {}.idxslope_analysis (
|
||||
|
@ -1096,7 +1065,7 @@ impl IdlSqliteWriteTransaction {
|
|||
.map_err(sqlite_error)?;
|
||||
|
||||
// Remove any data if it exists.
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.execute(
|
||||
&format!("DELETE FROM {}.idxslope_analysis", self.get_db_name()),
|
||||
[],
|
||||
|
@ -1106,7 +1075,7 @@ impl IdlSqliteWriteTransaction {
|
|||
|
||||
slopes.iter().try_for_each(|(k, v)| {
|
||||
let key = format!("idx_{}_{}", k.itype.as_idx_str(), k.attr);
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.execute(
|
||||
&format!("INSERT OR REPLACE INTO {}.idxslope_analysis (id, slope) VALUES(:id, :slope)", self.get_db_name()),
|
||||
named_params! {
|
||||
|
@ -1138,7 +1107,7 @@ impl IdlSqliteWriteTransaction {
|
|||
let key = format!("idx_{}_{}", ikey.itype.as_idx_str(), ikey.attr);
|
||||
|
||||
let mut stmt = self
|
||||
.get_conn()
|
||||
.get_conn()?
|
||||
.prepare(&format!(
|
||||
"SELECT slope FROM {}.idxslope_analysis WHERE id = :id",
|
||||
self.get_db_name()
|
||||
|
@ -1156,7 +1125,7 @@ impl IdlSqliteWriteTransaction {
|
|||
}
|
||||
|
||||
pub unsafe fn purge_id2entry(&self) -> Result<(), OperationError> {
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.execute(&format!("DELETE FROM {}.id2entry", self.get_db_name()), [])
|
||||
.map(|_| ())
|
||||
.map_err(sqlite_error)
|
||||
|
@ -1169,7 +1138,7 @@ impl IdlSqliteWriteTransaction {
|
|||
OperationError::SerdeJsonError
|
||||
})?;
|
||||
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.execute(
|
||||
&format!(
|
||||
"INSERT OR REPLACE INTO {}.db_sid (id, data) VALUES(:id, :sid)",
|
||||
|
@ -1195,7 +1164,7 @@ impl IdlSqliteWriteTransaction {
|
|||
OperationError::SerdeJsonError
|
||||
})?;
|
||||
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.execute(
|
||||
&format!(
|
||||
"INSERT OR REPLACE INTO {}.db_did (id, data) VALUES(:id, :did)",
|
||||
|
@ -1221,7 +1190,7 @@ impl IdlSqliteWriteTransaction {
|
|||
OperationError::SerdeJsonError
|
||||
})?;
|
||||
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.execute(
|
||||
&format!(
|
||||
"INSERT OR REPLACE INTO {}.db_op_ts (id, data) VALUES(:id, :did)",
|
||||
|
@ -1243,7 +1212,9 @@ impl IdlSqliteWriteTransaction {
|
|||
// ===== inner helpers =====
|
||||
// Some of these are not self due to use in new()
|
||||
fn get_db_version_key(&self, key: &str) -> i64 {
|
||||
self.conn
|
||||
#[allow(clippy::expect_used)]
|
||||
self.get_conn()
|
||||
.expect("Unable to access transaction connection")
|
||||
.query_row(
|
||||
&format!(
|
||||
"SELECT version FROM {}.db_version WHERE id = :id",
|
||||
|
@ -1258,8 +1229,8 @@ impl IdlSqliteWriteTransaction {
|
|||
})
|
||||
}
|
||||
|
||||
fn set_db_version_key(&self, key: &str, v: i64) -> Result<(), rusqlite::Error> {
|
||||
self.conn
|
||||
fn set_db_version_key(&self, key: &str, v: i64) -> Result<(), OperationError> {
|
||||
self.get_conn()?
|
||||
.execute(
|
||||
&format!(
|
||||
"INSERT OR REPLACE INTO {}.db_version (id, version) VALUES(:id, :dbv_id2entry)",
|
||||
|
@ -1271,6 +1242,11 @@ impl IdlSqliteWriteTransaction {
|
|||
},
|
||||
)
|
||||
.map(|_| ())
|
||||
.map_err(|e| {
|
||||
admin_error!(immediate = true, ?e, "CRITICAL: rusqlite error");
|
||||
eprintln!("CRITICAL: rusqlite error {e:?}");
|
||||
OperationError::SqliteError
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn get_db_index_version(&self) -> i64 {
|
||||
|
@ -1278,20 +1254,17 @@ impl IdlSqliteWriteTransaction {
|
|||
}
|
||||
|
||||
pub(crate) fn set_db_index_version(&self, v: i64) -> Result<(), OperationError> {
|
||||
self.set_db_version_key(DBV_INDEXV, v).map_err(|e| {
|
||||
admin_error!(immediate = true, ?e, "CRITICAL: rusqlite error");
|
||||
eprintln!("CRITICAL: rusqlite error {e:?}");
|
||||
OperationError::SqliteError
|
||||
})
|
||||
self.set_db_version_key(DBV_INDEXV, v)
|
||||
}
|
||||
|
||||
pub fn setup(&self) -> Result<(), OperationError> {
|
||||
// If the db_name is NOT main, we MAY need to create it as we are in
|
||||
// a test!
|
||||
trace!(db_name = %self.get_db_name(), "setup");
|
||||
if self.get_db_name() != "main" {
|
||||
warn!("Using non-default db-name - this database content WILL be lost!");
|
||||
// we need to attach the DB!
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.execute(&format!("ATTACH DATABASE '' AS {}", self.get_db_name()), [])
|
||||
.map_err(sqlite_error)?;
|
||||
};
|
||||
|
@ -1308,7 +1281,7 @@ impl IdlSqliteWriteTransaction {
|
|||
// rolled back individually, by upgraded in isolation, and more
|
||||
//
|
||||
// NEVER CHANGE THIS DEFINITION.
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.execute(
|
||||
&format!(
|
||||
"CREATE TABLE IF NOT EXISTS {}.db_version (
|
||||
|
@ -1325,10 +1298,12 @@ impl IdlSqliteWriteTransaction {
|
|||
// If the table is empty, populate the versions as 0.
|
||||
let mut dbv_id2entry = self.get_db_version_key(DBV_ID2ENTRY);
|
||||
|
||||
trace!(%dbv_id2entry);
|
||||
|
||||
// Check db_version here.
|
||||
// * if 0 -> create v1.
|
||||
if dbv_id2entry == 0 {
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.execute(
|
||||
&format!(
|
||||
"CREATE TABLE IF NOT EXISTS {}.id2entry (
|
||||
|
@ -1340,28 +1315,29 @@ impl IdlSqliteWriteTransaction {
|
|||
),
|
||||
[],
|
||||
)
|
||||
.and_then(|_| {
|
||||
self.conn.execute(
|
||||
&format!(
|
||||
"CREATE TABLE IF NOT EXISTS {}.db_sid (
|
||||
id INTEGER PRIMARY KEY ASC,
|
||||
data BLOB NOT NULL
|
||||
.map_err(sqlite_error)?;
|
||||
|
||||
self.get_conn()?
|
||||
.execute(
|
||||
&format!(
|
||||
"CREATE TABLE IF NOT EXISTS {}.db_sid (
|
||||
id INTEGER PRIMARY KEY ASC,
|
||||
data BLOB NOT NULL
|
||||
)
|
||||
",
|
||||
self.get_db_name()
|
||||
),
|
||||
[],
|
||||
)
|
||||
})
|
||||
self.get_db_name()
|
||||
),
|
||||
[],
|
||||
)
|
||||
.map_err(sqlite_error)?;
|
||||
|
||||
dbv_id2entry = 1;
|
||||
|
||||
admin_info!(entry = %dbv_id2entry, "dbv_id2entry migrated (id2entry, db_sid)");
|
||||
info!(entry = %dbv_id2entry, "dbv_id2entry migrated (id2entry, db_sid)");
|
||||
}
|
||||
// * if v1 -> add the domain uuid table
|
||||
if dbv_id2entry == 1 {
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.execute(
|
||||
&format!(
|
||||
"CREATE TABLE IF NOT EXISTS {}.db_did (
|
||||
|
@ -1376,11 +1352,11 @@ impl IdlSqliteWriteTransaction {
|
|||
.map_err(sqlite_error)?;
|
||||
|
||||
dbv_id2entry = 2;
|
||||
admin_info!(entry = %dbv_id2entry, "dbv_id2entry migrated (db_did)");
|
||||
info!(entry = %dbv_id2entry, "dbv_id2entry migrated (db_did)");
|
||||
}
|
||||
// * if v2 -> add the op max ts table.
|
||||
if dbv_id2entry == 2 {
|
||||
self.conn
|
||||
self.get_conn()?
|
||||
.execute(
|
||||
&format!(
|
||||
"CREATE TABLE IF NOT EXISTS {}.db_op_ts (
|
||||
|
@ -1394,7 +1370,7 @@ impl IdlSqliteWriteTransaction {
|
|||
)
|
||||
.map_err(sqlite_error)?;
|
||||
dbv_id2entry = 3;
|
||||
admin_info!(entry = %dbv_id2entry, "dbv_id2entry migrated (db_op_ts)");
|
||||
info!(entry = %dbv_id2entry, "dbv_id2entry migrated (db_op_ts)");
|
||||
}
|
||||
// * if v3 -> create name2uuid, uuid2spn, uuid2rdn.
|
||||
if dbv_id2entry == 3 {
|
||||
|
@ -1402,24 +1378,23 @@ impl IdlSqliteWriteTransaction {
|
|||
.and_then(|_| self.create_uuid2spn())
|
||||
.and_then(|_| self.create_uuid2rdn())?;
|
||||
dbv_id2entry = 4;
|
||||
admin_info!(entry = %dbv_id2entry, "dbv_id2entry migrated (name2uuid, uuid2spn, uuid2rdn)");
|
||||
info!(entry = %dbv_id2entry, "dbv_id2entry migrated (name2uuid, uuid2spn, uuid2rdn)");
|
||||
}
|
||||
// * if v4 -> migrate v1 to v2 entries.
|
||||
if dbv_id2entry == 4 {
|
||||
self.migrate_dbentryv1_to_dbentryv2()?;
|
||||
dbv_id2entry = 5;
|
||||
admin_info!(entry = %dbv_id2entry, "dbv_id2entry migrated (dbentryv1 -> dbentryv2)");
|
||||
info!(entry = %dbv_id2entry, "dbv_id2entry migrated (dbentryv1 -> dbentryv2)");
|
||||
}
|
||||
// * if v5 -> create externalid2uuid
|
||||
if dbv_id2entry == 5 {
|
||||
self.create_externalid2uuid()?;
|
||||
dbv_id2entry = 6;
|
||||
admin_info!(entry = %dbv_id2entry, "dbv_id2entry migrated (externalid2uuid)");
|
||||
info!(entry = %dbv_id2entry, "dbv_id2entry migrated (externalid2uuid)");
|
||||
}
|
||||
// * if v6 -> complete.
|
||||
|
||||
self.set_db_version_key(DBV_ID2ENTRY, dbv_id2entry)
|
||||
.map_err(sqlite_error)?;
|
||||
self.set_db_version_key(DBV_ID2ENTRY, dbv_id2entry)?;
|
||||
|
||||
// NOTE: Indexing is configured in a different step!
|
||||
// Indexing uses a db version flag to represent the version
|
||||
|
@ -1445,6 +1420,27 @@ impl IdlSqlite {
|
|||
flags.insert(OpenFlags::SQLITE_OPEN_NO_MUTEX);
|
||||
};
|
||||
|
||||
let fs_page_size = cfg.fstype as u32;
|
||||
let checkpoint_pages = cfg.fstype.checkpoint_pages();
|
||||
|
||||
// Initial setup routines.
|
||||
{
|
||||
let vconn =
|
||||
Connection::open_with_flags(cfg.path.as_str(), flags).map_err(sqlite_error)?;
|
||||
|
||||
vconn
|
||||
.execute_batch(
|
||||
format!(
|
||||
"PRAGMA page_size={fs_page_size};
|
||||
PRAGMA journal_mode=WAL;
|
||||
PRAGMA wal_autocheckpoint={checkpoint_pages};
|
||||
PRAGMA wal_checkpoint(RESTART);"
|
||||
)
|
||||
.as_str(),
|
||||
)
|
||||
.map_err(sqlite_error)?;
|
||||
}
|
||||
|
||||
// We need to run vacuum in the setup else we hit sqlite lock conditions.
|
||||
if vacuum {
|
||||
admin_warn!(
|
||||
|
@ -1511,31 +1507,18 @@ impl IdlSqlite {
|
|||
// limmediate_warning!(audit, "NOTICE: db vacuum complete\n");
|
||||
};
|
||||
|
||||
let fs_page_size = cfg.fstype as u32;
|
||||
let checkpoint_pages = cfg.fstype.checkpoint_pages();
|
||||
|
||||
let manager = SqliteConnectionManager::file(cfg.path.as_str())
|
||||
.with_init(move |c| {
|
||||
c.execute_batch(
|
||||
format!(
|
||||
"PRAGMA page_size={fs_page_size};
|
||||
PRAGMA journal_mode=WAL;
|
||||
PRAGMA wal_autocheckpoint={checkpoint_pages};
|
||||
PRAGMA wal_checkpoint(RESTART);"
|
||||
)
|
||||
.as_str(),
|
||||
)
|
||||
let pool = (0..cfg.pool_size)
|
||||
.map(|i| {
|
||||
trace!("Opening Connection {}", i);
|
||||
Connection::open_with_flags(cfg.path.as_str(), flags).map_err(sqlite_error)
|
||||
})
|
||||
.with_flags(flags);
|
||||
.collect::<Result<VecDeque<Connection>, OperationError>>()
|
||||
.map_err(|e| {
|
||||
error!(err = ?e, "Failed to build connection pool");
|
||||
e
|
||||
})?;
|
||||
|
||||
let builder1 = Pool::builder();
|
||||
let builder2 = builder1.max_size(cfg.pool_size);
|
||||
// Look at max_size and thread_pool here for perf later
|
||||
let pool = builder2.build(manager).map_err(|e| {
|
||||
admin_error!(?e, "r2d2 error");
|
||||
// ladmin_error!(audit, "r2d2 error {:?}", e);
|
||||
OperationError::SqliteError
|
||||
})?;
|
||||
let pool = Arc::new(Mutex::new(pool));
|
||||
|
||||
Ok(IdlSqlite {
|
||||
pool,
|
||||
|
@ -1545,10 +1528,14 @@ impl IdlSqlite {
|
|||
|
||||
pub(crate) fn get_allids_count(&self) -> Result<u64, OperationError> {
|
||||
#[allow(clippy::expect_used)]
|
||||
self.pool
|
||||
.try_get()
|
||||
.expect("Unable to get connection from pool!!!")
|
||||
.query_row("select count(id) from id2entry", [], |row| row.get(0))
|
||||
let guard = self.pool.lock().expect("Unable to lock connection pool.");
|
||||
// Get not pop here
|
||||
#[allow(clippy::expect_used)]
|
||||
let conn = guard
|
||||
.get(0)
|
||||
.expect("Unable to retrieve connection from pool.");
|
||||
|
||||
conn.query_row("select count(id) from id2entry", [], |row| row.get(0))
|
||||
.map_err(sqlite_error)
|
||||
}
|
||||
|
||||
|
@ -1558,18 +1545,34 @@ impl IdlSqlite {
|
|||
#[allow(clippy::expect_used)]
|
||||
let conn = self
|
||||
.pool
|
||||
.try_get()
|
||||
.expect("Unable to get connection from pool!!!");
|
||||
IdlSqliteReadTransaction::new(conn, self.db_name)
|
||||
.lock()
|
||||
.map_err(|e| {
|
||||
error!(err = ?e, "Unable to lock connection pool.");
|
||||
})
|
||||
.ok()
|
||||
.and_then(|mut q| {
|
||||
trace!(?q);
|
||||
q.pop_front()
|
||||
})
|
||||
.expect("Unable to retrieve connection from pool.");
|
||||
IdlSqliteReadTransaction::new(self.pool.clone(), conn, self.db_name)
|
||||
}
|
||||
|
||||
pub fn write(&self) -> IdlSqliteWriteTransaction {
|
||||
#[allow(clippy::expect_used)]
|
||||
let conn = self
|
||||
.pool
|
||||
.try_get()
|
||||
.expect("Unable to get connection from pool!!!");
|
||||
IdlSqliteWriteTransaction::new(conn, self.db_name)
|
||||
.lock()
|
||||
.map_err(|e| {
|
||||
error!(err = ?e, "Unable to lock connection pool.");
|
||||
})
|
||||
.ok()
|
||||
.and_then(|mut q| {
|
||||
trace!(?q);
|
||||
q.pop_front()
|
||||
})
|
||||
.expect("Unable to retrieve connection from pool.");
|
||||
IdlSqliteWriteTransaction::new(self.pool.clone(), conn, self.db_name)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
//! Constant Entries for the IDM
|
||||
|
||||
use crate::constants::uuids::*;
|
||||
///! Constant Entries for the IDM
|
||||
use crate::constants::values::*;
|
||||
use crate::entry::{Entry, EntryInit, EntryInitNew, EntryNew};
|
||||
use crate::value::Value;
|
||||
|
|
|
@ -234,10 +234,11 @@ impl UnixUserAccount {
|
|||
match &self.cred {
|
||||
Some(cred) => {
|
||||
cred.password_ref().and_then(|pw| {
|
||||
if pw.verify(cleartext).map_err(|e| {
|
||||
let valid = pw.verify(cleartext).map_err(|e| {
|
||||
error!(crypto_err = ?e);
|
||||
e.into()
|
||||
})? {
|
||||
})?;
|
||||
if valid {
|
||||
security_info!("Successful unix cred handling");
|
||||
if pw.requires_upgrade() {
|
||||
async_tx
|
||||
|
|
|
@ -695,10 +695,7 @@ impl Component for LoginApp {
|
|||
// to actually start the reauth as the same user.
|
||||
|
||||
match models::get_login_hint() {
|
||||
Some(spn) => LoginState::InitReauth {
|
||||
enable: true,
|
||||
spn: spn.clone(),
|
||||
},
|
||||
Some(spn) => LoginState::InitReauth { enable: true, spn },
|
||||
None => LoginState::Error {
|
||||
emsg: "Client Error - No login hint available".to_string(),
|
||||
kopid: None,
|
||||
|
@ -735,10 +732,7 @@ impl Component for LoginApp {
|
|||
}
|
||||
LoginWorkflow::Reauth => {
|
||||
match models::get_login_hint() {
|
||||
Some(spn) => LoginState::InitReauth {
|
||||
enable: true,
|
||||
spn: spn.clone(),
|
||||
},
|
||||
Some(spn) => LoginState::InitReauth { enable: true, spn },
|
||||
None => LoginState::Error {
|
||||
emsg: "Client Error - No login hint available".to_string(),
|
||||
kopid: None,
|
||||
|
@ -799,10 +793,7 @@ impl Component for LoginApp {
|
|||
});
|
||||
|
||||
self.state = match models::get_login_hint() {
|
||||
Some(spn) => LoginState::InitReauth {
|
||||
enable: false,
|
||||
spn: spn.clone(),
|
||||
},
|
||||
Some(spn) => LoginState::InitReauth { enable: false, spn },
|
||||
None => LoginState::Error {
|
||||
emsg: "Client Error - No login hint available".to_string(),
|
||||
kopid: None,
|
||||
|
|
|
@ -419,7 +419,13 @@ impl PersonOpt {
|
|||
}
|
||||
} else if matches!(ano.datetime.as_str(), "now") {
|
||||
// set the expiry to *now*
|
||||
let now = OffsetDateTime::now_utc().format(&Rfc3339).unwrap();
|
||||
let now = match OffsetDateTime::now_utc().format(&Rfc3339) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
error!(err = ?e, "Unable to format current time to rfc3339");
|
||||
return;
|
||||
}
|
||||
};
|
||||
debug!("Setting expiry to {}", now);
|
||||
match client
|
||||
.idm_person_account_set_attr(
|
||||
|
@ -434,7 +440,13 @@ impl PersonOpt {
|
|||
}
|
||||
} else if matches!(ano.datetime.as_str(), "epoch") {
|
||||
// set the expiry to the epoch
|
||||
let epoch_str = OffsetDateTime::UNIX_EPOCH.format(&Rfc3339).unwrap();
|
||||
let epoch_str = match OffsetDateTime::UNIX_EPOCH.format(&Rfc3339) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
error!(err = ?e, "Unable to format unix epoch to rfc3339");
|
||||
return;
|
||||
}
|
||||
};
|
||||
debug!("Setting expiry to {}", epoch_str);
|
||||
match client
|
||||
.idm_person_account_set_attr(
|
||||
|
|
|
@ -54,8 +54,6 @@ kanidm_proto.workspace = true
|
|||
kanidm_lib_crypto.workspace = true
|
||||
kanidm_lib_file_permissions.workspace = true
|
||||
notify-debouncer-full.workspace = true
|
||||
r2d2.workspace = true
|
||||
r2d2_sqlite.workspace = true
|
||||
rpassword.workspace = true
|
||||
rusqlite.workspace = true
|
||||
selinux = { workspace = true, optional = true }
|
||||
|
|
|
@ -7,23 +7,20 @@ use kanidm_lib_crypto::DbPasswordV1;
|
|||
use kanidm_lib_crypto::Password;
|
||||
use kanidm_proto::v1::{UnixGroupToken, UnixUserToken};
|
||||
use libc::umask;
|
||||
use r2d2::Pool;
|
||||
use r2d2_sqlite::SqliteConnectionManager;
|
||||
use rusqlite::Connection;
|
||||
use tokio::sync::{Mutex, MutexGuard};
|
||||
|
||||
use crate::cache::Id;
|
||||
|
||||
pub struct Db {
|
||||
pool: Pool<SqliteConnectionManager>,
|
||||
lock: Mutex<()>,
|
||||
conn: Mutex<Connection>,
|
||||
crypto_policy: CryptoPolicy,
|
||||
require_tpm: Option<tpm::TpmConfig>,
|
||||
}
|
||||
|
||||
pub struct DbTxn<'a> {
|
||||
_guard: MutexGuard<'a, ()>,
|
||||
conn: MutexGuard<'a, Connection>,
|
||||
committed: bool,
|
||||
conn: r2d2::PooledConnection<SqliteConnectionManager>,
|
||||
crypto_policy: &'a CryptoPolicy,
|
||||
require_tpm: Option<&'a tpm::TpmConfig>,
|
||||
}
|
||||
|
@ -31,15 +28,12 @@ pub struct DbTxn<'a> {
|
|||
impl Db {
|
||||
pub fn new(path: &str, require_tpm: Option<&str>) -> Result<Self, ()> {
|
||||
let before = unsafe { umask(0o0027) };
|
||||
let manager = SqliteConnectionManager::file(path);
|
||||
let conn = Connection::open(path).map_err(|e| {
|
||||
error!(err = ?e, "rusqulite error");
|
||||
})?;
|
||||
let _ = unsafe { umask(before) };
|
||||
// We only build a single thread. If we need more than one, we'll
|
||||
// need to re-do this to account for path = "" for debug.
|
||||
let builder1 = Pool::builder().max_size(1);
|
||||
let pool = builder1.build(manager).map_err(|e| {
|
||||
error!("r2d2 error {:?}", e);
|
||||
})?;
|
||||
|
||||
let crypto_policy = CryptoPolicy::time_target(Duration::from_millis(250));
|
||||
|
||||
debug!("Configured {:?}", crypto_policy);
|
||||
|
@ -64,8 +58,7 @@ impl Db {
|
|||
};
|
||||
|
||||
Ok(Db {
|
||||
pool,
|
||||
lock: Mutex::new(()),
|
||||
conn: Mutex::new(conn),
|
||||
crypto_policy,
|
||||
require_tpm,
|
||||
})
|
||||
|
@ -73,12 +66,8 @@ impl Db {
|
|||
|
||||
#[allow(clippy::expect_used)]
|
||||
pub async fn write(&self) -> DbTxn<'_> {
|
||||
let guard = self.lock.lock().await;
|
||||
let conn = self
|
||||
.pool
|
||||
.get()
|
||||
.expect("Unable to get connection from pool!!!");
|
||||
DbTxn::new(conn, guard, &self.crypto_policy, self.require_tpm.as_ref())
|
||||
let conn = self.conn.lock().await;
|
||||
DbTxn::new(conn, &self.crypto_policy, self.require_tpm.as_ref())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -90,8 +79,7 @@ impl fmt::Debug for Db {
|
|||
|
||||
impl<'a> DbTxn<'a> {
|
||||
pub fn new(
|
||||
conn: r2d2::PooledConnection<SqliteConnectionManager>,
|
||||
guard: MutexGuard<'a, ()>,
|
||||
conn: MutexGuard<'a, Connection>,
|
||||
crypto_policy: &'a CryptoPolicy,
|
||||
require_tpm: Option<&'a tpm::TpmConfig>,
|
||||
) -> Self {
|
||||
|
@ -103,7 +91,6 @@ impl<'a> DbTxn<'a> {
|
|||
DbTxn {
|
||||
committed: false,
|
||||
conn,
|
||||
_guard: guard,
|
||||
crypto_policy,
|
||||
require_tpm,
|
||||
}
|
||||
|
|
|
@ -66,7 +66,6 @@ async fn setup_test(fix_fn: Fixture) -> (CacheLayer, KanidmClient) {
|
|||
config.secure_cookies = false;
|
||||
config.integration_test_config = Some(int_config);
|
||||
config.role = ServerRole::WriteReplicaNoUI;
|
||||
// config.log_level = Some(LogLevel::Verbose as u32);
|
||||
config.threads = 1;
|
||||
|
||||
create_server_core(config, false)
|
||||
|
|
Loading…
Reference in a new issue