typedb_driver/transaction.rs
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20use std::{fmt, pin::Pin};
21
22use tracing::debug;
23
24use crate::{
25 Error, QueryOptions, TransactionOptions,
26 analyze::AnalyzedQuery,
27 answer::QueryAnswer,
28 common::{Promise, Result, TransactionType},
29 connection::TransactionStream,
30 given::GivenRows,
31};
32
33/// A transaction with a TypeDB database.
34pub struct Transaction {
35 /// The transaction’s type (READ or WRITE)
36 type_: TransactionType,
37 /// The options for the transaction
38 options: TransactionOptions,
39 transaction_stream: Pin<Box<TransactionStream>>,
40}
41
42impl Transaction {
43 pub(super) fn new(transaction_stream: TransactionStream) -> Self {
44 let transaction_stream = Box::pin(transaction_stream);
45 Transaction {
46 type_: transaction_stream.type_(),
47 options: transaction_stream.options().clone(),
48 transaction_stream,
49 }
50 }
51
52 /// Checks if the transaction is open.
53 ///
54 /// # Examples
55 ///
56 /// ```rust
57 /// transaction.is_open()
58 /// ```
59 pub fn is_open(&self) -> bool {
60 self.transaction_stream.is_open()
61 }
62
63 /// Performs a TypeQL query with default options.
64 /// See [`Transaction::query_with_options`]
65 ///
66 /// # Examples
67 ///
68 /// ```rust
69 /// transaction.query(query)
70 /// ```
71 pub fn query(&self, query: impl AsRef<str>) -> impl Promise<'static, Result<QueryAnswer>> {
72 self.query_with_options_and_rows(query, QueryOptions::new(), None)
73 }
74
75 /// Performs a TypeQL query in this transaction.
76 ///
77 /// # Arguments
78 ///
79 /// * `query` — The TypeQL query to be executed
80 /// * `options` — The QueryOptions to execute the query with
81 ///
82 /// # Examples
83 ///
84 /// ```rust
85 /// transaction.query_with_options(query, options)
86 /// ```
87 pub fn query_with_options(
88 &self,
89 query: impl AsRef<str>,
90 options: QueryOptions,
91 ) -> impl Promise<'static, Result<QueryAnswer>> {
92 self.query_with_options_and_rows(query, options, None)
93 }
94
95 /// Performs a TypeQL query in this transaction.
96 ///
97 /// # Arguments
98 ///
99 /// * `query` — The TypeQL query to be executed
100 /// * `rows` — The GivenRows to pass as input to the query.
101 ///
102 /// # Examples
103 ///
104 /// ```rust
105 /// transaction.query_with_options(query, options, rows)
106 /// ```
107 pub fn query_with_rows(
108 &self,
109 query: impl AsRef<str>,
110 rows: GivenRows,
111 ) -> impl Promise<'static, Result<QueryAnswer>> {
112 self.query_with_options_and_rows(query, QueryOptions::new(), Some(rows))
113 }
114
115 /// Performs a TypeQL query in this transaction.
116 ///
117 /// # Arguments
118 ///
119 /// * `query` — The TypeQL query to be executed
120 /// * `options` — The QueryOptions to execute the query with
121 /// * `rows` — The GivenRows to pass as input to the query.
122 ///
123 /// # Examples
124 ///
125 /// ```rust
126 /// transaction.query_with_options(query, options, rows)
127 /// ```
128 pub fn query_with_options_and_rows(
129 &self,
130 query: impl AsRef<str>,
131 options: QueryOptions,
132 rows: Option<GivenRows>,
133 ) -> impl Promise<'static, Result<QueryAnswer>> {
134 let query = query.as_ref();
135 debug!("Transaction submitting query: {}", query);
136 self.transaction_stream.query(query, options, rows)
137 }
138
139 /// Analyzes a TypeQL query in this transaction,
140 /// returning the translated structure & inferred types.
141 ///
142 /// # Arguments
143 ///
144 /// * `query` — The TypeQL query to be analyzed
145 ///
146 /// # Examples
147 ///
148 /// ```rust
149 /// transaction.analyze(query)
150 /// ```
151 pub fn analyze(&self, query: impl AsRef<str>) -> impl Promise<'static, Result<AnalyzedQuery>> {
152 self.transaction_stream.analyze(query.as_ref())
153 }
154
155 /// Retrieves the transaction’s type (READ or WRITE).
156 pub fn type_(&self) -> TransactionType {
157 self.type_
158 }
159
160 /// Registers a callback function which will be executed when this transaction is closed
161 /// returns a resolvable promise that must be awaited otherwise the callback may not be registered
162 ///
163 /// # Arguments
164 ///
165 /// * `function` — The callback function.
166 ///
167 /// # Examples
168 ///
169 /// ```rust
170 /// transaction.on_close(function)
171 /// ```
172 pub fn on_close(
173 &self,
174 callback: impl FnOnce(Option<Error>) + Send + Sync + 'static,
175 ) -> impl Promise<'_, Result<()>> {
176 self.transaction_stream.on_close(callback)
177 }
178
179 /// Closes the transaction and returns a resolvable promise
180 ///
181 /// # Examples
182 ///
183 /// ```rust
184 #[cfg_attr(feature = "sync", doc = "transaction.close().resolve()")]
185 #[cfg_attr(not(feature = "sync"), doc = "transaction.close().await")]
186 /// ```
187 pub fn close(&self) -> impl Promise<'_, Result<()>> {
188 self.transaction_stream.close()
189 }
190
191 /// Commits the changes made via this transaction to the TypeDB database. Whether or not the transaction is commited successfully, it gets closed after the commit call.
192 ///
193 /// # Examples
194 ///
195 /// ```rust
196 #[cfg_attr(feature = "sync", doc = "transaction.commit()")]
197 #[cfg_attr(not(feature = "sync"), doc = "transaction.commit().await")]
198 /// ```
199 pub fn commit(self) -> impl Promise<'static, Result> {
200 let stream = self.transaction_stream;
201 stream.commit()
202 }
203
204 /// Rolls back the uncommitted changes made via this transaction.
205 ///
206 /// # Examples
207 ///
208 /// ```rust
209 #[cfg_attr(feature = "sync", doc = "transaction.rollback()")]
210 #[cfg_attr(not(feature = "sync"), doc = "transaction.rollback().await")]
211 /// ```
212 pub fn rollback(&self) -> impl Promise<'_, Result> {
213 self.transaction_stream.rollback()
214 }
215}
216
217impl fmt::Debug for Transaction {
218 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
219 f.debug_struct("Transaction").field("type_", &self.type_).field("options", &self.options).finish()
220 }
221}