ADBC
Arrow Database Connectivity
Loading...
Searching...
No Matches
connection.h
1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18#pragma once
19
20#include <cstdint>
21#include <memory>
22#include <string>
23#include <string_view>
24#include <utility>
25#include <vector>
26
27#include <arrow-adbc/adbc.h>
28
29#include "driver/framework/base_driver.h"
30#include "driver/framework/objects.h"
31#include "driver/framework/utility.h"
32
33namespace adbc::driver {
41template <typename Derived>
42class Connection : public ObjectBase {
43 public:
44 using Base = Connection<Derived>;
45
47 enum class AutocommitState {
48 kAutocommit,
49 kTransaction,
50 };
51
52 Connection() : ObjectBase() {}
53 ~Connection() = default;
54
56 AdbcStatusCode Init(void* parent, AdbcError* error) override {
57 if (auto status = impl().InitImpl(parent); !status.ok()) {
58 return status.ToAdbc(error);
59 }
60 return ObjectBase::Init(parent, error);
61 }
62
65
67 AdbcStatusCode Commit(AdbcError* error) {
68 switch (autocommit_) {
69 case AutocommitState::kAutocommit:
70 return status::InvalidState(Derived::kErrorPrefix,
71 " No active transaction, cannot commit")
72 .ToAdbc(error);
73 case AutocommitState::kTransaction:
74 return impl().CommitImpl().ToAdbc(error);
75 }
76 assert(false);
78 }
79
81 AdbcStatusCode GetInfo(const uint32_t* info_codes, size_t info_codes_length,
82 ArrowArrayStream* out, AdbcError* error) {
83 if (!out) {
84 RAISE_STATUS(error, status::InvalidArgument("out must be non-null"));
85 }
86
87 std::vector<uint32_t> codes(info_codes, info_codes + info_codes_length);
88 std::vector<InfoValue> infos;
89 RAISE_RESULT(error, infos, impl().InfoImpl(codes));
90 RAISE_STATUS(error, MakeGetInfoStream(infos, out));
91 return ADBC_STATUS_OK;
92 }
93
95 AdbcStatusCode GetObjects(int c_depth, const char* catalog, const char* db_schema,
96 const char* table_name, const char** table_type,
97 const char* column_name, ArrowArrayStream* out,
98 AdbcError* error) {
99 const auto catalog_filter =
100 catalog ? std::make_optional(std::string_view(catalog)) : std::nullopt;
101 const auto schema_filter =
102 db_schema ? std::make_optional(std::string_view(db_schema)) : std::nullopt;
103 const auto table_filter =
104 table_name ? std::make_optional(std::string_view(table_name)) : std::nullopt;
105 const auto column_filter =
106 column_name ? std::make_optional(std::string_view(column_name)) : std::nullopt;
107 std::vector<std::string_view> table_type_filter;
108 while (table_type && *table_type) {
109 if (*table_type) {
110 table_type_filter.push_back(std::string_view(*table_type));
111 }
112 table_type++;
113 }
114
115 GetObjectsDepth depth = GetObjectsDepth::kColumns;
116 switch (c_depth) {
118 depth = GetObjectsDepth::kCatalogs;
119 break;
121 depth = GetObjectsDepth::kColumns;
122 break;
124 depth = GetObjectsDepth::kSchemas;
125 break;
127 depth = GetObjectsDepth::kTables;
128 break;
129 default:
130 return status::InvalidArgument(Derived::kErrorPrefix,
131 " GetObjects: invalid depth ", c_depth)
132 .ToAdbc(error);
133 }
134
135 std::unique_ptr<GetObjectsHelper> helper;
136 RAISE_RESULT(error, helper, impl().GetObjectsImpl());
137 auto status = BuildGetObjects(helper.get(), depth, catalog_filter, schema_filter,
138 table_filter, column_filter, table_type_filter, out);
139 RAISE_STATUS(error, helper->Close());
140 RAISE_STATUS(error, status);
141 return ADBC_STATUS_OK;
142 }
143
145 Result<Option> GetOption(std::string_view key) override {
147 switch (autocommit_) {
148 case AutocommitState::kAutocommit:
150 case AutocommitState::kTransaction:
152 }
153 } else if (key == ADBC_CONNECTION_OPTION_CURRENT_CATALOG) {
154 std::optional<std::string> catalog;
155 UNWRAP_RESULT(catalog, impl().GetCurrentCatalogImpl());
156 if (catalog) {
157 return driver::Option(std::move(*catalog));
158 }
159 return driver::Option();
161 std::optional<std::string> schema;
162 UNWRAP_RESULT(schema, impl().GetCurrentSchemaImpl());
163 if (schema) {
164 return driver::Option(std::move(*schema));
165 }
166 return driver::Option();
167 }
168 return status::NotImplemented(Derived::kErrorPrefix, " Unknown connection option ",
169 key);
170 }
171
173 AdbcStatusCode GetStatistics(const char* catalog, const char* db_schema,
174 const char* table_name, char approximate,
175 ArrowArrayStream* out, AdbcError* error) {
177 }
178
180 AdbcStatusCode GetStatisticNames(ArrowArrayStream* out, AdbcError* error) {
182 }
183
185 AdbcStatusCode GetTableSchema(const char* catalog, const char* db_schema,
186 const char* table_name, ArrowSchema* schema,
187 AdbcError* error) {
188 if (!table_name) {
189 return status::InvalidArgument(Derived::kErrorPrefix,
190 " GetTableSchema: must provide table_name")
191 .ToAdbc(error);
192 }
193 std::memset(schema, 0, sizeof(*schema));
194 std::optional<std::string_view> catalog_param =
195 catalog ? std::make_optional(std::string_view(catalog)) : std::nullopt;
196 std::optional<std::string_view> db_schema_param =
197 db_schema ? std::make_optional(std::string_view(db_schema)) : std::nullopt;
198 std::string_view table_name_param = table_name;
199
200 return impl()
201 .GetTableSchemaImpl(catalog_param, db_schema_param, table_name_param, schema)
202 .ToAdbc(error);
203 }
204
206 AdbcStatusCode GetTableTypes(ArrowArrayStream* out, AdbcError* error) {
207 if (!out) {
208 RAISE_STATUS(error, status::InvalidArgument("out must be non-null"));
209 }
210
211 std::vector<std::string> table_types;
212 RAISE_RESULT(error, table_types, impl().GetTableTypesImpl());
213 RAISE_STATUS(error, MakeTableTypesStream(table_types, out));
214 return ADBC_STATUS_OK;
215 }
216
218 AdbcStatusCode ReadPartition(const uint8_t* serialized_partition,
219 size_t serialized_length, ArrowArrayStream* out,
220 AdbcError* error) {
222 }
223
226 return impl().ReleaseImpl().ToAdbc(error);
227 }
228
230 AdbcStatusCode Rollback(AdbcError* error) {
231 switch (autocommit_) {
232 case AutocommitState::kAutocommit:
233 return status::InvalidState(Derived::kErrorPrefix,
234 " No active transaction, cannot rollback")
235 .ToAdbc(error);
236 case AutocommitState::kTransaction:
237 return impl().RollbackImpl().ToAdbc(error);
238 }
239 assert(false);
241 }
242
244 AdbcStatusCode SetOption(std::string_view key, Option value,
245 AdbcError* error) override {
246 return impl().SetOptionImpl(key, value).ToAdbc(error);
247 }
248
252 Status CommitImpl() { return status::NotImplemented("Commit"); }
253
254 Result<std::optional<std::string>> GetCurrentCatalogImpl() { return std::nullopt; }
255
256 Result<std::optional<std::string>> GetCurrentSchemaImpl() { return std::nullopt; }
257
265 return std::make_unique<GetObjectsHelper>();
266 }
267
268 Status GetTableSchemaImpl(std::optional<std::string_view> catalog,
269 std::optional<std::string_view> db_schema,
270 std::string_view table_name, ArrowSchema* schema) {
271 return status::NotImplemented("GetTableSchema");
272 }
273
274 Result<std::vector<std::string>> GetTableTypesImpl() {
275 return std::vector<std::string>();
276 }
277
278 Result<std::vector<InfoValue>> InfoImpl(const std::vector<uint32_t>& codes) {
279 return std::vector<InfoValue>{};
280 }
281
282 Status InitImpl(void* parent) { return status::Ok(); }
283
284 Status ReleaseImpl() { return status::Ok(); }
285
286 Status RollbackImpl() { return status::NotImplemented("Rollback"); }
287
288 Status SetOptionImpl(std::string_view key, Option value) {
290 bool enabled;
291 UNWRAP_RESULT(enabled, value.AsBool());
292 switch (autocommit_) {
293 case AutocommitState::kAutocommit: {
294 if (!enabled) {
295 UNWRAP_STATUS(impl().ToggleAutocommitImpl(false));
296 autocommit_ = AutocommitState::kTransaction;
297 }
298 break;
299 }
300 case AutocommitState::kTransaction: {
301 if (enabled) {
302 UNWRAP_STATUS(impl().ToggleAutocommitImpl(true));
303 autocommit_ = AutocommitState::kAutocommit;
304 }
305 break;
306 }
307 }
308 return status::Ok();
309 }
310 return status::NotImplemented(Derived::kErrorPrefix, " Unknown connection option ",
311 key, "=", value.Format());
312 }
313
314 Status ToggleAutocommitImpl(bool enable_autocommit) {
315 return status::NotImplemented(Derived::kErrorPrefix, " Cannot change autocommit");
316 }
317
318 protected:
319 AutocommitState autocommit_ = AutocommitState::kAutocommit;
320
321 private:
322 Derived& impl() { return static_cast<Derived&>(*this); }
323};
324
325} // namespace adbc::driver
The CRTP base implementation of an AdbcConnection.
Definition connection.h:42
Status CommitImpl()
Commit the current transaction and begin a new transaction.
Definition connection.h:252
AdbcStatusCode Release(AdbcError *error) override
Finalize the object.
Definition connection.h:225
Result< std::unique_ptr< GetObjectsHelper > > GetObjectsImpl()
Query the database catalog.
Definition connection.h:264
AdbcStatusCode SetOption(std::string_view key, Option value, AdbcError *error) override
Set an option value.
Definition connection.h:244
AdbcStatusCode Init(void *parent, AdbcError *error) override
Initialize the object.
Definition connection.h:56
Result< Option > GetOption(std::string_view key) override
Get an option value.
Definition connection.h:145
AutocommitState
Whether autocommit is enabled or not (by default: enabled).
Definition connection.h:47
Base class for private_data of AdbcDatabase, AdbcConnection, and AdbcStatement.
Definition base_driver.h:256
virtual AdbcStatusCode Init(void *parent, AdbcError *error)
Initialize the object.
Definition base_driver.h:276
A typed option value wrapper. It currently does not attempt conversion (i.e., getting a double option...
Definition base_driver.h:59
A wrapper around a value, or an error.
Definition status.h:203
A wrapper around AdbcStatusCode + AdbcError.
Definition status.h:43
#define ADBC_OBJECT_DEPTH_TABLES
Return metadata on catalogs, schemas, and tables.
Definition adbc.h:548
#define ADBC_CONNECTION_OPTION_CURRENT_DB_SCHEMA
The name of the canonical option for the current schema.
Definition adbc.h:648
#define ADBC_OBJECT_DEPTH_CATALOGS
Return metadata on catalogs only.
Definition adbc.h:538
#define ADBC_CONNECTION_OPTION_CURRENT_CATALOG
The name of the canonical option for the current catalog.
Definition adbc.h:639
#define ADBC_CONNECTION_OPTION_AUTOCOMMIT
The name of the canonical option for whether autocommit is enabled.
Definition adbc.h:622
#define ADBC_OBJECT_DEPTH_DB_SCHEMAS
Return metadata on catalogs and schemas.
Definition adbc.h:543
#define ADBC_OPTION_VALUE_DISABLED
Canonical option value for disabling an option.
Definition adbc.h:434
#define ADBC_OPTION_VALUE_ENABLED
Canonical option value for enabling an option.
Definition adbc.h:429
#define ADBC_OBJECT_DEPTH_COLUMNS
Return metadata on catalogs, schemas, tables, and columns.
Definition adbc.h:553
#define ADBC_STATUS_NOT_IMPLEMENTED
The operation is not implemented or supported.
Definition adbc.h:189
uint8_t AdbcStatusCode
Error codes for operations that may fail.
Definition adbc.h:176
#define ADBC_STATUS_OK
No error.
Definition adbc.h:179
#define ADBC_STATUS_INTERNAL
An error internal to the driver or database occurred.
Definition adbc.h:236
A detailed error message for an operation.
Definition adbc.h:283
Status MakeTableTypesStream(const std::vector< std::string > &table_types, ArrowArrayStream *out)
Create an ArrowArrayStream representation of a vector of table types.
GetObjectsDepth
The GetObjects level.
Definition objects.h:39
Status BuildGetObjects(GetObjectsHelper *helper, GetObjectsDepth depth, std::optional< std::string_view > catalog_filter, std::optional< std::string_view > schema_filter, std::optional< std::string_view > table_filter, std::optional< std::string_view > column_filter, const std::vector< std::string_view > &table_types, ArrowArrayStream *out)
A helper that implements GetObjects. The out/helper lifetime are caller-managed.
Status MakeGetInfoStream(const std::vector< InfoValue > &infos, ArrowArrayStream *out)
Create an ArrowArrayStream to be returned from AdbcConnectionGetInfo().
#define RAISE_RESULT(ERROR, LHS, RHS)
A helper to unwrap a Result in functions returning AdbcStatusCode.
Definition status.h:286
#define UNWRAP_STATUS(rhs)
A helper to unwrap a Status in functions returning Result/Status.
Definition status.h:298
#define RAISE_STATUS(ERROR, RHS)
A helper to unwrap a Status in functions returning AdbcStatusCode.
Definition status.h:290
#define UNWRAP_RESULT(lhs, rhs)
A helper to unwrap a Result in functions returning Result/Status.
Definition status.h:294