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
use std::collections::HashMap;
use versatile_data::{
IdxSized
,Activity
,FieldData
,Condition
,Term
};
use super::Database;
mod operation;
pub use operation::{
Record
,SessionOperation
,UpdateDepends
};
mod sequence_number;
use sequence_number::SequenceNumber;
mod relation;
use relation::SessionRelation;
mod update;
use update::*;
struct SessionData{
sequence_number:SequenceNumber
,sequence:IdxSized<usize>
,collection_id:IdxSized<i32>
,collection_row:IdxSized<u32>
,operation:IdxSized<SessionOperation>
,activity: IdxSized<u8>
,term_begin: IdxSized<i64>
,term_end: IdxSized<i64>
,fields:HashMap<String,FieldData>
,relation:SessionRelation
}
pub struct Session<'a>{
main_database:&'a mut Database
,session_dir:String
,data:Option<SessionData>
,search_condition:Vec<Condition>
}
impl<'a> Session<'a>{
pub fn new(
main_database:&'a mut Database
,session_name:&'a str
)->Result<Session,std::io::Error>{
let session_dir=main_database.root_dir().to_string()+"/sessions/"+session_name;
if !std::path::Path::new(&session_dir).exists(){
std::fs::create_dir_all(&session_dir).unwrap();
}
Ok(Session{
main_database
,session_dir:session_dir.to_string()
,data:Some(Self::new_data(&session_dir)?)
,search_condition:Vec::new()
})
}
fn new_data(session_dir:&str)->Result<SessionData,std::io::Error>{
Ok(SessionData{
sequence_number:SequenceNumber::new(&(session_dir.to_string()+"/sequece_number.i"))?
,sequence:IdxSized::new(&(session_dir.to_string()+"/sequence.i"))?
,collection_id:IdxSized::new(&(session_dir.to_string()+"/collection_id.i"))?
,collection_row:IdxSized::new(&(session_dir.to_string()+"/collection_row.i"))?
,operation:IdxSized::new(&(session_dir.to_string()+"/operation.i"))?
,activity:IdxSized::new(&(session_dir.to_string()+"/activity.i"))?
,term_begin:IdxSized::new(&(session_dir.to_string()+"/term_begin.i"))?
,term_end:IdxSized::new(&(session_dir.to_string()+"/term_end.i"))?
,fields:HashMap::new()
,relation:SessionRelation::new(&session_dir)
})
}
pub fn clear(&mut self){
self.data=None;
if std::path::Path::new(&self.session_dir).exists(){
std::fs::remove_dir_all(&self.session_dir).unwrap();
}
}
pub fn public(&mut self){
if let Some(ref mut data)=self.data{
public(data,self.main_database);
self.clear();
}
}
pub fn update(&mut self,records:Vec::<Record>){
match self.data{
Some(ref mut data)=>{
let sequence=data.sequence_number.next();
update_recursive(&self.main_database,data,&self.session_dir,sequence,&records,None);
}
,None=>{
if let Ok(data)=Self::new_data(&self.session_dir){
self.data=Some(data);
if let Some(ref mut data)=self.data{
let sequence=data.sequence_number.next();
update_recursive(&self.main_database,data,&self.session_dir,sequence,&records,None);
}
}
}
}
}
pub fn search_default(mut self)->Self{
self.search_condition.push(Condition::Term(Term::In(chrono::Local::now().timestamp())));
self.search_condition.push(Condition::Activity(Activity::Active));
self
}
pub fn search(mut self,condition:Condition)->Self{
self.search_condition.push(condition);
self
}
}