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
//! Persist review conversations, identities and sessions through scoped repositories.
//!
//! Use [`Database`] for a shared connection pool. Begin a [`Transaction`] to compose
//! writes across repositories; commit explicitly or drop it to roll back.
//! Returned [`models`] are SeaORM values. Writes go through [`repositories`];
//! application validation and workflow orchestration belong to backend services.
//!
//! # Examples
//!
//! ```
//! use lgtm_db::{Database, models::identities, types::IdentityKind};
//! # #[tokio::main]
//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let db = Database::connect("sqlite::memory:").await?;
//! let actor = identities::Model {
//! id: uuid::Uuid::new_v4(), name: "Alice".into(), kind: IdentityKind::Human,
//! email: Some("alice@example.com".into()), model: None, provider: None,
//! forge_account: String::new(),
//! };
//! let tx = db.begin().await?;
//! tx.identities.insert(&actor).await?;
//! assert_eq!(tx.identities.get_by_id(&actor.id).await?, Some(actor));
//! tx.commit().await?;
//! db.close().await;
//! # Ok(()) }
//! ```
//!
//! # Storage and features
//!
//! Internal keys are typed UUIDs. External forge IDs are opaque strings, scoped by
//! context and object kind. Forge repositories use complete repository URLs.
//! Local contexts use notes paths or Git-directory/branch pairs.
//! The default `sqlite` feature enables SQLite; `postgres` adds PostgreSQL.
//! One private Rust migration history is applied when opening the database.
//!
//! # API boundaries
//!
//! Entity module paths are private; row models are exported via `models`:
//! ```compile_fail
//! use lgtm_db::entities::comments::Model;
//! ```
//! Raw connections are not part of the client API:
//! ```compile_fail
//! fn inspect(db: &lgtm_db::Database) { let _ = db.connection(); }
//! ```
//! Model modules do not re-export active model or entity names:
//! ```compile_fail
//! use lgtm_db::models::comments::ActiveModel;
//! ```
//! ```compile_fail
//! use lgtm_db::models::comments::Entity;
//! ```
//! Returned models retain their SeaORM traits, but the database handle cannot
//! be used as a raw connection for direct ORM writes:
//! ```compile_fail
//! use sea_orm::{ActiveModelTrait, IntoActiveModel};
//! async fn bypass(db: &lgtm_db::Database, comment: lgtm_db::models::comments::Model) {
//! comment.into_active_model().update(db).await.unwrap();
//! }
//! ```
//! Migration internals are not a client operation:
//! ```compile_fail
//! use lgtm_db::migration::Migrator;
//! ```
//! Profile editing is not exposed:
//! ```compile_fail
//! async fn rename(db: &lgtm_db::Database) {
//! db.identities.rename("id", "Name", "email@example.com").await;
//! }
//! ```
pub use ;
/// Typed database discriminators.
pub use common as types;