-
Notifications
You must be signed in to change notification settings - Fork 2
/
vtable_repository_impl.rs
128 lines (110 loc) · 4.22 KB
/
vtable_repository_impl.rs
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use crate::sqlite::{
sqlite_rowid::SqliteRowid,
transaction::{
sqlite_tx::{
dao::{NaviDao, SqliteMasterDao, VersionDao},
SqliteTx,
},
VTableDao,
},
};
use apllodb_immutable_schema_engine_domain::{
row::column::non_pk_column::column_name::NonPKColumnName,
row_iter::ImmutableSchemaRowIter,
traits::{VTableRepository, VersionRepository},
transaction::ImmutableSchemaTx,
version::{active_versions::ActiveVersions, id::VersionId},
vtable::{id::VTableId, VTable},
};
use apllodb_shared_components::error::ApllodbResult;
use std::collections::VecDeque;
#[derive(Debug)]
pub struct VTableRepositoryImpl<'tx, 'db: 'tx> {
tx: &'tx SqliteTx<'db>,
}
impl<'tx, 'db: 'tx> VTableRepository<'tx, 'db> for VTableRepositoryImpl<'tx, 'db> {
type Tx = SqliteTx<'db>;
fn new(tx: &'tx Self::Tx) -> Self {
Self { tx }
}
/// # Failures
///
/// - [DuplicateTable](error/enum.ApllodbErrorKind.html#variant.DuplicateTable) when:
/// - Table `table_name` is already visible to this transaction.
/// - Errors from [TableDao::create()](foobar.html).
fn create(&self, vtable: &VTable) -> ApllodbResult<()> {
self.vtable_dao().insert(&vtable)?;
self.navi_dao().create_table(&vtable)?;
Ok(())
}
/// # Failures
///
/// - [IoError](error/enum.ApllodbErrorKind.html#variant.IoError) when:
/// - rusqlite raises an error.
/// - [UndefinedTable](error/enum.ApllodbErrorKind.html#variant.UndefinedTable) when:
/// - Table `table_name` is not visible to this transaction.
fn read(&self, vtable_id: &VTableId) -> ApllodbResult<VTable> {
self.vtable_dao().select(&vtable_id)
}
/// # Failures
///
/// - [UndefinedTable](error/enum.ApllodbErrorKind.html#variant.UndefinedTable) when:
/// - Table `table_name` is not visible to this transaction.
/// - [IoError](error/enum.ApllodbErrorKind.html#variant.IoError) when:
/// - rusqlite raises an error.
fn update(&self, _vtable: &VTable) -> ApllodbResult<()> {
// TODO update VTable on TableWideConstraints change.
Ok(())
}
fn full_scan(
&self,
vtable_id: &VTableId,
projection: &[NonPKColumnName],
) -> ApllodbResult<
ImmutableSchemaRowIter<
<<Self::Tx as ImmutableSchemaTx<'tx, 'db>>::VRepo as VersionRepository<'tx, 'db>>::VerRowIter,
>,
>{
let mut ver_row_iters: VecDeque<<<Self::Tx as ImmutableSchemaTx<'tx, 'db>>::VRepo as VersionRepository<'tx, 'db>>::VerRowIter> = VecDeque::new();
let vtable = self.vtable_dao().select(vtable_id)?;
let navi_collection = self.navi_dao().full_scan_latest_revision(&vtable)?;
for (version_number, navi_collection) in navi_collection.group_by_version_number()? {
let version_id = VersionId::new(&vtable_id, &version_number);
let version = self
.sqlite_master_dao()
.select_active_version(&vtable, &version_id)?;
let ver_row_iter = self.version_dao().join_with_navi(
&vtable,
&version,
&navi_collection
.map(|navi| navi.map(|n| n.rowid))
.collect::<ApllodbResult<Vec<SqliteRowid>>>()?,
projection,
)?;
ver_row_iters.push_back(ver_row_iter);
}
Ok(ImmutableSchemaRowIter::chain(ver_row_iters))
}
fn delete_all(&self, vtable: &VTable) -> ApllodbResult<()> {
self.navi_dao().insert_deleted_records_all(&vtable)?;
Ok(())
}
fn active_versions(&self, vtable: &VTable) -> ApllodbResult<ActiveVersions> {
let active_versions = self.sqlite_master_dao().select_active_versions(vtable)?;
Ok(ActiveVersions::from(active_versions))
}
}
impl<'tx, 'db: 'tx> VTableRepositoryImpl<'tx, 'db> {
fn vtable_dao(&self) -> VTableDao<'tx, 'db> {
VTableDao::new(&self.tx)
}
fn version_dao(&self) -> VersionDao<'tx, 'db> {
VersionDao::new(&self.tx)
}
fn navi_dao(&self) -> NaviDao<'tx, 'db> {
NaviDao::new(&self.tx)
}
fn sqlite_master_dao(&self) -> SqliteMasterDao<'tx, 'db> {
SqliteMasterDao::new(&self.tx)
}
}