Skip to main content

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}