1mod pipeline;
4
5use std::sync::Arc;
6
7use super::{
8 AdapterCapabilities, AdapterFuture, Count, Create, DbAdapter, DbRecord, Delete, DeleteMany,
9 FindMany, FindOne, SchemaCreation, TransactionCallback, Update, UpdateMany,
10};
11use crate::db::DbSchema;
12use crate::env::logger::{create_logger, Logger, LoggerOptions};
13use crate::plugin::PluginDatabaseHook;
14use pipeline::{
15 hooked_create, hooked_delete, hooked_delete_many, hooked_update, hooked_update_many,
16 AfterHookQueue,
17};
18
19#[derive(Clone)]
21pub struct HookedAdapter<A = Arc<dyn DbAdapter>> {
22 inner: A,
23 hooks: Arc<Vec<PluginDatabaseHook>>,
24 logger: Logger,
25 after_queue: Option<AfterHookQueue>,
26}
27
28impl<A> HookedAdapter<A> {
29 pub fn new(inner: A, hooks: Vec<PluginDatabaseHook>) -> Self {
30 Self::with_logger(inner, hooks, create_logger(LoggerOptions::default()))
31 }
32
33 pub fn with_logger(inner: A, hooks: Vec<PluginDatabaseHook>, logger: Logger) -> Self {
34 Self {
35 inner,
36 hooks: Arc::new(hooks),
37 logger,
38 after_queue: None,
39 }
40 }
41
42 pub fn hooks(&self) -> &[PluginDatabaseHook] {
43 self.hooks.as_slice()
44 }
45
46 fn with_after_queue(
47 inner: A,
48 hooks: Arc<Vec<PluginDatabaseHook>>,
49 logger: Logger,
50 after_queue: AfterHookQueue,
51 ) -> Self {
52 Self {
53 inner,
54 hooks,
55 logger,
56 after_queue: Some(after_queue),
57 }
58 }
59}
60
61impl<A> DbAdapter for HookedAdapter<A>
62where
63 A: DbAdapter,
64{
65 fn id(&self) -> &str {
66 self.inner.id()
67 }
68
69 fn capabilities(&self) -> AdapterCapabilities {
70 self.inner.capabilities()
71 }
72
73 fn create<'a>(&'a self, query: Create) -> AdapterFuture<'a, DbRecord> {
74 hooked_create(
75 &self.inner,
76 Arc::clone(&self.hooks),
77 self.logger.clone(),
78 self.after_queue.clone(),
79 query,
80 )
81 }
82
83 fn find_one<'a>(&'a self, query: FindOne) -> AdapterFuture<'a, Option<DbRecord>> {
84 self.inner.find_one(query)
85 }
86
87 fn find_many<'a>(&'a self, query: FindMany) -> AdapterFuture<'a, Vec<DbRecord>> {
88 self.inner.find_many(query)
89 }
90
91 fn count<'a>(&'a self, query: Count) -> AdapterFuture<'a, u64> {
92 self.inner.count(query)
93 }
94
95 fn update<'a>(&'a self, query: Update) -> AdapterFuture<'a, Option<DbRecord>> {
96 hooked_update(
97 &self.inner,
98 Arc::clone(&self.hooks),
99 self.logger.clone(),
100 self.after_queue.clone(),
101 query,
102 )
103 }
104
105 fn update_many<'a>(&'a self, query: UpdateMany) -> AdapterFuture<'a, u64> {
106 hooked_update_many(
107 &self.inner,
108 Arc::clone(&self.hooks),
109 self.logger.clone(),
110 self.after_queue.clone(),
111 query,
112 )
113 }
114
115 fn delete<'a>(&'a self, query: Delete) -> AdapterFuture<'a, ()> {
116 hooked_delete(
117 &self.inner,
118 Arc::clone(&self.hooks),
119 self.logger.clone(),
120 self.after_queue.clone(),
121 query,
122 )
123 }
124
125 fn delete_many<'a>(&'a self, query: DeleteMany) -> AdapterFuture<'a, u64> {
126 hooked_delete_many(
127 &self.inner,
128 Arc::clone(&self.hooks),
129 self.logger.clone(),
130 self.after_queue.clone(),
131 query,
132 )
133 }
134
135 fn transaction<'a>(&'a self, callback: TransactionCallback<'a>) -> AdapterFuture<'a, ()> {
136 Box::pin(async move {
137 let should_run_after_hooks = self.after_queue.is_none();
138 let after_queue = self.after_queue.clone().unwrap_or_default();
139 let transaction_queue = after_queue.clone();
140 let hooks = Arc::clone(&self.hooks);
141 let logger = self.logger.clone();
142 self.inner
143 .transaction(Box::new(move |transaction| {
144 let adapter = HookedAdapter::with_after_queue(
145 transaction,
146 Arc::clone(&hooks),
147 logger.clone(),
148 transaction_queue,
149 );
150 callback(Box::new(adapter))
151 }))
152 .await?;
153 if should_run_after_hooks {
154 after_queue
155 .run(self.hooks.as_slice(), &self.logger, &self.inner)
156 .await?;
157 }
158 Ok(())
159 })
160 }
161
162 fn create_schema<'a>(
163 &'a self,
164 schema: &'a DbSchema,
165 file: Option<&'a str>,
166 ) -> AdapterFuture<'a, Option<SchemaCreation>> {
167 self.inner.create_schema(schema, file)
168 }
169
170 fn run_migrations<'a>(&'a self, schema: &'a DbSchema) -> AdapterFuture<'a, ()> {
171 self.inner.run_migrations(schema)
172 }
173}