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