Skip to content

Commit 70cc2af

Browse files
committed
feat(rust/driver_manager): reconcile with C++ driver manager
Closes #4089.
1 parent ee835b9 commit 70cc2af

9 files changed

Lines changed: 387 additions & 198 deletions

File tree

docs/source/format/connection_profiles.rst

Lines changed: 46 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,37 @@
1515
.. specific language governing permissions and limitations
1616
.. under the License.
1717
18-
==================================
19-
Driver Manager Connection Profiles
20-
==================================
18+
===========================================
19+
ADBC Driver Manager and Connection Profiles
20+
===========================================
2121

22-
Overview
23-
========
22+
.. note:: This document describes using the :term:`driver manager` to load
23+
drivers. The driver manager is not required to use ADBC in general
24+
but it allows loading drivers written in a different language from the
25+
application and improves the experience when using multiple drivers in
26+
a single application. For more information on how the driver manager
27+
works see :doc:`how_manager`.
2428

25-
There are two ways to pass connection options to driver managers:
29+
There are two ways to pass driver options through the driver manager:
2630

27-
1. Directly specifying all connection options as arguments to driver manager functions in your
28-
application code. (see the `SetOption` family of functions in :doc:`specification` for details)
29-
2. Referring to a **connection profile** which contains connection options, and optionally overriding
30-
some options in your application code.
31+
1. Directly specifying all options as arguments to the driver manager in your
32+
application code (see the `SetOption` family of functions in
33+
:doc:`specification` for details).
34+
2. Referring to a :term:`connection profile` which contains options, and
35+
optionally overriding some options by setting them through the above
36+
method.
3137

32-
The ADBC driver manager supports **connection profiles** that specify a driver and connection options
33-
in a reusable configuration. This allows users to:
38+
Connection profiles combine a driver and driver options in a reusable
39+
configuration. This allows users to:
3440

3541
- Define connection information in files or environment variables
3642
- Share connection configurations across applications
3743
- Distribute standardized connection settings
3844
- Avoid hardcoding driver names and credentials in application code
3945

40-
Profiles are loaded during ``AdbcDatabaseInit()`` before initializing the driver. Options
41-
from the profile are applied automatically but do not override options already set via ``AdbcDatabaseSetOption()``.
46+
Profiles are loaded during ``AdbcDatabaseInit()`` before initializing the
47+
driver. Options from the profile are applied automatically but do not override
48+
options already set via ``AdbcDatabaseSetOption()``.
4249

4350
Quick Start
4451
===========
@@ -74,9 +81,12 @@ Filesystem-based profiles use TOML format with the following structure:
7481

7582
.. code-block:: toml
7683
84+
# The version is required.
7785
profile_version = 1
86+
# It is optional to provide the driver.
7887
driver = "snowflake"
7988
89+
# The Options table is required, even if empty
8090
[Options]
8191
# String options
8292
adbc.snowflake.sql.account = "mycompany"
@@ -111,18 +121,19 @@ driver
111121

112122
The ``driver`` field specifies which ADBC driver to load. This can be:
113123

114-
- A driver name (e.g., ``"snowflake"``)
124+
- A driver or driver manifest name (e.g., ``"snowflake"``)
115125
- A path to a shared library (e.g., ``"/usr/local/lib/libadbc_driver_snowflake.so"``)
116126
- A path to a driver manifest (e.g., ``"/etc/adbc/drivers/snowflake.toml"``)
117127

118128
If omitted, the driver must be specified through other means (e.g., the ``driver`` option or ``uri`` parameter).
129+
If the application specifies a driver, and specifies a profile that itself references a driver, the two must match exactly, or it is an error.
119130
The driver will be loaded identically to if it was specified via ``AdbcDatabaseSetOption("driver", "<driver>")``.
120131
For more detils, see :doc:`driver_manifests`.
121132

122133
Options Section
123134
---------------
124135

125-
The ``[Options]`` section contains driver-specific configuration options. Options can be of the following types:
136+
The ``[Options]`` section contains driver-specific configuration options. This section must be present, even if empty. Options can be of the following types:
126137

127138
**String values**
128139
Applied using ``AdbcDatabaseSetOption()``
@@ -153,6 +164,10 @@ The ``[Options]`` section contains driver-specific configuration options. Option
153164
154165
adbc.snowflake.sql.client_session_keep_alive = true
155166
167+
.. warning:: If the application overrides option values but uses a different
168+
type for the value than the profile does, it is undefined which
169+
will take effect.
170+
156171
Value Substitution
157172
------------------
158173

@@ -190,7 +205,7 @@ Profile Search Locations
190205

191206
When using a profile name (not an absolute path), the driver manager searches for ``<profile_name>.toml`` in the following locations:
192207

193-
1. **Additional Search Paths** (if configured via ``AdbcDriverManagerDatabaseSetAdditionalSearchPathList()``)
208+
1. **Additional Search Paths** (if configured via ``additional_profile_search_path_list`` option)
194209
2. **ADBC_PROFILE_PATH** environment variable (colon-separated on Unix, semicolon-separated on Windows)
195210
3. **Conda Environment** (if built with Conda support and ``CONDA_PREFIX`` is set):
196211

@@ -561,34 +576,28 @@ Sets a custom connection profile provider. Must be called before ``AdbcDatabaseI
561576
Setting Additional Search Paths
562577
--------------------------------
563578

564-
.. code-block:: c
565-
566-
AdbcStatusCode AdbcDriverManagerDatabaseSetAdditionalSearchPathList(
567-
struct AdbcDatabase* database,
568-
const char* path_list,
569-
struct AdbcError* error);
570-
571-
Adds additional directories to search for profiles. Must be called before ``AdbcDatabaseInit()``.
572-
573-
**Parameters:**
574-
575-
- ``database``: Database object to configure
576-
- ``path_list``: OS-specific path separator delimited list (``:``) on Unix, ``;`` on Windows), or ``NULL`` to clear
577-
- ``error``: Optional error output
578-
579-
**Returns:** ``ADBC_STATUS_OK`` on success, error code otherwise.
579+
This can be done via the ``additional_profile_search_path_list`` option. It
580+
must be set before ``AdbcDatabaseInit()``. The value of this option is an
581+
OS-specific delimited list (``:`` on Unix, ``;`` on Windows), or ``NULL`` to
582+
clear.
580583

581584
**Example:**
582585

583586
.. code-block:: c
584587
585588
// Unix/Linux/macOS
586-
AdbcDriverManagerDatabaseSetAdditionalSearchPathList(
587-
&database, "/opt/app/profiles:/etc/app/profiles", &error);
589+
AdbcDatabaseSetOption(
590+
&database,
591+
"additional_profile_search_path_list",
592+
"/opt/app/profiles:/etc/app/profiles",
593+
&error);
588594
589595
// Windows
590-
AdbcDriverManagerDatabaseSetAdditionalSearchPathList(
591-
&database, "C:\\App\\Profiles;C:\\ProgramData\\App\\Profiles", &error);
596+
AdbcDatabaseSetOption(
597+
&database,
598+
"additional_profile_search_path_list",
599+
"C:\\App\\Profiles;C:\\ProgramData\\App\\Profiles",
600+
&error);
592601
593602
594603
See Also

docs/source/format/driver_manifests.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ ADBC Driver Manager and Manifests
2828

2929
There are two ways to load a driver with the driver manager:
3030

31-
1. Directly specifying the dynamic library to load
32-
2. Referring to a driver manifest file which contains metadata along with the
33-
location of the dynamic library to be loaded
31+
1. Directly specifying the dynamic library to load.
32+
2. Referring to a :term:`driver manifest` file which contains metadata along
33+
with the location of the dynamic library to be loaded.
3434

3535
With either method, you specify the dynamic library or driver manifest as the
3636
``driver`` option to the driver manager or you can use an explicit function for

docs/source/glossary.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ Glossary
3434
In ADBC, the connection object/struct represents a single connection to a
3535
database. Multiple connections may be created from one :term:`database`.
3636

37+
connection profile
38+
A preconfigured driver and options that can be loaded by the
39+
:term:`driver manager` for convenience. Specified via a TOML file. See
40+
:doc:`format/connection_profiles`.
41+
3742
database
3843
In ADBC, the database object/struct holds state that is shared across
3944
connections.

rust/driver_manager/src/lib.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -494,14 +494,13 @@ impl ManagedDatabase {
494494
additional_search_paths: Option<Vec<PathBuf>>,
495495
opts: impl IntoIterator<Item = (<Self as Optionable>::Option, OptionValue)>,
496496
) -> Result<Self> {
497-
let profile_provider = FilesystemProfileProvider;
498497
Self::from_uri_with_profile_provider(
499498
uri,
500499
entrypoint,
501500
version,
502501
load_flags,
503502
additional_search_paths,
504-
profile_provider,
503+
FilesystemProfileProvider::default(),
505504
opts,
506505
)
507506
}
@@ -534,7 +533,7 @@ impl ManagedDatabase {
534533
/// use adbc_driver_manager::profile::FilesystemProfileProvider;
535534
/// use adbc_core::LOAD_FLAG_DEFAULT;
536535
///
537-
/// let provider = FilesystemProfileProvider;
536+
/// let provider = FilesystemProfileProvider::default();
538537
/// let opts = vec![(OptionDatabase::Username, OptionValue::String("admin".to_string()))];
539538
///
540539
/// let db = ManagedDatabase::from_uri_with_profile_provider(
@@ -575,8 +574,7 @@ impl ManagedDatabase {
575574
(drv, final_opts)
576575
}
577576
DriverLocator::Profile(profile) => {
578-
let profile =
579-
profile_provider.get_profile(profile, additional_search_paths.clone())?;
577+
let profile = profile_provider.get_profile(profile)?;
580578
let (driver_name, init_func) = profile.get_driver_name()?;
581579

582580
let drv: ManagedDriver;

0 commit comments

Comments
 (0)