• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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 #define MLOG_TAG "PhotoDayMonthYearOperation"
17 
18 #include "photo_day_month_year_operation.h"
19 
20 #include "media_file_utils.h"
21 #include "media_log.h"
22 #include "medialibrary_unistore_manager.h"
23 #include "result_set_utils.h"
24 
25 namespace OHOS {
26 namespace Media {
27 const int32_t UPDATE_BATCH_SIZE = 200;
28 
29 const std::string QUERY_NEED_UPDATE_FILE_IDS = ""
30     "SELECT file_id FROM Photos "
31     "WHERE"
32     "  date_added = 0"
33     "  OR date_taken = 0"
34     "  OR date_day <> strftime( '%Y%m%d', date_taken / 1000, 'unixepoch', 'localtime' );";
35 
36 const std::string UPDATE_DAY_MONTH_YEAR = ""
37     "UPDATE Photos "
38     "SET date_added ="
39     " CASE"
40     "  WHEN date_added <> 0 THEN"
41     "  date_added "
42     "  WHEN date_taken <> 0 THEN"
43     "  date_taken "
44     "  WHEN date_modified <> 0 THEN"
45     "  date_modified ELSE strftime( '%s', 'now' ) "
46     " END, "
47     "date_taken ="
48     " CASE"
49     "  WHEN date_taken <> 0 THEN"
50     "  date_taken "
51     "  WHEN date_added <> 0 THEN"
52     "  date_added "
53     "  WHEN date_modified <> 0 THEN"
54     "  date_modified ELSE strftime( '%s', 'now' ) "
55     " END, "
56     "date_day ="
57     " CASE"
58     "  WHEN date_taken <> 0 THEN"
59     "  strftime( '%Y%m%d', date_taken / 1000, 'unixepoch', 'localtime' ) "
60     "  WHEN date_added <> 0 THEN"
61     "  strftime( '%Y%m%d', date_added / 1000, 'unixepoch', 'localtime' ) "
62     "  WHEN date_modified <> 0 THEN"
63     "  strftime( '%Y%m%d', date_modified / 1000, 'unixepoch', 'localtime' ) "
64     "  ELSE strftime( '%Y%m%d', strftime( '%s', 'now' ) / 1000, 'unixepoch', 'localtime' ) "
65     " END, "
66     "date_month ="
67     " CASE"
68     "  WHEN date_taken <> 0 THEN"
69     "  strftime( '%Y%m', date_taken / 1000, 'unixepoch', 'localtime' ) "
70     "  WHEN date_added <> 0 THEN"
71     "  strftime( '%Y%m', date_added / 1000, 'unixepoch', 'localtime' ) "
72     "  WHEN date_modified <> 0 THEN"
73     "  strftime( '%Y%m', date_modified / 1000, 'unixepoch', 'localtime' ) "
74     "  ELSE strftime( '%Y%m', strftime( '%s', 'now' ) / 1000, 'unixepoch', 'localtime' ) "
75     " END, "
76     "date_year ="
77     " CASE"
78     "  WHEN date_taken <> 0 THEN"
79     "  strftime( '%Y', date_taken / 1000, 'unixepoch', 'localtime' ) "
80     "  WHEN date_added <> 0 THEN"
81     "  strftime( '%Y', date_added / 1000, 'unixepoch', 'localtime' ) "
82     "  WHEN date_modified <> 0 THEN"
83     "  strftime( '%Y', date_modified / 1000, 'unixepoch', 'localtime' ) "
84     "  ELSE strftime( '%Y', strftime( '%s', 'now' ) / 1000, 'unixepoch', 'localtime' ) "
85     " END, "
86     "dirty ="
87     " CASE"
88     "  WHEN dirty = 0 THEN"
89     "  2 ELSE dirty "
90     " END "
91     "WHERE"
92     "  ( date_added = 0 "
93     "  OR date_taken = 0 "
94     "  OR date_day <> strftime( '%Y%m%d', date_taken / 1000, 'unixepoch', 'localtime' ) )"
95     "  AND file_id IN ( ";
96 
UpdatePhotosDate(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)97 int32_t PhotoDayMonthYearOperation::UpdatePhotosDate(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
98 {
99     MEDIA_INFO_LOG("update photos date start");
100     int64_t startTime = MediaFileUtils::UTCTimeMilliSeconds();
101     bool cond = (rdbStore == nullptr || !rdbStore->CheckRdbStore());
102     CHECK_AND_RETURN_RET_LOG(!cond, NativeRdb::E_ERROR,
103         "Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
104     auto resultSet = rdbStore->QueryByStep(QUERY_NEED_UPDATE_FILE_IDS);
105     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, NativeRdb::E_ERROR, "query photos by step failed");
106 
107     std::vector<std::string> needUpdateFileIds;
108     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
109         needUpdateFileIds.push_back(GetStringVal(PhotoColumn::MEDIA_ID, resultSet));
110     }
111     resultSet->Close();
112     auto needChangedSize = needUpdateFileIds.size();
113     CHECK_AND_RETURN_RET(needChangedSize > 0, NativeRdb::E_OK);
114 
115     int32_t ret = NativeRdb::E_OK;
116     int64_t totalChanged = 0;
117     for (size_t start = 0; start < needChangedSize; start += UPDATE_BATCH_SIZE) {
118         size_t end = std::min(start + UPDATE_BATCH_SIZE, needChangedSize);
119         std::stringstream updateSql;
120         updateSql << UPDATE_DAY_MONTH_YEAR;
121         for (size_t i = start; i < end; ++i) {
122             if (i != start) {
123                 updateSql << ", ";
124             }
125             updateSql << needUpdateFileIds[i];
126         }
127         updateSql << " );";
128         int64_t batchStart = MediaFileUtils::UTCTimeMilliSeconds();
129         int64_t changedRowCount = 0;
130         auto errCode = rdbStore->ExecuteForChangedRowCount(changedRowCount, updateSql.str());
131         if (errCode != NativeRdb::E_OK) {
132             ret = errCode;
133             MEDIA_ERR_LOG("update photos date failed, errCode: %{public}d, batchStart: %{public}" PRId64
134                 ", cost: %{public}" PRId64,
135                 errCode, batchStart, MediaFileUtils::UTCTimeMilliSeconds() - batchStart);
136         } else {
137             totalChanged += changedRowCount;
138             MEDIA_DEBUG_LOG("update photos date, batchStart: %{public}" PRId64 ", cost: %{public}" PRId64
139                 ", changedRowCount: %{public}" PRId64,
140                 batchStart, MediaFileUtils::UTCTimeMilliSeconds() - batchStart, changedRowCount);
141         }
142     }
143 
144     MEDIA_INFO_LOG("update photos date end, startTime: %{public}" PRId64 ", cost: %{public}" PRId64
145         ", needChangedSize: %{public}zu, totalChanged: %{public}" PRId64,
146         startTime, MediaFileUtils::UTCTimeMilliSeconds() - startTime, needChangedSize, totalChanged);
147     return ret;
148 }
149 
UpdatePhotosDateAndIdx(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)150 int32_t PhotoDayMonthYearOperation::UpdatePhotosDateAndIdx(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
151 {
152     MEDIA_INFO_LOG("update phots date start");
153     int64_t startTime = MediaFileUtils::UTCTimeMilliSeconds();
154     bool cond = (rdbStore == nullptr || !rdbStore->CheckRdbStore());
155     CHECK_AND_RETURN_RET_LOG(!cond, NativeRdb::E_ERROR,
156         "Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
157 
158     auto ret = UpdatePhotosDate(rdbStore);
159     CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, ret, "update day month year failed, ret=%{public}d", ret);
160     MEDIA_INFO_LOG("update phots date end, startTime: %{public}" PRId64 ", cost: %{public}" PRId64, startTime,
161         (MediaFileUtils::UTCTimeMilliSeconds() - startTime));
162     return NativeRdb::E_OK;
163 }
164 
UpdatePhotosDate(NativeRdb::RdbStore & rdbStore)165 int32_t PhotoDayMonthYearOperation::UpdatePhotosDate(NativeRdb::RdbStore &rdbStore)
166 {
167     MEDIA_INFO_LOG("update photos date start");
168     int64_t startTime = MediaFileUtils::UTCTimeMilliSeconds();
169 
170     auto resultSet = rdbStore.QueryByStep(QUERY_NEED_UPDATE_FILE_IDS);
171     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, NativeRdb::E_ERROR, "query photos by step failed");
172 
173     std::vector<std::string> needUpdateFileIds;
174     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
175         needUpdateFileIds.push_back(GetStringVal(PhotoColumn::MEDIA_ID, resultSet));
176     }
177     resultSet->Close();
178     auto needChangedSize = needUpdateFileIds.size();
179     CHECK_AND_RETURN_RET(needChangedSize > 0, NativeRdb::E_OK);
180 
181     std::stringstream updateSql;
182     updateSql << UPDATE_DAY_MONTH_YEAR;
183     for (size_t i = 0; i < needChangedSize; ++i) {
184         if (i != 0) {
185             updateSql << ", ";
186         }
187         updateSql << needUpdateFileIds[i];
188     }
189     updateSql << " );";
190     int64_t changedRowCount = 0;
191     auto errCode = rdbStore.ExecuteForChangedRowCount(changedRowCount, updateSql.str());
192     CHECK_AND_RETURN_RET_LOG(errCode == NativeRdb::E_OK, errCode,
193         "update photos date failed, errCode: %{public}d, startTime: %{public}" PRId64
194         ", cost: %{public}" PRId64 ", needChangedSize: %{public}zu",
195         errCode, startTime, MediaFileUtils::UTCTimeMilliSeconds() - startTime, needChangedSize);
196 
197     MEDIA_INFO_LOG("update photos date end, startTime: %{public}" PRId64 ", cost: %{public}" PRId64
198         ", needChangedSize: %{public}zu, changedRowCount: %{public}" PRId64,
199         startTime, MediaFileUtils::UTCTimeMilliSeconds() - startTime, needChangedSize, changedRowCount);
200     return NativeRdb::E_OK;
201 }
202 
UpdatePhotosDateIdx(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)203 int32_t PhotoDayMonthYearOperation::UpdatePhotosDateIdx(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
204 {
205     MEDIA_INFO_LOG("update photos date idx start");
206     int64_t startTime = MediaFileUtils::UTCTimeMilliSeconds();
207     bool cond = (rdbStore == nullptr || !rdbStore->CheckRdbStore());
208     CHECK_AND_RETURN_RET_LOG(!cond, NativeRdb::E_ERROR,
209         "Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
210 
211     auto ret = rdbStore->ExecuteSql(PhotoColumn::DROP_SCHPT_DAY_INDEX);
212     CHECK_AND_PRINT_LOG(ret == NativeRdb::E_OK, "drop idx date_day failed, ret=%{public}d", ret);
213 
214     ret = rdbStore->ExecuteSql(PhotoColumn::CREATE_SCHPT_DAY_INDEX);
215     CHECK_AND_PRINT_LOG(ret == NativeRdb::E_OK, "create idx date_day failed, ret=%{public}d", ret);
216 
217     ret = rdbStore->ExecuteSql(PhotoColumn::DROP_SCHPT_MONTH_COUNT_READY_INDEX);
218     CHECK_AND_PRINT_LOG(ret == NativeRdb::E_OK, "drop idx date_month failed, ret=%{public}d", ret);
219 
220     ret = rdbStore->ExecuteSql(PhotoColumn::CREATE_SCHPT_MONTH_COUNT_READY_INDEX);
221     CHECK_AND_PRINT_LOG(ret == NativeRdb::E_OK, "create idx date_month failed, ret=%{public}d", ret);
222 
223     ret = rdbStore->ExecuteSql(PhotoColumn::DROP_SCHPT_YEAR_COUNT_READY_INDEX);
224     CHECK_AND_PRINT_LOG(ret == NativeRdb::E_OK, "drop idx date_year failed, ret=%{public}d", ret);
225 
226     ret = rdbStore->ExecuteSql(PhotoColumn::CREATE_SCHPT_YEAR_COUNT_READY_INDEX);
227     CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, ret, "create idx date_year failed, ret=%{public}d", ret);
228 
229     MEDIA_INFO_LOG("update photos date idx end, startTime: %{public}" PRId64 ", cost: %{public}" PRId64, startTime,
230         (MediaFileUtils::UTCTimeMilliSeconds() - startTime));
231     return NativeRdb::E_OK;
232 }
233 
QueryNeedUpdateFileIds(const int32_t batchSize)234 std::pair<int32_t, std::vector<std::string>> PhotoDayMonthYearOperation::QueryNeedUpdateFileIds(const int32_t batchSize)
235 {
236     MEDIA_DEBUG_LOG("Query need update fileIds start");
237 
238     std::vector<std::string> needUpdateFileIds;
239     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
240     if (rdbStore == nullptr) {
241         MEDIA_ERR_LOG("rdbStore is nullptr!");
242         return { NativeRdb::E_ERROR, needUpdateFileIds };
243     }
244 
245     const std::string sql = ""
246         "SELECT"
247         "  file_id "
248         "FROM"
249         "  Photos "
250         "WHERE"
251         "  date_added = 0 "
252         "  OR date_taken = 0 "
253         "  OR date_day <> strftime( '%Y%m%d', date_taken / 1000, 'unixepoch', 'localtime' ) "
254         "  LIMIT " +
255         std::to_string(batchSize) + ";";
256 
257     auto resultSet = rdbStore->QueryByStep(sql);
258     if (resultSet == nullptr) {
259         MEDIA_ERR_LOG("query need update fileIds by step failed!");
260         return { NativeRdb::E_ERROR, needUpdateFileIds };
261     }
262 
263     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
264         needUpdateFileIds.push_back(GetStringVal(PhotoColumn::MEDIA_ID, resultSet));
265     }
266     resultSet->Close();
267 
268     return { NativeRdb::E_OK, needUpdateFileIds };
269 }
270 
UpdateAbnormalDayMonthYear(std::vector<std::string> & fileIds)271 int32_t PhotoDayMonthYearOperation::UpdateAbnormalDayMonthYear(std::vector<std::string> &fileIds)
272 {
273     MEDIA_DEBUG_LOG("update abnormal day month year data start");
274 
275     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
276     CHECK_AND_RETURN_RET_LOG(rdbStore != nullptr, NativeRdb::E_ERROR, "rdbStore is nullptr!");
277 
278     auto needChangedSize = fileIds.size();
279     CHECK_AND_RETURN_RET(needChangedSize > 0, NativeRdb::E_OK);
280 
281     std::stringstream updateSql;
282     updateSql << UPDATE_DAY_MONTH_YEAR;
283     for (size_t i = 0; i < needChangedSize; ++i) {
284         if (i != 0) {
285             updateSql << ", ";
286         }
287         updateSql << fileIds[i];
288     }
289     updateSql << " );";
290     int64_t changedRowCount = 0;
291 
292     auto errCode = rdbStore->ExecuteForChangedRowCount(changedRowCount, updateSql.str());
293     CHECK_AND_RETURN_RET_LOG(errCode == NativeRdb::E_OK, errCode,
294         "update abnormal day month year data failed, errCode: %{public}d, needChangedSize: %{public}zu",
295         errCode, needChangedSize);
296     MEDIA_DEBUG_LOG(
297         "update abnormal day month year data end, needChangedSize: %{public}zu, changedRowCount: %{public}" PRId64,
298         needChangedSize, changedRowCount);
299     return NativeRdb::E_OK;
300 }
301 } // namespace Media
302 } // namespace OHOS
303