1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
//! Family driver traits (RFC 0014, #895).
//!
//! A driver is a connector's I/O and nothing else. The engine — this module
//! for the family-neutral contract, `faucet-common-sql` and
//! `faucet-common-file` for the SQL and object-store families — drives every
//! lifecycle from the driver's primitives: overwrite staging, the
//! exactly-once commit, scoped cleanup, rollback, per-row outcomes and the row
//! report. A connector built on a driver cannot get one of those contracts
//! wrong by forgetting a hook, because it does not implement the hook.
//!
//! | Layer | Trait | Adapter to [`Sink`](crate::Sink) / [`Source`](crate::Source) |
//! |---|---|---|
//! | any sink | [`SinkDriver`] (+ [`StagingDriver`], [`CommitTokenDriver`], [`CleanupDriver`], [`SchemaDriver`], [`RollbackDriver`]) | [`DriverSink`] |
//! | any source | [`SourceDriver`] | [`DriverSource`] |
//! | messaging, produce | [`MessageDriver`] (+ [`MessageTransactions`]) | [`MessageSinkDriver`] → [`DriverSink`] |
//! | messaging, consume | [`MessageConsumer`] | [`MessageSourceDriver`] → [`DriverSource`] |
//! | HTTP | [`HttpDriver`] | [`HttpSinkDriver`] → [`DriverSink`] |
//! | SQL | `faucet_common_sql::SqlDriver` | `faucet_common_sql::SqlSinkDriver` → [`DriverSink`] |
//! | object storage | `faucet_common_file::ObjectStoreDriver` | `faucet_common_file::FileSink` (a [`DriverSink`] inside) |
//!
//! The SQL and object-store traits live in their family crates because they
//! are built on those crates' engines (`SqlSinkEngine` / `SqlDialect`,
//! `FileWriter` / `StorageBackend`), and `faucet-core` depends on no
//! connector-family crate.
//!
//! **Values.** Drivers exchange JSON [`Value`](crate::Value) records under the
//! value-fidelity rules (#885); a destination that writes Arrow directly adds
//! a `ColumnarDriver` (feature `arrow`) and receives the
//! `RecordBatch` unconverted.
//!
//! **Calls.** Every async primitive receives the run's
//! [`CallSlot`](crate::CallSlot); the adapter installs the run's context into
//! it. Make each backend request through it.
//!
//! **Migrating a connector.** Keep the public type and config; hold the
//! adapter and forward:
//!
//! ```
//! use faucet_core::driver::{DriverSink, PageWrite, RowPolicy, SinkDriver};
//! use faucet_core::{CallSlot, FaucetError, Sink, Value, async_trait, forward_sink};
//!
//! /// The connector's I/O.
//! struct AcmeDriver;
//!
//! #[async_trait]
//! impl SinkDriver for AcmeDriver {
//! fn connector_name(&self) -> &'static str {
//! "acme"
//! }
//! async fn write(
//! &self,
//! calls: &CallSlot,
//! rows: &[Value],
//! _policy: RowPolicy,
//! ) -> Result<PageWrite, FaucetError> {
//! let n = rows.len();
//! calls
//! .call_once("insert", async move { Ok::<_, FaucetError>(n) })
//! .await?;
//! Ok(PageWrite::accepted(n))
//! }
//! }
//!
//! /// The public connector type, unchanged for its users.
//! pub struct AcmeSink {
//! inner: DriverSink<AcmeDriver>,
//! }
//!
//! #[async_trait]
//! impl Sink for AcmeSink {
//! forward_sink!(inner);
//! }
//! ```
//!
//! See RFC 0014 for the deprecated hooks these traits replace and the
//! migration guide.
pub use ;
pub use ;
pub use ColumnarDriver;
pub use ;
pub use ColumnarStream;
pub use ;