11use {
22 crate :: { Column , Index } ,
33 serde:: { Deserialize , Serialize } ,
4+ std:: collections:: HashMap ,
45} ;
56
67#[ derive( Clone , Serialize , Deserialize ) ]
@@ -9,3 +10,175 @@ pub struct Schema {
910 pub column_defs : Vec < Column > ,
1011 pub indexes : Vec < Index > ,
1112}
13+
14+ #[ derive( Clone , Default ) ]
15+ pub struct SchemaDiff {
16+ pub table_name : Option < String > ,
17+ pub column_defs : Option < HashMap < Option < usize > , Option < Column > > > ,
18+ pub indexes : Option < HashMap < Option < usize > , Option < Index > > > ,
19+ }
20+ impl SchemaDiff {
21+ pub fn new_rename ( new_name : String ) -> Self {
22+ Self {
23+ table_name : Some ( new_name) ,
24+ column_defs : None ,
25+ indexes : None ,
26+ }
27+ }
28+ pub fn new_add_column ( new_column : Column ) -> Self {
29+ Self {
30+ table_name : None ,
31+ column_defs : Some ( [ ( None , Some ( new_column) ) ] . into ( ) ) ,
32+ indexes : None ,
33+ }
34+ }
35+ pub fn new_remove_column ( column_index : usize ) -> Self {
36+ Self {
37+ table_name : None ,
38+ column_defs : Some ( [ ( Some ( column_index) , None ) ] . into ( ) ) ,
39+ indexes : None ,
40+ }
41+ }
42+ pub fn new_rename_column (
43+ column_index : usize ,
44+ mut column : Column ,
45+ new_column_name : String ,
46+ ) -> Self {
47+ column. name = new_column_name;
48+ Self {
49+ table_name : None ,
50+ column_defs : Some ( [ ( Some ( column_index) , Some ( column) ) ] . into ( ) ) ,
51+ indexes : None ,
52+ }
53+ }
54+ pub fn new_add_index ( new_index : Index ) -> Self {
55+ Self {
56+ table_name : None ,
57+ column_defs : None ,
58+ indexes : Some ( [ ( None , Some ( new_index) ) ] . into ( ) ) ,
59+ }
60+ }
61+ }
62+
63+ impl SchemaDiff {
64+ pub fn merge ( self , mut schema : Schema ) -> Schema {
65+ if let Some ( table_name) = self . table_name {
66+ schema. table_name = table_name
67+ }
68+ if let Some ( column_defs) = self . column_defs {
69+ for ( index, column_def) in column_defs. into_iter ( ) {
70+ match ( index, column_def) {
71+ ( None , None ) => ( ) ,
72+ ( Some ( index) , None ) => {
73+ schema. column_defs . remove ( index) ;
74+ } // TODO: WARN: Will be an issue if multiple change
75+ ( Some ( index) , Some ( column_def) ) => {
76+ schema
77+ . column_defs
78+ . get_mut ( index)
79+ . map ( |old_column_def| * old_column_def = column_def) ;
80+ }
81+ ( None , Some ( column_def) ) => {
82+ schema. column_defs . push ( column_def) ;
83+ }
84+ }
85+ }
86+ }
87+ if let Some ( indexes) = self . indexes {
88+ for ( index, index_def) in indexes. into_iter ( ) {
89+ match ( index, index_def) {
90+ ( None , None ) => ( ) ,
91+ ( Some ( index) , None ) => {
92+ schema. indexes . remove ( index) ;
93+ } // TODO: WARN: Will be an issue if multiple change
94+ ( Some ( index) , Some ( index_def) ) => {
95+ schema
96+ . indexes
97+ . get_mut ( index)
98+ . map ( |old_index_def| * old_index_def = index_def) ;
99+ }
100+ ( None , Some ( index_def) ) => {
101+ schema. indexes . push ( index_def) ;
102+ }
103+ }
104+ }
105+ }
106+ schema
107+ }
108+ }
109+
110+ impl From < Schema > for SchemaDiff {
111+ fn from ( from : Schema ) -> Self {
112+ let column_defs = from
113+ . column_defs
114+ . into_iter ( )
115+ . enumerate ( )
116+ . map ( |( key, col) | ( Some ( key) , Some ( col) ) )
117+ . collect :: < HashMap < Option < usize > , Option < Column > > > ( ) ;
118+ let indexes = from
119+ . indexes
120+ . into_iter ( )
121+ . enumerate ( )
122+ . map ( |( key, idx) | ( Some ( key) , Some ( idx) ) )
123+ . collect :: < HashMap < Option < usize > , Option < Index > > > ( ) ;
124+ Self {
125+ table_name : Some ( from. table_name ) ,
126+ column_defs : Some ( column_defs) ,
127+ indexes : Some ( indexes) ,
128+ }
129+ }
130+ }
131+
132+ pub enum SchemaChange {
133+ RenameTable ( String ) ,
134+
135+ ColumnUpdate ( usize , Column ) ,
136+ ColumnAdd ( Column ) ,
137+ ColumnRemove ( usize ) ,
138+
139+ IndexUpdate ( usize , Index ) ,
140+ IndexAdd ( Index ) ,
141+ IndexRemove ( usize ) ,
142+ }
143+ impl SchemaDiff {
144+ pub fn get_changes ( & self ) -> Vec < SchemaChange > {
145+ use SchemaChange :: * ;
146+ let mut changes = Vec :: new ( ) ;
147+ if let Some ( table_name) = & self . table_name {
148+ changes. push ( RenameTable ( table_name. clone ( ) ) )
149+ }
150+ if let Some ( column_defs) = & self . column_defs {
151+ for ( index, column_def) in column_defs. into_iter ( ) {
152+ match ( index, column_def) {
153+ ( None , None ) => ( ) ,
154+ ( Some ( index) , Some ( column_def) ) => {
155+ changes. push ( ColumnUpdate ( * index, column_def. clone ( ) ) ) ;
156+ }
157+ ( None , Some ( column_def) ) => {
158+ changes. push ( ColumnAdd ( column_def. clone ( ) ) ) ;
159+ }
160+ ( Some ( index) , None ) => {
161+ changes. push ( ColumnRemove ( * index) ) ;
162+ }
163+ }
164+ }
165+ }
166+ if let Some ( indexes) = & self . indexes {
167+ for ( index, index_def) in indexes. into_iter ( ) {
168+ match ( index, index_def) {
169+ ( None , None ) => ( ) ,
170+ ( Some ( index) , Some ( index_def) ) => {
171+ changes. push ( IndexUpdate ( * index, index_def. clone ( ) ) ) ;
172+ }
173+ ( None , Some ( index_def) ) => {
174+ changes. push ( IndexAdd ( index_def. clone ( ) ) ) ;
175+ }
176+ ( Some ( index) , None ) => {
177+ changes. push ( IndexRemove ( * index) ) ;
178+ }
179+ }
180+ }
181+ }
182+ changes
183+ }
184+ }
0 commit comments