• 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     if (rdbStore == nullptr || !rdbStore->CheckRdbStore()) {
102         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
103         return NativeRdb::E_ERROR;
104     }
105 
106     auto resultSet = rdbStore->QueryByStep(QUERY_NEED_UPDATE_FILE_IDS);
107     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, NativeRdb::E_ERROR, "query photos by step failed");
108 
109     std::vector<std::string> needUpdateFileIds;
110     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
111         needUpdateFileIds.push_back(GetStringVal(PhotoColumn::MEDIA_ID, resultSet));
112     }
113     resultSet->Close();
114     auto needChangedSize = needUpdateFileIds.size();
115     CHECK_AND_RETURN_RET(needChangedSize > 0, NativeRdb::E_OK);
116 
117     int32_t ret = NativeRdb::E_OK;
118     int64_t totalChanged = 0;
119     for (size_t start = 0; start < needChangedSize; start += UPDATE_BATCH_SIZE) {
120         size_t end = std::min(start + UPDATE_BATCH_SIZE, needChangedSize);
121         std::stringstream updateSql;
122         updateSql << UPDATE_DAY_MONTH_YEAR;
123         for (size_t i = start; i < end; ++i) {
124             if (i != start) {
125                 updateSql << ", ";
126             }
127             updateSql << needUpdateFileIds[i];
128         }
129         updateSql << " );";
130         int64_t batchStart = MediaFileUtils::UTCTimeMilliSeconds();
131         int64_t changedRowCount = 0;
132         auto errCode = rdbStore->ExecuteForChangedRowCount(changedRowCount, updateSql.str());
133         if (errCode != NativeRdb::E_OK) {
134             ret = errCode;
135             MEDIA_ERR_LOG("update photos date failed, errCode: %{public}d, batchStart: %{public}" PRId64
136                 ", cost: %{public}" PRId64,
137                 errCode, batchStart, MediaFileUtils::UTCTimeMilliSeconds() - batchStart);
138         } else {
139             totalChanged += changedRowCount;
140             MEDIA_DEBUG_LOG("update photos date, batchStart: %{public}" PRId64 ", cost: %{public}" PRId64
141                 ", changedRowCount: %{public}" PRId64,
142                 batchStart, MediaFileUtils::UTCTimeMilliSeconds() - batchStart, changedRowCount);
143         }
144     }
145 
146     MEDIA_INFO_LOG("update photos date end, startTime: %{public}" PRId64 ", cost: %{public}" PRId64
147         ", needChangedSize: %{public}zu, totalChanged: %{public}" PRId64,
148         startTime, MediaFileUtils::UTCTimeMilliSeconds() - startTime, needChangedSize, totalChanged);
149     return ret;
150 }
151 
UpdatePhotosDateAndIdx(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)152 int32_t PhotoDayMonthYearOperation::UpdatePhotosDateAndIdx(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
153 {
154     MEDIA_INFO_LOG("update phots date start");
155     int64_t startTime = MediaFileUtils::UTCTimeMilliSeconds();
156     if (rdbStore == nullptr || !rdbStore->CheckRdbStore()) {
157         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
158         return NativeRdb::E_ERROR;
159     }
160 
161     auto ret = UpdatePhotosDate(rdbStore);
162     CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, ret, "update day month year failed, ret=%{public}d", ret);
163 
164     MEDIA_INFO_LOG("update phots date end, startTime: %{public}" PRId64 ", cost: %{public}" PRId64, startTime,
165         (MediaFileUtils::UTCTimeMilliSeconds() - startTime));
166     return NativeRdb::E_OK;
167 }
168 
UpdatePhotosDate(NativeRdb::RdbStore & rdbStore)169 int32_t PhotoDayMonthYearOperation::UpdatePhotosDate(NativeRdb::RdbStore &rdbStore)
170 {
171     MEDIA_INFO_LOG("update photos date start");
172     int64_t startTime = MediaFileUtils::UTCTimeMilliSeconds();
173 
174     auto resultSet = rdbStore.QueryByStep(QUERY_NEED_UPDATE_FILE_IDS);
175     CHECK_AND_RETURN_RET_LOG(resultSet != nullptr, NativeRdb::E_ERROR, "query photos by step failed");
176 
177     std::vector<std::string> needUpdateFileIds;
178     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
179         needUpdateFileIds.push_back(GetStringVal(PhotoColumn::MEDIA_ID, resultSet));
180     }
181     resultSet->Close();
182     auto needChangedSize = needUpdateFileIds.size();
183     CHECK_AND_RETURN_RET(needChangedSize > 0, NativeRdb::E_OK);
184 
185     std::stringstream updateSql;
186     updateSql << UPDATE_DAY_MONTH_YEAR;
187     for (size_t i = 0; i < needChangedSize; ++i) {
188         if (i != 0) {
189             updateSql << ", ";
190         }
191         updateSql << needUpdateFileIds[i];
192     }
193     updateSql << " );";
194     int64_t changedRowCount = 0;
195     auto errCode = rdbStore.ExecuteForChangedRowCount(changedRowCount, updateSql.str());
196     if (errCode != NativeRdb::E_OK) {
197         MEDIA_ERR_LOG("update photos date failed, errCode: %{public}d, startTime: %{public}" PRId64
198             ", cost: %{public}" PRId64 ", needChangedSize: %{public}zu",
199             errCode, startTime, MediaFileUtils::UTCTimeMilliSeconds() - startTime, needChangedSize);
200         return errCode;
201     }
202     MEDIA_INFO_LOG("update photos date end, startTime: %{public}" PRId64 ", cost: %{public}" PRId64
203         ", needChangedSize: %{public}zu, changedRowCount: %{public}" PRId64,
204         startTime, MediaFileUtils::UTCTimeMilliSeconds() - startTime, needChangedSize, changedRowCount);
205     return NativeRdb::E_OK;
206 }
207 
UpdatePhotosDateIdx(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)208 int32_t PhotoDayMonthYearOperation::UpdatePhotosDateIdx(const std::shared_ptr<MediaLibraryRdbStore> rdbStore)
209 {
210     MEDIA_INFO_LOG("update photos date idx start");
211     int64_t startTime = MediaFileUtils::UTCTimeMilliSeconds();
212     if (rdbStore == nullptr || !rdbStore->CheckRdbStore()) {
213         MEDIA_ERR_LOG("Pointer rdbStore_ is nullptr. Maybe it didn't init successfully.");
214         return NativeRdb::E_ERROR;
215     }
216 
217     auto ret = rdbStore->ExecuteSql(PhotoColumn::DROP_SCHPT_DAY_INDEX);
218     CHECK_AND_PRINT_LOG(ret == NativeRdb::E_OK, "drop idx date_day failed, ret=%{public}d", ret);
219 
220     ret = rdbStore->ExecuteSql(PhotoColumn::CREATE_SCHPT_DAY_INDEX);
221     CHECK_AND_PRINT_LOG(ret == NativeRdb::E_OK, "create idx date_day failed, ret=%{public}d", ret);
222 
223     ret = rdbStore->ExecuteSql(PhotoColumn::DROP_SCHPT_MONTH_COUNT_READY_INDEX);
224     CHECK_AND_PRINT_LOG(ret == NativeRdb::E_OK, "drop idx date_month failed, ret=%{public}d", ret);
225 
226     ret = rdbStore->ExecuteSql(PhotoColumn::CREATE_SCHPT_MONTH_COUNT_READY_INDEX);
227     CHECK_AND_PRINT_LOG(ret == NativeRdb::E_OK, "create idx date_month failed, ret=%{public}d", ret);
228 
229     ret = rdbStore->ExecuteSql(PhotoColumn::DROP_SCHPT_YEAR_COUNT_READY_INDEX);
230     CHECK_AND_PRINT_LOG(ret == NativeRdb::E_OK, "drop idx date_year failed, ret=%{public}d", ret);
231 
232     ret = rdbStore->ExecuteSql(PhotoColumn::CREATE_SCHPT_YEAR_COUNT_READY_INDEX);
233     CHECK_AND_RETURN_RET_LOG(ret == NativeRdb::E_OK, ret, "create idx date_year failed, ret=%{public}d", ret);
234 
235     MEDIA_INFO_LOG("update photos date idx end, startTime: %{public}" PRId64 ", cost: %{public}" PRId64, startTime,
236         (MediaFileUtils::UTCTimeMilliSeconds() - startTime));
237     return NativeRdb::E_OK;
238 }
239 
QueryNeedUpdateFileIds(const int32_t batchSize)240 std::pair<int32_t, std::vector<std::string>> PhotoDayMonthYearOperation::QueryNeedUpdateFileIds(const int32_t batchSize)
241 {
242     MEDIA_DEBUG_LOG("Query need update fileIds start");
243 
244     std::vector<std::string> needUpdateFileIds;
245     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
246     if (rdbStore == nullptr) {
247         MEDIA_ERR_LOG("rdbStore is nullptr!");
248         return { NativeRdb::E_ERROR, needUpdateFileIds };
249     }
250 
251     const std::string sql = ""
252         "SELECT"
253         "  file_id "
254         "FROM"
255         "  Photos "
256         "WHERE"
257         "  date_added = 0 "
258         "  OR date_taken = 0 "
259         "  OR date_day <> strftime( '%Y%m%d', date_taken / 1000, 'unixepoch', 'localtime' ) "
260         "  LIMIT " +
261         std::to_string(batchSize) + ";";
262 
263     auto resultSet = rdbStore->QueryByStep(sql);
264     if (resultSet == nullptr) {
265         MEDIA_ERR_LOG("query need update fileIds by step failed!");
266         return { NativeRdb::E_ERROR, needUpdateFileIds };
267     }
268 
269     while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
270         needUpdateFileIds.push_back(GetStringVal(PhotoColumn::MEDIA_ID, resultSet));
271     }
272     resultSet->Close();
273 
274     return { NativeRdb::E_OK, needUpdateFileIds };
275 }
276 
UpdateAbnormalDayMonthYear(std::vector<std::string> & fileIds)277 int32_t PhotoDayMonthYearOperation::UpdateAbnormalDayMonthYear(std::vector<std::string> &fileIds)
278 {
279     MEDIA_DEBUG_LOG("update abnormal day month year data start");
280 
281     auto rdbStore = MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
282     if (rdbStore == nullptr) {
283         MEDIA_ERR_LOG("rdbStore is nullptr!");
284         return NativeRdb::E_ERROR;
285     }
286 
287     auto needChangedSize = fileIds.size();
288     CHECK_AND_RETURN_RET(needChangedSize > 0, NativeRdb::E_OK);
289 
290     std::stringstream updateSql;
291     updateSql << UPDATE_DAY_MONTH_YEAR;
292     for (size_t i = 0; i < needChangedSize; ++i) {
293         if (i != 0) {
294             updateSql << ", ";
295         }
296         updateSql << fileIds[i];
297     }
298     updateSql << " );";
299     int64_t changedRowCount = 0;
300     auto errCode = rdbStore->ExecuteForChangedRowCount(changedRowCount, updateSql.str());
301     if (errCode != NativeRdb::E_OK) {
302         MEDIA_ERR_LOG("update abnormal day month year data failed, errCode: %{public}d, needChangedSize: %{public}zu",
303             errCode, needChangedSize);
304         return errCode;
305     }
306     MEDIA_DEBUG_LOG(
307         "update abnormal day month year data end, needChangedSize: %{public}zu, changedRowCount: %{public}" PRId64,
308         needChangedSize, changedRowCount);
309     return NativeRdb::E_OK;
310 }
311 } // namespace Media
312 } // namespace OHOS
313