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 #include <utility>
17 
18 #include "clone_source.h"
19 #define private public
20 #define protected public
21 #include "medialibrary_unistore.h"
22 #undef private
23 #undef protected
24 #include "media_column.h"
25 #include "media_log.h"
26 #include "photo_album_column.h"
27 #include "photo_map_column.h"
28 #include "vision_column.h"
29 #include "vision_db_sqls_more.h"
30 
31 using namespace std;
32 
33 namespace OHOS {
34 namespace Media {
35 const unordered_map<string, string> TABLE_CREATE_MAP = {
36     { PhotoColumn::PHOTOS_TABLE, PhotoColumn::CREATE_PHOTO_TABLE },
37     { PhotoAlbumColumns::TABLE, PhotoAlbumColumns::CREATE_TABLE },
38     { PhotoMap::TABLE, PhotoMap::CREATE_TABLE },
39     { ANALYSIS_ALBUM_TABLE, CREATE_ANALYSIS_ALBUM_FOR_ONCREATE },
40     { VISION_FACE_TAG_TABLE, CREATE_FACE_TAG_TBL_FOR_ONCREATE },
41     { VISION_IMAGE_FACE_TABLE, CREATE_IMG_FACE_TBL_FOR_ONCREATE },
42     { ANALYSIS_PHOTO_MAP_TABLE, CREATE_ANALYSIS_ALBUM_MAP },
43     { AudioColumn::AUDIOS_TABLE, AudioColumn::CREATE_AUDIO_TABLE },
44 };
45 const unordered_map<string, InsertType> TABLE_INSERT_TYPE_MAP = {
46     { PhotoColumn::PHOTOS_TABLE, InsertType::PHOTOS },
47     { PhotoAlbumColumns::TABLE, InsertType::PHOTO_ALBUM },
48     { PhotoMap::TABLE, InsertType::PHOTO_MAP },
49     { ANALYSIS_ALBUM_TABLE, InsertType::ANALYSIS_ALBUM },
50     { VISION_FACE_TAG_TABLE, InsertType::FACE_TAG_TBL },
51     { VISION_IMAGE_FACE_TABLE, InsertType::IMG_FACE_TBL },
52     { ANALYSIS_PHOTO_MAP_TABLE, InsertType::ANALYSIS_PHOTO_MAP },
53     { AudioColumn::AUDIOS_TABLE, InsertType::AUDIOS },
54 };
55 const string VALUES_BEGIN = " VALUES (";
56 const string VALUES_END = ") ";
57 const string INSERT_PHOTO = "INSERT INTO " + PhotoColumn::PHOTOS_TABLE + "(" + MediaColumn::MEDIA_ID + ", " +
58     MediaColumn::MEDIA_FILE_PATH + ", " + MediaColumn::MEDIA_SIZE + ", " + MediaColumn::MEDIA_TITLE + ", " +
59     MediaColumn::MEDIA_NAME + ", " + MediaColumn::MEDIA_TYPE + ", " + MediaColumn::MEDIA_OWNER_PACKAGE + ", " +
60     MediaColumn::MEDIA_PACKAGE_NAME + ", " + MediaColumn::MEDIA_DATE_ADDED + ", "  +
61     MediaColumn::MEDIA_DATE_MODIFIED + ", " + MediaColumn::MEDIA_DATE_TAKEN + ", " +
62     MediaColumn::MEDIA_DURATION + ", " + MediaColumn::MEDIA_IS_FAV + ", " + MediaColumn::MEDIA_DATE_TRASHED + ", " +
63     MediaColumn::MEDIA_HIDDEN + ", " + PhotoColumn::PHOTO_HEIGHT + ", " + PhotoColumn::PHOTO_WIDTH + ", " +
64     PhotoColumn::PHOTO_EDIT_TIME + ", " + PhotoColumn::PHOTO_SHOOTING_MODE + ")";
65 const string INSERT_PHOTO_ALBUM = "INSERT INTO " + PhotoAlbumColumns::TABLE + "(" + PhotoAlbumColumns::ALBUM_ID + ", " +
66     PhotoAlbumColumns::ALBUM_TYPE + ", " + PhotoAlbumColumns::ALBUM_SUBTYPE + ", " +
67     PhotoAlbumColumns::ALBUM_NAME + ", " + PhotoAlbumColumns::ALBUM_DATE_MODIFIED + ", " +
68     PhotoAlbumColumns::ALBUM_BUNDLE_NAME + ")";
69 const string INSERT_PHOTO_MAP = "INSERT INTO " + PhotoMap::TABLE + "(" + PhotoMap::ALBUM_ID + ", " +
70     PhotoMap::ASSET_ID + ")";
71 const string INSERT_ANALYSIS_ALBUM = "INSERT INTO " + ANALYSIS_ALBUM_TABLE + "(" + PhotoAlbumColumns::ALBUM_ID + ", " +
72     PhotoAlbumColumns::ALBUM_TYPE + ", " + PhotoAlbumColumns::ALBUM_SUBTYPE + ", " +
73     PhotoAlbumColumns::ALBUM_NAME + ") ";
74 const string INSERT_ANALYSIS_PHOTO_MAP = "INSERT INTO " + ANALYSIS_PHOTO_MAP_TABLE + "(" + PhotoMap::ALBUM_ID + ", " +
75     PhotoMap::ASSET_ID + ")";
76 const string INSERT_AUDIO = "INSERT INTO " + AudioColumn::AUDIOS_TABLE + "(" + AudioColumn::MEDIA_ID + ", " +
77     AudioColumn::MEDIA_FILE_PATH + ", " + AudioColumn::MEDIA_SIZE + ", " + AudioColumn::MEDIA_TITLE + ", " +
78     AudioColumn::MEDIA_NAME + ", " + AudioColumn::MEDIA_TYPE + ", " + AudioColumn::MEDIA_DATE_ADDED + ", "  +
79     AudioColumn::MEDIA_DATE_MODIFIED + ", " + AudioColumn::MEDIA_DATE_TAKEN + ", " +
80     AudioColumn::MEDIA_DURATION + ", " + AudioColumn::MEDIA_IS_FAV + ", " + AudioColumn::MEDIA_DATE_TRASHED + ", " +
81     AudioColumn::AUDIO_ARTIST + ")";
82 
OnCreate(NativeRdb::RdbStore & store)83 int32_t CloneOpenCall::OnCreate(NativeRdb::RdbStore &store)
84 {
85     for (const auto &createSql : createSqls_) {
86         int32_t errCode = store.ExecuteSql(createSql);
87         if (errCode != NativeRdb::E_OK) {
88             MEDIA_INFO_LOG("Execute %{public}s failed: %{public}d", createSql.c_str(), errCode);
89             return errCode;
90         }
91     }
92     return NativeRdb::E_OK;
93 }
94 
OnUpgrade(NativeRdb::RdbStore & store,int oldVersion,int newVersion)95 int32_t CloneOpenCall::OnUpgrade(NativeRdb::RdbStore &store, int oldVersion, int newVersion)
96 {
97     return 0;
98 }
99 
Init(const vector<string> & tableList)100 void CloneOpenCall::Init(const vector<string> &tableList)
101 {
102     for (const auto &tableName : tableList) {
103         if (TABLE_CREATE_MAP.count(tableName) == 0) {
104             MEDIA_INFO_LOG("Find value failed: %{public}s, skip", tableName.c_str());
105             continue;
106         }
107         string createSql = TABLE_CREATE_MAP.at(tableName);
108         createSqls_.push_back(createSql);
109     }
110 }
111 
Init(const string & dbPath,const vector<string> & tableList)112 void CloneSource::Init(const string &dbPath, const vector<string> &tableList)
113 {
114     NativeRdb::RdbStoreConfig config(dbPath);
115     CloneOpenCall helper;
116     helper.Init(tableList);
117     int errCode = 0;
118     shared_ptr<NativeRdb::RdbStore> store = NativeRdb::RdbHelper::GetRdbStore(config, 1, helper, errCode);
119     cloneStorePtr_ = store;
120     Insert(tableList);
121 }
122 
Insert(const vector<string> & tableList)123 void CloneSource::Insert(const vector<string> &tableList)
124 {
125     for (const auto &tableName : tableList) {
126         if (TABLE_INSERT_TYPE_MAP.count(tableName) == 0) {
127             MEDIA_INFO_LOG("Find value failed: %{public}s, skip", tableName.c_str());
128             continue;
129         }
130         InsertType insertType = TABLE_INSERT_TYPE_MAP.at(tableName);
131         InsertByType(insertType);
132     }
133 }
134 
InsertByType(InsertType insertType)135 void CloneSource::InsertByType(InsertType insertType)
136 {
137     switch (insertType) {
138         case InsertType::PHOTOS: {
139             InsertPhoto();
140             break;
141         }
142         case InsertType::PHOTO_ALBUM: {
143             InsertPhotoAlbum();
144             break;
145         }
146         case InsertType::PHOTO_MAP: {
147             InsertPhotoMap();
148             break;
149         }
150         case InsertType::ANALYSIS_ALBUM: {
151             InsertAnalysisAlbum();
152             break;
153         }
154         case InsertType::FACE_TAG_TBL: {
155             InsertFaceTag();
156             break;
157         }
158         case InsertType::IMG_FACE_TBL: {
159             InsertImgFaceTbl();
160             break;
161         }
162         case InsertType::ANALYSIS_PHOTO_MAP: {
163             InsertAnalysisPhotoMap();
164             break;
165         }
166         case InsertType::AUDIOS: {
167             InsertAudio();
168             break;
169         }
170         default:
171             MEDIA_INFO_LOG("Invalid insert type");
172     }
173 }
174 
InsertPhoto()175 void CloneSource::InsertPhoto()
176 {
177     // file_id,
178     // data, size, title, display_name, media_type,
179     // owner_package, package_name, date_added, date_modified, date_taken, duration, is_favorite, date_trashed, hidden
180     // height, width, edit_time, shooting_mode
181     cloneStorePtr_->ExecuteSql(INSERT_PHOTO + VALUES_BEGIN + "1, " +
182         "'/storage/cloud/files/Photo/16/IMG_1501924305_000.jpg', 175258, 'cam_pic', 'cam_pic.jpg', 1, " +
183         "'com.ohos.camera', '相机', 1501924205218, 1501924205423, 1501924205, 0, 0, 0, 0, " +
184         "1280, 960, 0, '1'" + VALUES_END); // cam, pic, shootingmode = 1
185     cloneStorePtr_->ExecuteSql(INSERT_PHOTO + VALUES_BEGIN + "2, " +
186         "'/storage/cloud/files/Photo/1/IMG_1501924307_001.jpg', 175397, 'cam_pic_del', 'cam_pic_del.jpg', 1, " +
187         "'com.ohos.camera', '相机', 1501924207184, 1501924207286, 1501924207, 0, 0, 1501924271267, 0, " +
188         "1280, 960, 0, ''" + VALUES_END); // cam, pic, trashed
189     cloneStorePtr_->ExecuteSql(INSERT_PHOTO + VALUES_BEGIN + "3, " +
190         "'/storage/cloud/files/Photo/16/VID_1501924310_000.mp4', 167055, 'cam_vid_fav', 'cam_vid_fav.mp4', 2, " +
191         "'com.ohos.camera', '相机', 1501924210677, 1501924216550, 1501924210, 5450, 1, 0, 0, " +
192         "480, 640, 0, ''" + VALUES_END); // cam, vid, favorite
193     cloneStorePtr_->ExecuteSql(INSERT_PHOTO + VALUES_BEGIN + "4, " +
194         "'/storage/cloud/files/Photo/2/IMG_1501924331_002.jpg', 505571, 'scr_pic_hid', 'scr_pic_hid.jpg', 1, " +
195         "'com.ohos.screenshot', '截图', 1501924231249, 1501924231286, 1501924231, 0, 0, 0, 1, " +
196         "1280, 720, 0, ''" + VALUES_END); // screenshot, pic, hidden
197     cloneStorePtr_->ExecuteSql(INSERT_PHOTO + VALUES_BEGIN + "5, " +
198         "'/storage/cloud/files/Photo/4/IMG_1501924357_004.jpg', 85975, 'scr_pic_edit', 'scr_pic_edit.jpg', 1, " +
199         "'com.ohos.screenshot', '截图', 1501924257174, 1501924257583, 1501924257, 0, 0, 0, 0, " +
200         "592, 720, 1501935124, ''" + VALUES_END); // screenshot, pic, edit
201     cloneStorePtr_->ExecuteSql(INSERT_PHOTO + VALUES_BEGIN + "6, " +
202         "'/storage/cloud/files/Photo/16/IMG_1501924305_005.jpg', 0, 'size_0', 'size_0.jpg', 1, " +
203         "'com.ohos.camera', '相机', 1501924205218, 1501924205423, 1501924205, 0, 0, 0, 0, " +
204         "1280, 960, 0, ''" + VALUES_END); // cam, pic, size = 0
205 }
206 
InsertPhotoAlbum()207 void CloneSource::InsertPhotoAlbum()
208 {
209     // album_id, album_type, album_subtype, album_name, date_modified, bundle_name
210     cloneStorePtr_->ExecuteSql(INSERT_PHOTO_ALBUM + VALUES_BEGIN + "8, 2048, 2049, '相机', 0, 'com.ohos.camera'" +
211         VALUES_END);
212     cloneStorePtr_->ExecuteSql(INSERT_PHOTO_ALBUM + VALUES_BEGIN + "9, 2048, 2049, '截图', 0, 'com.ohos.screenshot'" +
213         VALUES_END);
214     cloneStorePtr_->ExecuteSql(INSERT_PHOTO_ALBUM + VALUES_BEGIN + "11, 0, 1, '新建相册1', 1711540817842, NULL" +
215         VALUES_END);
216 }
217 
InsertPhotoMap()218 void CloneSource::InsertPhotoMap()
219 {
220     // map_album, map_asset
221     cloneStorePtr_->ExecuteSql(INSERT_PHOTO_MAP + VALUES_BEGIN + "8, 1" + VALUES_END);
222     cloneStorePtr_->ExecuteSql(INSERT_PHOTO_MAP + VALUES_BEGIN + "8, 2" + VALUES_END);
223     cloneStorePtr_->ExecuteSql(INSERT_PHOTO_MAP + VALUES_BEGIN + "8, 3" + VALUES_END);
224     cloneStorePtr_->ExecuteSql(INSERT_PHOTO_MAP + VALUES_BEGIN + "9, 4" + VALUES_END);
225     cloneStorePtr_->ExecuteSql(INSERT_PHOTO_MAP + VALUES_BEGIN + "9, 5" + VALUES_END);
226     cloneStorePtr_->ExecuteSql(INSERT_PHOTO_MAP + VALUES_BEGIN + "11, 1" + VALUES_END);
227     cloneStorePtr_->ExecuteSql(INSERT_PHOTO_MAP + VALUES_BEGIN + "11, 4" + VALUES_END);
228 }
229 
InsertAnalysisAlbum()230 void CloneSource::InsertAnalysisAlbum()
231 {
232     // album_id, album_type, album_subtype, album_name
233     cloneStorePtr_->ExecuteSql(INSERT_ANALYSIS_ALBUM + VALUES_BEGIN + "1, 4096, 4101, '1'" + VALUES_END);
234     cloneStorePtr_->ExecuteSql("INSERT INTO " + ANALYSIS_ALBUM_TABLE + "("
235         "album_type, album_subtype, album_name, tag_id, cover_uri, is_cover_satisfied) "
236         "VALUES (4096, 4102, 'Test Portrait Album', 'test_tag_id', 'test_cover_uri', 1)");
237 }
238 
InsertFaceTag()239 void CloneSource::InsertFaceTag()
240 {
241     // insert data into VISION_FACE_TAG_TABLE
242     cloneStorePtr_->ExecuteSql(
243         "INSERT INTO " + VISION_FACE_TAG_TABLE + "(tag_id, tag_name, center_features, tag_version, analysis_version) "
244         "VALUES ('test_tag_id', 'Test Face Tag', 'test_center_features', 1, 1)");
245 }
246 
InsertImgFaceTbl()247 void CloneSource::InsertImgFaceTbl()
248 {
249     // insert data into VISION_IMAGE_FACE_TABLE
250     cloneStorePtr_->ExecuteSql(
251         "INSERT INTO " + VISION_IMAGE_FACE_TABLE + " (file_id, face_id, tag_id, scale_x, scale_y) "
252         "VALUES (1, 'test_face_id', 'test_tag_id', 1.0, 1.0)");
253 }
254 
InsertAnalysisPhotoMap()255 void CloneSource::InsertAnalysisPhotoMap()
256 {
257     // map_album, map_asset
258     cloneStorePtr_->ExecuteSql(INSERT_ANALYSIS_PHOTO_MAP + VALUES_BEGIN + "1, 1" + VALUES_END);
259 }
260 
InsertAudio()261 void CloneSource::InsertAudio()
262 {
263     // file_id,
264     // data, size, title,
265     // display_name, media_type, date_added, date_modified, date_taken, duration, is_favorite, date_trashed,
266     // artist
267     cloneStorePtr_->ExecuteSql(INSERT_AUDIO + VALUES_BEGIN + "1, " +
268         "'/storage/cloud/files/Audio/16/AUD_1501924014_000.mp3', 4239718, 'Risk It All', " +
269         "'A8_MUSIC_PRODUCTIONS_-_Risk_It_All.mp3', 3, 1501923914046, 1501923914090, 1704038400, 175490, 0, 0, " +
270         "'A8 MUSIC PRODUCTIONS'" + VALUES_END);
271     cloneStorePtr_->ExecuteSql(INSERT_AUDIO + VALUES_BEGIN + "2, " +
272         "'/storage/cloud/files/Audio/1/AUD_1501924014_001.mp3', 5679616, 'Alone', " +
273         "'Alone_-_Color_Out.mp3', 3, 1501923914157, 1501923914200, 1609430400, 245498, 0, 1501924213700, " +
274         "'Color Out'" + VALUES_END); // trashed
275     cloneStorePtr_->ExecuteSql(INSERT_AUDIO + VALUES_BEGIN + "3, " +
276         "'/storage/cloud/files/Audio/2/AUD_1501924014_002.mp3', 2900316, 'Muito Love', " +
277         "'Ed_Napoli_-_Muito_Love.mp3', 3, 1501923914301, 1501923914326, 1704038400, 120633, 1, 0, " +
278         "'Ed Napoli'" + VALUES_END); // favorite
279     cloneStorePtr_->ExecuteSql(INSERT_AUDIO + VALUES_BEGIN + "4, " +
280         "'/storage/cloud/files/Audio/2/AUD_1501924014_003.mp3', 0, 'size_0', " +
281         "'size_0.mp3', 3, 1501923914301, 1501923914326, 1704038400, 120633, 0, 0, " +
282         "'Ed Napoli'" + VALUES_END); // size = 0
283 }
284 } // namespace Media
285 } // namespace OHOS