1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *    http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 use std::fs;
17 
18 use asset_common::CallingInfo;
19 use asset_definition::{DataType, Extension, Value};
20 
21 use crate::{
22     database::Database,
23     statement::Statement,
24     table::Table,
25     types::{ColumnInfo, DbMap, SQLITE_DONE, SQLITE_ROW},
26 };
27 
28 #[test]
create_delete_table()29 fn create_delete_table() {
30     fs::create_dir_all("/data/asset_test/0").unwrap();
31     let columns = &[
32         ColumnInfo { name: "id", is_primary_key: true, not_null: true, data_type: DataType::Number },
33         ColumnInfo { name: "alias", is_primary_key: false, not_null: true, data_type: DataType::Bytes },
34     ];
35     let calling_info = CallingInfo::new_self();
36     let mut db =
37         Database::build(calling_info.user_id(), calling_info.owner_type_enum(), calling_info.owner_info(), false)
38             .unwrap();
39     let table = Table::new("table_name", &db);
40     assert!(!table.exist().unwrap());
41     assert!(table.create(columns).is_ok());
42     assert!(table.exist().unwrap());
43     table.delete().unwrap();
44     db.close_db();
45     fs::remove_dir_all("/data/asset_test/0").unwrap();
46 }
47 
48 #[test]
table_restore()49 fn table_restore() {
50     fs::create_dir_all("/data/asset_test/0").unwrap();
51     let calling_info = CallingInfo::new_self();
52     let mut db =
53         Database::build(calling_info.user_id(), calling_info.owner_type_enum(), calling_info.owner_info(), false)
54             .unwrap();
55     let table = Table::new("table_name", &db);
56     table
57         .create(&[ColumnInfo { name: "Id", data_type: DataType::Number, is_primary_key: true, not_null: true }])
58         .unwrap();
59     let count = table.insert_row(&DbMap::from([("Id", Value::Number(1))])).unwrap();
60     assert_eq!(count, 1);
61     fs::copy(
62         "/data/asset_test/0/Native_asset_service_8100.db",
63         "/data/asset_test/0/Native_asset_service_8100.db.backup",
64     )
65     .unwrap();
66     db.close_db();
67 
68     fs::remove_file("/data/asset_test/0/Native_asset_service_8100.db").unwrap();
69     fs::copy(
70         "/data/asset_test/0/Native_asset_service_8100.db.backup",
71         "/data/asset_test/0/Native_asset_service_8100.db",
72     )
73     .unwrap();
74     db.open().unwrap();
75     let table = Table::new("table_name", &db);
76     let count = table.count_datas(&DbMap::new(), false).unwrap();
77     assert_eq!(count, 1);
78     db.close_db();
79     fs::remove_dir_all("/data/asset_test/0").unwrap();
80 }
81 
82 #[cfg(test)]
insert_test_data() -> Database83 fn insert_test_data() -> Database {
84     fs::create_dir_all("/data/asset_test/0").unwrap();
85     let calling_info = CallingInfo::new_self();
86     let db = Database::build(calling_info.user_id(), calling_info.owner_type_enum(), calling_info.owner_info(), false)
87         .unwrap();
88     let columns = &[
89         ColumnInfo { name: "Id", is_primary_key: true, not_null: true, data_type: DataType::Number },
90         ColumnInfo { name: "Owner", is_primary_key: false, not_null: true, data_type: DataType::Bytes },
91         ColumnInfo { name: "Alias", is_primary_key: false, not_null: true, data_type: DataType::Bytes },
92         ColumnInfo { name: "value", is_primary_key: false, not_null: true, data_type: DataType::Bytes },
93     ];
94     let table = Table::new("table_name", &db);
95     table.create(columns).unwrap();
96 
97     let mut datas = DbMap::new();
98     datas.insert_attr("Owner", b"owner1".to_vec());
99     datas.insert_attr("Alias", b"alias1".to_vec());
100     datas.insert_attr("value", b"aaaa".to_vec());
101     assert_eq!(1, table.insert_row(&datas).unwrap());
102 
103     datas.insert_attr("Owner", b"owner2".to_vec());
104     datas.insert_attr("Alias", b"alias2".to_vec());
105     datas.insert_attr("value", b"bbbb".to_vec());
106     assert_eq!(1, table.insert_row(&datas).unwrap());
107 
108     datas.insert_attr("Owner", b"owner2".to_vec());
109     datas.insert_attr("Alias", b"alias3".to_vec());
110     datas.insert_attr("value", b"cccc".to_vec());
111     assert_eq!(1, table.insert_row(&datas).unwrap());
112     db
113 }
114 
115 #[test]
execute_sql()116 fn execute_sql() {
117     fs::create_dir_all("/data/asset_test/0").unwrap();
118     let db = insert_test_data();
119     let sql = "select Owner,Alias from table_name where Id>?";
120     let stmt = Statement::prepare(sql, &db).unwrap();
121     assert!(stmt.bind_data(1, &Value::Number(1)).is_ok());
122 
123     let mut count = 0;
124     while stmt.step().unwrap() == SQLITE_ROW {
125         count += 1;
126     }
127     assert_eq!(count, 2);
128     fs::remove_dir_all("/data/asset_test/0").unwrap();
129 }
130 
131 #[test]
data_life_circle()132 fn data_life_circle() {
133     fs::create_dir_all("/data/asset_test/0").unwrap();
134     let db = insert_test_data();
135     let mut datas = DbMap::new();
136     datas.insert_attr("Owner", b"owner1".to_vec());
137     datas.insert_attr("Alias", b"alias1".to_vec());
138     let table = Table::new("table_name", &db);
139     assert!(table.is_data_exists(&datas, false).unwrap());
140 
141     datas.insert_attr("Owner", b"owner1".to_vec());
142     datas.insert_attr("Alias", b"alias2".to_vec());
143     assert!(!table.is_data_exists(&datas, false).unwrap());
144 
145     datas.insert_attr("Owner", b"owner2".to_vec());
146     datas.insert_attr("Alias", b"alias3".to_vec());
147     assert_eq!(1, table.update_row(&datas, false, &DbMap::from([("value", Value::Bytes(b"dddd".to_vec()))])).unwrap());
148     assert_eq!(1, table.delete_row(&datas, None, false).unwrap());
149     fs::remove_dir_all("/data/asset_test/0").unwrap();
150 }
151 
152 #[test]
single_data()153 fn single_data() {
154     fs::create_dir_all("/data/asset_test/0").unwrap();
155     let calling_info = CallingInfo::new_self();
156     let db = Database::build(calling_info.user_id(), calling_info.owner_type_enum(), calling_info.owner_info(), false)
157         .unwrap();
158     let table = Table::new("table_name", &db);
159     let columns = &[
160         ColumnInfo { name: "id", is_primary_key: true, not_null: true, data_type: DataType::Number },
161         ColumnInfo { name: "alias", is_primary_key: false, not_null: true, data_type: DataType::Bytes },
162     ];
163     table.create(columns).unwrap();
164     db.exec("insert into table_name values(1, 'test')").unwrap();
165 
166     let stmt = Statement::prepare("select id,alias from table_name where id < ?", &db).unwrap();
167     stmt.bind_data(1, &Value::Number(1000)).unwrap();
168 
169     while stmt.step().unwrap() == SQLITE_ROW {
170         let count = stmt.data_count();
171         assert_eq!(2, count);
172 
173         assert_eq!("id", stmt.query_column_name(0).unwrap());
174         assert_eq!("alias", stmt.query_column_name(1).unwrap());
175 
176         let id = stmt.query_column_int(0);
177         let alias = stmt.query_column_blob(1);
178         assert_eq!(1, id);
179         assert_eq!("test".as_bytes(), alias);
180     }
181     drop(stmt);
182     fs::remove_dir_all("/data/asset_test/0").unwrap();
183 }
184 
185 #[test]
multiple_data()186 fn multiple_data() {
187     fs::create_dir_all("/data/asset_test/0").unwrap();
188     let calling_info = CallingInfo::new_self();
189     let db = Database::build(calling_info.user_id(), calling_info.owner_type_enum(), calling_info.owner_info(), false)
190         .unwrap();
191     let table = Table::new("table_name", &db);
192     let columns = &[
193         ColumnInfo { name: "id", is_primary_key: true, not_null: true, data_type: DataType::Number },
194         ColumnInfo { name: "alias", is_primary_key: false, not_null: true, data_type: DataType::Bytes },
195     ];
196     table.create(columns).unwrap();
197     let data_set = &[
198         [Value::Number(2), Value::Bytes(b"test2".to_vec())],
199         [Value::Number(3), Value::Bytes(b"test3".to_vec())],
200         [Value::Number(4), Value::Bytes(b"test4".to_vec())],
201     ];
202     let stmt = Statement::prepare("insert into table_name values(?, ?)", &db).unwrap();
203     for data in data_set {
204         stmt.reset().unwrap();
205         stmt.bind_data(1, &data[0]).unwrap();
206         stmt.bind_data(2, &data[1]).unwrap();
207         assert_eq!(SQLITE_DONE, stmt.step().unwrap());
208     }
209 
210     let stmt = Statement::prepare("select id,alias from table_name where id < ?", &db).unwrap();
211     stmt.bind_data(1, &Value::Number(1000)).unwrap();
212     let mut index = 0;
213     while stmt.step().unwrap() == SQLITE_ROW {
214         let data_count = stmt.data_count();
215         assert_eq!(data_count, 2);
216 
217         let id = stmt.query_column_int(0);
218         let alias = stmt.query_column_blob(1);
219         assert_eq!(data_set[index][0], Value::Number(id));
220         assert_eq!(data_set[index][1], Value::Bytes(alias.to_vec()));
221         index += 1;
222     }
223     assert!(table.delete().is_ok());
224     fs::remove_dir_all("/data/asset_test/0").unwrap();
225 }
226 
227 #[test]
insert_query_row()228 fn insert_query_row() {
229     fs::create_dir_all("/data/asset_test/0").unwrap();
230     let calling_info = CallingInfo::new_self();
231     let db = Database::build(calling_info.user_id(), calling_info.owner_type_enum(), calling_info.owner_info(), false)
232         .unwrap();
233     let table = Table::new("table_name", &db);
234 
235     let columns = &[
236         ColumnInfo { name: "id", is_primary_key: true, not_null: true, data_type: DataType::Number },
237         ColumnInfo { name: "alias", is_primary_key: false, not_null: true, data_type: DataType::Bytes },
238     ];
239     table.create(columns).unwrap();
240 
241     let datas = DbMap::from([("id", Value::Number(3)), ("alias", Value::Bytes(b"alias1".to_vec()))]);
242     assert_eq!(table.insert_row(&datas).unwrap(), 1);
243     let datas = DbMap::from([("alias", Value::Bytes(b"alias1".to_vec()))]);
244     assert_eq!(table.insert_row(&datas).unwrap(), 1);
245 
246     let result_set = table.query_row(&vec![], &DbMap::new(), None, false, columns).unwrap();
247     assert_eq!(result_set.len(), 2);
248 
249     let count = table.count_datas(&DbMap::new(), false).unwrap();
250     assert_eq!(count, 2);
251     let count = table.count_datas(&DbMap::from([("id", Value::Number(3))]), false).unwrap();
252     assert_eq!(count, 1);
253 
254     fs::remove_dir_all("/data/asset_test/0").unwrap();
255 }
256 
257 #[test]
update_delete_row()258 fn update_delete_row() {
259     fs::create_dir_all("/data/asset_test/0").unwrap();
260     let calling_info = CallingInfo::new_self();
261     let db = Database::build(calling_info.user_id(), calling_info.owner_type_enum(), calling_info.owner_info(), false)
262         .unwrap();
263     let table = Table::new("table_name", &db);
264 
265     let columns = &[
266         ColumnInfo { name: "id", is_primary_key: true, not_null: true, data_type: DataType::Number },
267         ColumnInfo { name: "alias", is_primary_key: false, not_null: true, data_type: DataType::Bytes },
268     ];
269     table.create(columns).unwrap();
270     let datas = DbMap::from([("id", Value::Number(1)), ("alias", Value::Bytes(b"alias1".to_vec()))]);
271     assert_eq!(table.insert_row(&datas).unwrap(), 1);
272     let datas = DbMap::from([("id", Value::Number(2)), ("alias", Value::Bytes(b"alias2".to_vec()))]);
273     assert_eq!(table.insert_row(&datas).unwrap(), 1);
274 
275     let conditions = DbMap::from([("id", Value::Number(2))]);
276     let datas = DbMap::from([("alias", Value::Bytes(b"test_update".to_vec()))]);
277     assert_eq!(table.update_row(&conditions, false, &datas).unwrap(), 1);
278     assert!(table.is_data_exists(&datas, false).unwrap());
279     assert_eq!(table.delete_row(&conditions, None, false).unwrap(), 1);
280     assert!(!table.is_data_exists(&conditions, false).unwrap());
281 
282     fs::remove_dir_all("/data/asset_test/0").unwrap();
283 }
284 
285 #[test]
upgrade_table()286 fn upgrade_table() {
287     fs::create_dir_all("/data/asset_test/0").unwrap();
288     let calling_info = CallingInfo::new_self();
289     let db = Database::build(calling_info.user_id(), calling_info.owner_type_enum(), calling_info.owner_info(), false)
290         .unwrap();
291     let table = Table::new("table_name", &db);
292 
293     let columns = &[
294         ColumnInfo { name: "id", is_primary_key: true, not_null: true, data_type: DataType::Number },
295         ColumnInfo { name: "alias", is_primary_key: false, not_null: true, data_type: DataType::Bytes },
296     ];
297     table.create(columns).unwrap();
298     assert!(table
299         .add_column(
300             &ColumnInfo { name: "value", is_primary_key: false, not_null: false, data_type: DataType::Bytes },
301             &None
302         )
303         .is_ok());
304     assert!(table
305         .add_column(
306             &ColumnInfo { name: "value1", is_primary_key: false, not_null: true, data_type: DataType::Bytes },
307             &None
308         )
309         .is_err());
310     assert!(table
311         .add_column(
312             &ColumnInfo { name: "value2", is_primary_key: true, not_null: true, data_type: DataType::Number },
313             &None
314         )
315         .is_err());
316     assert!(table
317         .add_column(
318             &ColumnInfo { name: "value3", is_primary_key: false, not_null: true, data_type: DataType::Number },
319             &Some(Value::Number(1))
320         )
321         .is_ok());
322     fs::remove_dir_all("/data/asset_test/0").unwrap();
323 }
324 
325 #[test]
replace_datas()326 fn replace_datas() {
327     fs::create_dir_all("/data/asset_test/0").unwrap();
328     let calling_info = CallingInfo::new_self();
329     let db = Database::build(calling_info.user_id(), calling_info.owner_type_enum(), calling_info.owner_info(), false)
330         .unwrap();
331     let table = Table::new("table_name", &db);
332 
333     let columns = &[
334         ColumnInfo { name: "id", is_primary_key: true, not_null: true, data_type: DataType::Number },
335         ColumnInfo { name: "alias", is_primary_key: false, not_null: true, data_type: DataType::Bytes },
336     ];
337     table.create(columns).unwrap();
338     let datas = DbMap::from([("id", Value::Number(1)), ("alias", Value::Bytes(b"alias1".to_vec()))]);
339     assert_eq!(table.insert_row(&datas).unwrap(), 1);
340     let datas = DbMap::from([("id", Value::Number(2)), ("alias", Value::Bytes(b"alias2".to_vec()))]);
341     assert_eq!(table.insert_row(&datas).unwrap(), 1);
342 
343     let conditions = DbMap::from([("id", Value::Number(2))]);
344     let datas = DbMap::from([("id", Value::Number(3)), ("alias", Value::Bytes(b"alias3".to_vec()))]);
345     table.replace_row(&conditions, false, &datas).unwrap();
346     assert!(table.is_data_exists(&datas, false).unwrap());
347 
348     assert_eq!(table.count_datas(&conditions, false).unwrap(), 0);
349     fs::remove_dir_all("/data/asset_test/0").unwrap();
350 }
351