1
1
use std:: {
2
2
fs:: File ,
3
3
error:: Error ,
4
-
5
- io:: {
6
- self ,
7
- Write ,
8
- BufWriter
9
- } ,
10
- } ;
11
-
12
- use flate2:: {
13
- Compression ,
14
- write:: GzEncoder
15
4
} ;
16
5
17
6
use mysql:: {
18
7
* ,
19
- Row ,
20
8
prelude:: *
21
9
} ;
22
10
23
11
use crate :: {
24
- ui:: success_alerts:: SuccessAlerts ,
25
-
26
- utils:: {
27
- date:: Date ,
28
- file:: FileUtils
29
- } ,
12
+ utils:: file:: FileUtils ,
13
+ ui:: success_alerts:: SuccessAlerts ,
14
+ helpers:: export_handlers:: ExportHandlers ,
30
15
31
16
engine:: {
32
17
configs:: Configs ,
33
18
connection:: Connection
34
19
} ,
35
20
} ;
36
21
37
- enum Writer {
38
- Compressed ( BufWriter < GzEncoder < File > > ) ,
39
- Uncompressed ( BufWriter < File > ) ,
40
- }
41
-
42
- impl Writer {
43
- fn as_write ( & mut self ) -> & mut dyn Write {
44
- match self {
45
- Writer :: Compressed ( w) => w,
46
- Writer :: Uncompressed ( w) => w,
47
- }
48
- }
49
- }
50
-
51
22
pub struct Export {
52
23
pub host : String ,
53
24
pub port : u16 ,
@@ -58,8 +29,15 @@ pub struct Export {
58
29
}
59
30
60
31
impl Export {
61
-
62
- pub fn new ( host : & str , port : u16 , user : & str , password : & str , dbname : & str , dump_file_path : & str ) -> Self {
32
+
33
+ pub fn new (
34
+ host : & str ,
35
+ port : u16 ,
36
+ user : & str ,
37
+ password : & str ,
38
+ dbname : & str ,
39
+ dump_file_path : & str
40
+ ) -> Self {
63
41
Self {
64
42
host : host. to_string ( ) ,
65
43
port,
@@ -70,85 +48,6 @@ impl Export {
70
48
}
71
49
}
72
50
73
- fn create_writer ( & self , file : File , compress_data : bool ) -> Writer {
74
- if compress_data {
75
- let encoder = GzEncoder :: new ( file, Compression :: default ( ) ) ;
76
- Writer :: Compressed ( BufWriter :: new ( encoder) )
77
- } else {
78
- Writer :: Uncompressed ( BufWriter :: new ( file) )
79
- }
80
- }
81
-
82
- fn comments_header ( & self , writer : & mut dyn Write ) -> Result < ( ) , Box < dyn Error > > {
83
- writeln ! ( writer, "-- Exporting using {} v.{}" , env!( "CARGO_PKG_NAME" ) , env!( "CARGO_PKG_VERSION" ) ) ?;
84
- writeln ! ( writer, "-- Database backup: {}" , self . dbname) ?;
85
- writeln ! ( writer, "-- Export date and time: {}" , Date :: timestamp( ) ) ?;
86
- writeln ! ( writer, "-- ---------------------------------------------------\n " ) ?;
87
-
88
- Ok ( ( ) )
89
- }
90
-
91
- fn write_create_new_database ( & self , writer : & mut dyn Write ) -> Result < ( ) , Box < dyn Error > > {
92
- let database_if_not_exists = Configs . boolean ( "exports" , "database_if_not_exists" , true ) ;
93
-
94
- if database_if_not_exists {
95
- writeln ! ( writer, "CREATE DATABASE IF NOT EXISTS `{}`;" , self . dbname) ?;
96
- writeln ! ( writer, "USE `{}`;" , self . dbname) ?;
97
- writeln ! ( writer, "-- ---------------------------------------------------\n " ) ?;
98
- }
99
- Ok ( ( ) )
100
- }
101
-
102
- fn write_inserts_for_table ( & self , table : & str , conn : & mut PooledConn , writer : & mut dyn Write ) -> Result < ( ) , Box < dyn Error > > {
103
- let dump_data = Configs . boolean ( "exports" , "dump_data" , true ) ;
104
- let insert_ignore_into = Configs . boolean ( "exports" , "insert_ignore_into" , false ) ;
105
-
106
- if dump_data {
107
- let rows: Vec < Row > = conn. query ( format ! ( "SELECT * FROM `{}`" , table) ) ?;
108
-
109
- if rows. is_empty ( ) {
110
- writeln ! ( writer, "-- Table `{}` contains no data." , table) ?;
111
- } else {
112
- for row in rows {
113
- let values: Vec < String > = row. clone ( ) . unwrap ( ) . into_iter ( ) . map ( |value| match value {
114
- Value :: NULL => "NULL" . to_string ( ) ,
115
- Value :: Bytes ( bytes) => format ! ( "'{}'" , String :: from_utf8_lossy( & bytes) ) ,
116
- Value :: Int ( int) => int. to_string ( ) ,
117
- Value :: UInt ( uint) => uint. to_string ( ) ,
118
- Value :: Float ( float) => float. to_string ( ) ,
119
- _ => "NULL" . to_string ( ) ,
120
- } ) . collect ( ) ;
121
-
122
- let line = if insert_ignore_into {
123
- format ! ( "INSERT IGNORE INTO `{}` VALUES ({});" , table, values. join( ", " ) )
124
- } else {
125
- format ! ( "INSERT INTO `{}` VALUES ({});" , table, values. join( ", " ) )
126
- } ;
127
-
128
- writeln ! ( writer, "{}" , line) ?;
129
- }
130
- }
131
- }
132
-
133
- Ok ( ( ) )
134
- }
135
-
136
- fn write_structure_for_table ( & self , table : & str , conn : & mut PooledConn , writer : & mut dyn Write ) -> Result < ( ) , Box < dyn Error > > {
137
- let drop_table_if_exists = Configs . boolean ( "exports" , "drop_table_if_exists" , false ) ;
138
-
139
- writeln ! ( writer, "-- Exporting the table: `{}`" , table) ?;
140
-
141
- if drop_table_if_exists {
142
- writeln ! ( writer, "DROP TABLE IF EXISTS `{}`;" , table) ?;
143
- }
144
-
145
- let row: Row = conn. query_first ( format ! ( "SHOW CREATE TABLE `{}`" , table) ) ?. unwrap ( ) ;
146
- let create_table: String = row. get ( 1 ) . expect ( "Error retrieving CREATE TABLE" ) ;
147
- writeln ! ( writer, "{};\n " , create_table) ?;
148
-
149
- Ok ( ( ) )
150
- }
151
-
152
51
pub fn dump ( & self ) -> Result < ( ) , Box < dyn Error > > {
153
52
let compress_data = Configs . boolean ( "exports" , "compress_data" , false ) ;
154
53
@@ -158,6 +57,11 @@ impl Export {
158
57
self . dump_file_path . clone ( )
159
58
} ;
160
59
60
+ let export_handlers = ExportHandlers :: new (
61
+ File :: create ( dump_file_path. clone ( ) ) ?,
62
+ & self . dbname
63
+ ) ;
64
+
161
65
let pool = Connection {
162
66
host : self . host . clone ( ) ,
163
67
port : self . port ,
@@ -166,14 +70,13 @@ impl Export {
166
70
dbname : Some ( self . dbname . clone ( ) ) ,
167
71
} . create_pool ( ) ?;
168
72
169
- FileUtils :: create_path ( & dump_file_path) ;
73
+ FileUtils :: create_path ( & dump_file_path. clone ( ) ) ;
170
74
171
75
let mut conn = pool. get_conn ( ) ?;
172
- let file = File :: create ( & dump_file_path) ?;
173
- let mut writer = self . create_writer ( file, compress_data) ;
76
+ let mut writer = export_handlers. create_writer ( ) ?;
174
77
175
- self . comments_header ( writer. as_write ( ) ) ?;
176
- self . write_create_new_database ( writer. as_write ( ) ) ?;
78
+ export_handlers . comments_header ( writer. as_write ( ) ) ?;
79
+ export_handlers . write_create_new_database ( writer. as_write ( ) ) ?;
177
80
178
81
let tables: Vec < String > = conn. query ( "SHOW TABLES" ) ?;
179
82
let ignore_tables = Configs . list ( "exports" , "ignore_tables" ) . unwrap_or_default ( ) ;
@@ -184,13 +87,12 @@ impl Export {
184
87
continue ;
185
88
}
186
89
187
- self . write_structure_for_table ( & table, & mut conn, writer. as_write ( ) ) ?;
188
- self . write_inserts_for_table ( & table, & mut conn, writer. as_write ( ) ) ?;
90
+ export_handlers . write_structure_for_table ( & table, & mut conn, writer. as_write ( ) ) ?;
91
+ export_handlers . write_inserts_for_table ( & table, & mut conn, writer. as_write ( ) ) ?;
189
92
writeln ! ( writer. as_write( ) , "-- End of table `{}`" , table) ?;
190
93
}
191
94
192
95
SuccessAlerts :: dump ( & dump_file_path) ;
193
- io:: stdout ( ) . flush ( ) . unwrap ( ) ;
194
96
195
97
Ok ( ( ) )
196
98
}
0 commit comments