• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 use std::sync::LazyLock;
15 use std::time::{SystemTime, UNIX_EPOCH};
16 
17 use rdb::{OpenConfig, RdbStore, SecurityLevel};
18 
19 use crate::service::notification_bar::NotificationDispatcher;
20 
21 const DB_PATH: &str = if cfg!(test) {
22     "/data/test/notification.db"
23 } else {
24     "/data/service/el1/public/database/request/request.db"
25 };
26 
27 const MILLIS_IN_A_WEEK: u64 = 7 * 24 * 60 * 60 * 1000;
28 
29 pub(crate) static REQUEST_DB: LazyLock<RdbStore<'static>> = LazyLock::new(|| {
30     let mut config = OpenConfig::new(DB_PATH);
31     config.security_level(SecurityLevel::S1);
32     if cfg!(test) {
33         config.encrypt_status(false);
34         config.bundle_name("Test");
35     } else {
36         config.encrypt_status(true);
37     }
38     RdbStore::open(config).unwrap()
39 });
40 
clear_database_part(pre_count: usize) -> Result<bool, ()>41 pub(crate) fn clear_database_part(pre_count: usize) -> Result<bool, ()> {
42     let mut remain = true;
43     // rdb not support RETURNING expr.
44     let current_time = match SystemTime::now().duration_since(UNIX_EPOCH) {
45         Ok(duration) => duration,
46         Err(e) => {
47             error!("Failed to get current time: {}", e);
48             return Err(());
49         }
50     }
51     .as_millis() as u64;
52 
53     let task_ids: Vec<_> = match REQUEST_DB.query::<u32>(
54         "SELECT task_id from request_task WHERE mtime < ? LIMIT ?",
55         (current_time - MILLIS_IN_A_WEEK, pre_count as u64),
56     ) {
57         Ok(rows) => rows.collect(),
58         Err(e) => {
59             error!("Failed to clear database: {}", e);
60             return Err(());
61         }
62     };
63 
64     if task_ids.len() < pre_count {
65         remain = false;
66     }
67 
68     for task_id in task_ids {
69         debug!(
70             "clear {} info for have been overdue for more than a week.",
71             task_id
72         );
73         if let Err(e) = REQUEST_DB.execute("DELETE from request_task WHERE task_id = ?", task_id) {
74             error!("Failed to clear task {} info: {}", task_id, e);
75         }
76         NotificationDispatcher::get_instance().clear_task_info(task_id);
77     }
78     Ok(remain)
79 }
80 
81 #[cfg(test)]
82 mod ut_database {
83     include!("../tests/ut/ut_database.rs");
84 }
85