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};
31
32/// A transaction with a TypeDB database.
33pub struct Transaction {
34 /// The transaction’s type (READ or WRITE)
35 type_: TransactionType,
36 /// The options for the transaction
37 options: TransactionOptions,
38 transaction_stream: Pin<Box<TransactionStream>>,
39}
40
41impl Transaction {
42 pub(super) fn new(transaction_stream: TransactionStream) -> Self {
43 let transaction_stream = Box::pin(transaction_stream);
44 Transaction {
45 type_: transaction_stream.type_(),
46 options: transaction_stream.options().clone(),
47 transaction_stream,
48 }
49 }
50
51 /// Checks if the transaction is open.
52 ///
53 /// # Examples
54 ///
55 /// ```rust
56 /// transaction.is_open()
57 /// ```
58 pub fn is_open(&self) -> bool {
59 self.transaction_stream.is_open()
60 }
61
62 /// Performs a TypeQL query with default options.
63 /// See [`Transaction::query_with_options`]
64 ///
65 /// # Examples
66 ///
67 /// ```rust
68 /// transaction.query(query)
69 /// ```
70 pub fn query(&self, query: impl AsRef<str>) -> impl Promise<'static, Result<QueryAnswer>> {
71 self.query_with_options(query, QueryOptions::new())
72 }
73
74 /// Performs a TypeQL query in this transaction.
75 ///
76 /// # Arguments
77 ///
78 /// * `query` — The TypeQL query to be executed
79 /// * `options` — The QueryOptions to execute the query with
80 ///
81 /// # Examples
82 ///
83 /// ```rust
84 /// transaction.query_with_options(query, options)
85 /// ```
86 pub fn query_with_options(
87 &self,
88 query: impl AsRef<str>,
89 options: QueryOptions,
90 ) -> impl Promise<'static, Result<QueryAnswer>> {
91 let query = query.as_ref();
92 debug!("Transaction submitting query: {}", query);
93 self.transaction_stream.query(query, options)
94 }
95
96 /// Analyzes a TypeQL query in this transaction,
97 /// returning the translated structure & inferred types.
98 ///
99 /// # Arguments
100 ///
101 /// * `query` — The TypeQL query to be analyzed
102 ///
103 /// # Examples
104 ///
105 /// ```rust
106 /// transaction.analyze(query)
107 /// ```
108 pub fn analyze(&self, query: impl AsRef<str>) -> impl Promise<'static, Result<AnalyzedQuery>> {
109 self.transaction_stream.analyze(query.as_ref())
110 }
111
112 /// Retrieves the transaction’s type (READ or WRITE).
113 pub fn type_(&self) -> TransactionType {
114 self.type_
115 }
116
117 /// Registers a callback function which will be executed when this transaction is closed
118 /// returns a resolvable promise that must be awaited otherwise the callback may not be registered
119 ///
120 /// # Arguments
121 ///
122 /// * `function` — The callback function.
123 ///
124 /// # Examples
125 ///
126 /// ```rust
127 /// transaction.on_close(function)
128 /// ```
129 pub fn on_close(
130 &self,
131 callback: impl FnOnce(Option<Error>) + Send + Sync + 'static,
132 ) -> impl Promise<'_, Result<()>> {
133 self.transaction_stream.on_close(callback)
134 }
135
136 /// Closes the transaction and returns a resolvable promise
137 ///
138 /// # Examples
139 ///
140 /// ```rust
141 #[cfg_attr(feature = "sync", doc = "transaction.close().resolve()")]
142 #[cfg_attr(not(feature = "sync"), doc = "transaction.close().await")]
143 /// ```
144 pub fn close(&self) -> impl Promise<'_, Result<()>> {
145 self.transaction_stream.close()
146 }
147
148 /// 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.
149 ///
150 /// # Examples
151 ///
152 /// ```rust
153 #[cfg_attr(feature = "sync", doc = "transaction.commit()")]
154 #[cfg_attr(not(feature = "sync"), doc = "transaction.commit().await")]
155 /// ```
156 pub fn commit(self) -> impl Promise<'static, Result> {
157 let stream = self.transaction_stream;
158 stream.commit()
159 }
160
161 /// Rolls back the uncommitted changes made via this transaction.
162 ///
163 /// # Examples
164 ///
165 /// ```rust
166 #[cfg_attr(feature = "sync", doc = "transaction.rollback()")]
167 #[cfg_attr(not(feature = "sync"), doc = "transaction.rollback().await")]
168 /// ```
169 pub fn rollback(&self) -> impl Promise<'_, Result> {
170 self.transaction_stream.rollback()
171 }
172}
173
174impl fmt::Debug for Transaction {
175 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176 f.debug_struct("Transaction").field("type_", &self.type_).field("options", &self.options).finish()
177 }
178}