• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022 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
16import { atob } from 'js-base64'
17import ohosDataRdb from '@ohos.data.rdb'
18import fileio from '@ohos.fileio'
19import { LogUtil } from './LogUtil'
20import FolderUtil from './FolderUtil'
21import NoteUtil from './NoteUtil'
22import SysDefData from '../model/databaseModel/SysDefData'
23import FolderData from '../model/databaseModel/FolderData'
24import NoteData from '../model/databaseModel/NoteData'
25import { TableSql, TableName, FolderTableColumn, NoteTableColumn, SysDefFolderUuid
26} from '../model/databaseModel/EnumData'
27
28const TAG = "RdbStoreUtil"
29
30const FileMaxSize: number = 20 * 1024 * 1024
31
32/**
33 * db instance
34 */
35
36export default {
37  /**
38   * create db and table
39   */
40  createRdbStore(context) {
41    ohosDataRdb.getRdbStore(context, SysDefData.dbInfo.db_name, SysDefData.dbInfo.db_verison)
42      .then(async (store) => {
43        LogUtil.info(TAG, "createRdbStore, store is " + store)
44        globalThis.rdbStore = store
45        // create table
46        await globalThis.rdbStore.executeSql(TableSql.FolderTableSQL, null)
47        await globalThis.rdbStore.executeSql(TableSql.NoteTableSQL, null)
48        await globalThis.rdbStore.executeSql(TableSql.AttachmentTableSQL, null)
49        await globalThis.rdbStore.executeSql(TableSql.FormTableSQL, null)
50        LogUtil.info(TAG, "create table success")
51        // insert system defined folder
52        await globalThis.rdbStore.insert(TableName.FolderTable, SysDefData.sys_def_allNotes)
53        await globalThis.rdbStore.insert(TableName.FolderTable, SysDefData.sys_def_unClassified)
54        await globalThis.rdbStore.insert(TableName.FolderTable, SysDefData.sys_def_myFavorites)
55        await globalThis.rdbStore.insert(TableName.FolderTable, SysDefData.sys_def_recentDeletes)
56        await globalThis.rdbStore.insert(TableName.FolderTable, SysDefData.sys_def_personal)
57        await globalThis.rdbStore.insert(TableName.FolderTable, SysDefData.sys_def_life)
58        await globalThis.rdbStore.insert(TableName.FolderTable, SysDefData.sys_def_work)
59        LogUtil.info(TAG, "insert system defined folder success")
60        // insert system defined note and attachment
61        await globalThis.rdbStore.insert(TableName.NoteTable, SysDefData.sys_def_note1)
62        await globalThis.rdbStore.insert(TableName.NoteTable, SysDefData.sys_def_note2)
63        await globalThis.rdbStore.insert(TableName.NoteTable, SysDefData.sys_def_note3)
64        await globalThis.rdbStore.insert(TableName.NoteTable, SysDefData.sys_def_note4)
65        LogUtil.info(TAG, "insert system defined note and attachment success")
66
67        // add sys-def folder and note to AppStorage
68        let folderDataArray = []
69        let sysDefFolderArray = [SysDefData.sys_def_allNotes, SysDefData.sys_def_unClassified,
70        SysDefData.sys_def_myFavorites, SysDefData.sys_def_recentDeletes,
71        SysDefData.sys_def_personal, SysDefData.sys_def_life, SysDefData.sys_def_work]
72        sysDefFolderArray.forEach((sysDefFolder) => {
73          let folderData = new FolderData(sysDefFolder.id, sysDefFolder.name, sysDefFolder.uuid, sysDefFolder.color,
74            sysDefFolder.folder_type, sysDefFolder.is_deleted, sysDefFolder.created_time,
75            sysDefFolder.modified_time)
76          folderDataArray.push(folderData)
77        })
78        LogUtil.info(TAG, "folderDataArray[sysdef] : " + folderDataArray.length)
79
80        let noteDataArray = []
81        let sysDefNoteArray = [SysDefData.sys_def_note1, SysDefData.sys_def_note2,
82        SysDefData.sys_def_note3, SysDefData.sys_def_note4]
83        sysDefNoteArray.forEach((sysDefNote) => {
84          let noteData = new NoteData(sysDefNote.id, sysDefNote.title, sysDefNote.uuid, sysDefNote.folder_uuid, sysDefNote.content_text,
85            sysDefNote.content_img, sysDefNote.note_type, sysDefNote.is_top, sysDefNote.is_favorite,
86            sysDefNote.is_deleted, sysDefNote.created_time, sysDefNote.modified_time, sysDefNote.deleted_time, sysDefNote.slider_value)
87          noteDataArray.push(noteData)
88        })
89        LogUtil.info(TAG, "noteDataArray[sysdef] : " + noteDataArray.length)
90
91        AppStorage.SetOrCreate('AllFolderArray', folderDataArray)
92        AppStorage.SetOrCreate('AllNoteArray', noteDataArray)
93        LogUtil.info(TAG, "AppStorage[sysdef] set AllFolderArray and AllNoteArray success")
94
95        // save continue data
96        let isContinue = AppStorage.Get<boolean>('IsContinue');
97        LogUtil.info(TAG, "createRdbStore, isContinue is " + isContinue)
98        if (isContinue) {
99          let continueNote: string = AppStorage.Get('ContinueNote')
100          let continueSection = AppStorage.Get('ContinueSection')
101          let noteObj = JSON.parse(continueNote)
102          let noteData = new NoteData(noteObj.uuid, noteObj.title, noteObj.uuid, noteObj.folder_uuid,
103            noteObj.content_text, noteObj.content_img, noteObj.note_type, noteObj.is_top, noteObj.is_favorite,
104            noteObj.is_deleted, noteObj.created_time, noteObj.modified_time, noteObj.deleted_time, noteObj.slider_value)
105
106          // save img to FileDir
107          LogUtil.info(TAG, "createRdbStore, save img to FileDir")
108          let imgNameArray = this.getImgNameFromHtml(noteData)
109          imgNameArray.forEach((imgName: string) => {
110            this.writeToFileDir(imgName)
111          })
112
113          // if not exit this note
114          let exist = false
115          let folderUuid = ""
116          for (let note of noteDataArray) {
117            if (noteData.created_time == note.created_time) {
118              exist = true
119              folderUuid = note.folder_uuid
120              break
121            }
122          }
123          LogUtil.info(TAG, "createRdbStore, exist : " + exist)
124          if (!exist) {
125            // 迁移过来的笔记在本地不存在,则保存在未分类文件夹
126            noteData.folder_uuid = SysDefFolderUuid.UnClassified
127            noteDataArray.push(noteData)
128            AppStorage.SetOrCreate('AllNoteArray', noteDataArray)
129            this.insert(TableName.NoteTable, noteData.toNoteObject(), null)
130            AppStorage.SetOrCreate('Folder', FolderUtil.getFolderData(folderDataArray, SysDefFolderUuid.UnClassified))
131          } else {
132            // 迁移过来的笔记在本地存在,则进行修改
133            for (let i = 0; i < noteDataArray.length; i++) {
134              if (noteData.created_time == noteDataArray[i].created_time) {
135                noteDataArray[i] = noteData
136                LogUtil.info(TAG, "createRdbStore, update noteData in noteDataArray success")
137                break
138              }
139            }
140            let predicates_note = this.getRdbPredicates(TableName.NoteTable)
141            predicates_note.equalTo(NoteTableColumn.CreatedTime, noteData.created_time)
142            this.update(noteData.toNoteObject(), predicates_note, null)
143            AppStorage.SetOrCreate('Folder', FolderUtil.getFolderData(folderDataArray, folderUuid))
144          }
145          AppStorage.SetOrCreate('Note', noteData)
146          AppStorage.SetOrCreate<string>('ContinueNote', JSON.stringify(noteData.toNoteObject()))
147          AppStorage.SetOrCreate('Section', continueSection)
148          AppStorage.SetOrCreate<NoteData>('NewNote', noteData)
149        } else {
150          LogUtil.info(TAG, "createRdbStore, IsContinue false")
151          AppStorage.SetOrCreate('Folder', AppStorage.Get('AllFolderArray')[0])
152          let note = NoteUtil.getFirstNoteData(AppStorage.Get('AllNoteArray'), SysDefFolderUuid.AllNotes)
153          AppStorage.SetOrCreate('Note', note)
154          if (note) {
155            AppStorage.SetOrCreate<string>('ContinueNote', JSON.stringify(note.toNoteObject()))
156          }
157          AppStorage.SetOrCreate('Section', 3)
158        }
159        AppStorage.SetOrCreate('DBQueryFinished', 1)
160        LogUtil.info(TAG, "createRdbStore, set DBQueryFinished 1")
161      })
162      .catch((err) => {
163        LogUtil.warn(TAG, "createRdbStore, error : " + err)
164      })
165  },
166
167  /**
168   * query folders and notes from the database, then save them to the AppStorage.
169   */
170  initAppStorage(context) {
171    let folderDataArray = []
172    let noteDataArray = []
173    ohosDataRdb.getRdbStore(context, SysDefData.dbInfo.db_name, SysDefData.dbInfo.db_verison)
174      .then(async (store) => {
175        LogUtil.info(TAG, "initAppStorage, store is " + store)
176        globalThis.rdbStore = store
177        // query folder
178        let columns_folder = []
179        let predicates_folder = new ohosDataRdb.RdbPredicates(TableName.FolderTable)
180        let resultSet_folder = await globalThis.rdbStore.query(predicates_folder, columns_folder)
181        while (resultSet_folder.goToNextRow()) {
182          let id = resultSet_folder.getLong(resultSet_folder.getColumnIndex(FolderTableColumn.Id))
183          let name = resultSet_folder.getString(resultSet_folder.getColumnIndex(FolderTableColumn.Name))
184          let uuid = resultSet_folder.getString(resultSet_folder.getColumnIndex(FolderTableColumn.Uuid))
185          let color = resultSet_folder.getString(resultSet_folder.getColumnIndex(FolderTableColumn.Color))
186          let folder_type = resultSet_folder.getLong(resultSet_folder.getColumnIndex(FolderTableColumn.FolderType))
187          let is_deleted = resultSet_folder.getLong(resultSet_folder.getColumnIndex(FolderTableColumn.IsDeleted))
188          let created_time = resultSet_folder.getLong(resultSet_folder.getColumnIndex(FolderTableColumn.CreatedTime))
189          let modified_time = resultSet_folder.getLong(resultSet_folder.getColumnIndex(FolderTableColumn.ModifiedTime))
190          let folderData = new FolderData(id, name, uuid, color, folder_type, is_deleted, created_time, modified_time)
191          folderDataArray.push(folderData)
192        }
193        LogUtil.info(TAG, "folderDataArray[query] : " + folderDataArray.length)
194        // query note
195        let columns_note = []
196        let predicates_note = new ohosDataRdb.RdbPredicates(TableName.NoteTable)
197        let resultSet_note = await globalThis.rdbStore.query(predicates_note, columns_note)
198        while (resultSet_note.goToNextRow()) {
199          let id = resultSet_note.getLong(resultSet_note.getColumnIndex(NoteTableColumn.Id))
200          let title = resultSet_note.getString(resultSet_note.getColumnIndex(NoteTableColumn.Title))
201          let uuid = resultSet_note.getString(resultSet_note.getColumnIndex(NoteTableColumn.Uuid))
202          let folder_uuid = resultSet_note.getString(resultSet_note.getColumnIndex(NoteTableColumn.FolderUuid))
203          // 暂时规避备忘录二次打开白屏问题,后续数据库解决
204          let content_text = '';
205          let content_img = '';
206          try {
207            content_text = resultSet_note.getString(resultSet_note.getColumnIndex(NoteTableColumn.ContentText))
208            content_img = resultSet_note.getString(resultSet_note.getColumnIndex(NoteTableColumn.ContentImg))
209          } catch (err) {
210            LogUtil.error(TAG, "initAppStorage, content_img = error : " + err)
211          }
212          let noteType = resultSet_note.getLong(resultSet_note.getColumnIndex(NoteTableColumn.NoteType))
213          let is_top = resultSet_note.getLong(resultSet_note.getColumnIndex(NoteTableColumn.IsTop))
214          let is_favorite = resultSet_note.getLong(resultSet_note.getColumnIndex(NoteTableColumn.IsFavorite))
215          let is_deleted = resultSet_note.getLong(resultSet_note.getColumnIndex(NoteTableColumn.IsDeleted))
216          let created_time = resultSet_note.getLong(resultSet_note.getColumnIndex(NoteTableColumn.CreatedTime))
217          let modified_time = resultSet_note.getLong(resultSet_note.getColumnIndex(NoteTableColumn.ModifiedTime))
218          let deleted_time = resultSet_note.getLong(resultSet_note.getColumnIndex(NoteTableColumn.DeletedTime))
219          let slider_value = resultSet_note.getLong(resultSet_note.getColumnIndex(NoteTableColumn.SliderValue))
220          let noteData = new NoteData(id, title, uuid, folder_uuid, content_text, content_img, noteType, is_top, is_favorite, is_deleted, created_time, modified_time, deleted_time, slider_value)
221          noteDataArray.push(noteData)
222        }
223        LogUtil.info(TAG, "noteDataArray[query] : " + noteDataArray.length)
224
225        AppStorage.SetOrCreate('AllFolderArray', folderDataArray)
226        AppStorage.SetOrCreate('AllNoteArray', noteDataArray)
227        LogUtil.info(TAG, "AppStorage[query] set AllFolderArray and AllNoteArray success")
228
229        // save continue data
230        let isContinue = AppStorage.Get<boolean>('IsContinue');
231        LogUtil.info(TAG, "initAppStorage, isContinue is " + isContinue)
232        if (isContinue) {
233          let continueNote: string = AppStorage.Get('ContinueNote')
234          let continueSection = AppStorage.Get('ContinueSection')
235
236          let noteObj = JSON.parse(continueNote)
237          let noteData = new NoteData(noteObj.uuid, noteObj.title, noteObj.uuid, noteObj.folder_uuid,
238            noteObj.content_text, noteObj.content_img, noteObj.note_type, noteObj.is_top, noteObj.is_favorite,
239            noteObj.is_deleted, noteObj.created_time, noteObj.modified_time, noteObj.deleted_time, noteObj.slider_value)
240
241          // save img to FileDir
242          LogUtil.info(TAG, "initAppStorage, save img to FileDir")
243          let imgNameArray = this.getImgNameFromHtml(noteData)
244          imgNameArray.forEach((imgName: string) => {
245            this.writeToFileDir(imgName)
246          })
247
248          // if not exit this note
249          let exist = false
250          let folderUuid = ""
251          for (let note of noteDataArray) {
252            if (noteData.created_time == note.created_time) {
253              exist = true
254              folderUuid = note.folder_uuid
255              break
256            }
257          }
258          LogUtil.info(TAG, "initAppStorage, exist : " + exist)
259          if (!exist) {
260            // 迁移过来的笔记在本地不存在,则保存在未分类文件夹
261            noteData.folder_uuid = SysDefFolderUuid.UnClassified
262            noteDataArray.push(noteData)
263            AppStorage.SetOrCreate('AllNoteArray', noteDataArray)
264            this.insert(TableName.NoteTable, noteData.toNoteObject(), null)
265            AppStorage.SetOrCreate('Folder', FolderUtil.getFolderData(folderDataArray, SysDefFolderUuid.UnClassified))
266          } else {
267            // 迁移过来的笔记在本地存在,则进行修改
268            for (let i = 0; i < noteDataArray.length; i++) {
269              if (noteData.created_time == noteDataArray[i].created_time) {
270                noteDataArray[i] = noteData
271                LogUtil.info(TAG, "initAppStorage, update noteData in noteDataArray success")
272                break
273              }
274            }
275            let predicates_note = this.getRdbPredicates(TableName.NoteTable)
276            predicates_note.equalTo(NoteTableColumn.CreatedTime, noteData.created_time)
277            this.update(noteData.toNoteObject(), predicates_note, null)
278            AppStorage.SetOrCreate('Folder', FolderUtil.getFolderData(folderDataArray, folderUuid))
279          }
280          AppStorage.SetOrCreate('Note', noteData)
281          AppStorage.SetOrCreate<string>('ContinueNote', JSON.stringify(noteData.toNoteObject()))
282          AppStorage.SetOrCreate('Section', continueSection)
283          AppStorage.SetOrCreate<NoteData>('NewNote', noteData)
284        } else {
285          LogUtil.info(TAG, "initAppStorage, IsContinue false")
286          AppStorage.SetOrCreate('Folder', AppStorage.Get('AllFolderArray')[0])
287          let note = NoteUtil.getFirstNoteData(AppStorage.Get('AllNoteArray'), SysDefFolderUuid.AllNotes)
288          AppStorage.SetOrCreate('Note', note)
289          if (note) {
290            AppStorage.SetOrCreate<string>('ContinueNote', JSON.stringify(note.toNoteObject()))
291          }
292          AppStorage.SetOrCreate('Section', 3)
293        }
294        AppStorage.SetOrCreate('DBQueryFinished', 1)
295        LogUtil.info(TAG, "initAppStorage, set DBQueryFinished 1")
296      })
297      .catch((err) => {
298        LogUtil.error(TAG, "initAppStorage, error : " + err)
299      })
300  },
301
302  getImgNameFromHtml(noteData: NoteData): any{
303    let newModuleName = "file://" + globalThis.noteContext.filesDir
304    let imgNameArray = []
305    if (noteData.content_text == undefined || noteData.content_text == null || noteData.content_text == "") {
306      LogUtil.info(TAG, "noteData.content_text is null or undefined")
307      return imgNameArray
308    }
309    let base64regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/
310    let html = ""
311    if (base64regex.test(noteData.content_text)) {
312      html = atob(noteData.content_text)
313    } else {
314      html = noteData.content_text
315    }
316    if (html == undefined || html == null || html == "") {
317      return imgNameArray
318    }
319    let imgReg = /<img[^>]+>/g
320    let srcReg = /src=[\'\"]?([^\'\"]*)[\'\"]?/i
321    let imgArray = html.match(imgReg)
322    if (imgArray != null) {
323      let hasFirstImg: boolean = false
324      for (let i = 0; i < imgArray.length; i++) {
325        let src = imgArray[i].match(srcReg)
326        if (src != null && src.length > 1) {
327          LogUtil.info(TAG, "getImgNameFromHtml, src[1] : " + src[1])
328          let lastIndex = src[1].lastIndexOf('/')
329          if (lastIndex != -1) {
330            let oldModuleName = src[1].substring(0, lastIndex)
331            let imgName = src[1].substring(lastIndex + 1)
332            noteData.content_text = noteData.content_text.replace(oldModuleName, newModuleName)
333            if (!hasFirstImg) {
334              noteData.content_img = newModuleName + "/" + imgName
335              hasFirstImg = true
336            }
337            imgNameArray.push(imgName)
338          }
339        }
340      }
341    }
342    return imgNameArray
343  },
344
345  writeToFileDir(fileName: string) {
346    LogUtil.info(TAG, "writeToFileDir fileName : " + fileName)
347
348    let desPath = globalThis.noteContext.filesDir + "/" + fileName
349    LogUtil.info(TAG, "desPath : " + desPath)
350    try {
351      fileio.accessSync(desPath)
352      LogUtil.info(TAG, "desPath has existed, return")
353      return
354    } catch (err) {
355      LogUtil.warn(TAG, "desPath has not existed, need to write")
356    }
357    let srcPath
358    let size
359    try{
360      srcPath = globalThis.noteContext.distributedFilesDir + "/" + fileName
361      LogUtil.info(TAG, "srcPath : " + srcPath)
362      size = fileio.statSync(srcPath).size
363      LogUtil.info(TAG, "srcPath size : " + size)
364      if (size > FileMaxSize) {
365        LogUtil.warn(TAG, "srcPath size more then FileMaxSize, return")
366        return
367      }
368    }
369    catch (err) {
370      LogUtil.warn(TAG, "desPath has not existed, need to write two")
371      return
372    }
373
374
375    let srcFd
376    try {
377      srcFd = fileio.openSync(srcPath, 0o0)
378      LogUtil.info(TAG, "open srcPath success : " + srcFd)
379    } catch (err) {
380      LogUtil.warn(TAG, "open srcPath failed : " + err)
381      return
382    }
383
384    let desFd
385    try {
386      desFd = fileio.openSync(desPath, 0o2 | 0o100, 0o400 | 0o200 | 0o040 | 0o020)
387      LogUtil.info(TAG, "open desPath success : " + srcFd)
388    } catch (err) {
389      LogUtil.warn(TAG, "open desPath failed : " + err)
390      return
391    }
392
393    let buf = new ArrayBuffer(size)
394    try {
395      let readNum = fileio.readSync(srcFd, buf)
396      LogUtil.info(TAG, "readNum : " + readNum)
397      let writeNum = fileio.writeSync(desFd, buf)
398      LogUtil.info(TAG, "writeNum : " + writeNum)
399    } catch (err) {
400      LogUtil.warn(TAG, "read or write error : " + err)
401    }
402  },
403
404  /**
405   * insert
406   * @param tableName
407   * @param valueBucket
408   * @param callback
409   */
410  insert(tableName, valueBucket, callback) {
411    globalThis.rdbStore.insert(tableName, valueBucket).then((rowId) => {
412      LogUtil.info(TAG, "insert success, rowId is " + rowId)
413      if (callback != null) {
414        callback(rowId)
415      }
416    }).catch((err) => {
417      LogUtil.warn(TAG, "insert error : " + err)
418    })
419  },
420
421  /**
422   * delete
423   * @param predicates
424   * @param callback
425   */
426  delete(predicates, callback) {
427    globalThis.rdbStore.delete(predicates).then((affectedRowCount) => {
428      LogUtil.info(TAG, "delete success, affectedRowCount is " + affectedRowCount)
429      if (callback != null) {
430        callback(affectedRowCount)
431      }
432    }).catch((err) => {
433      LogUtil.warn(TAG, "delete error : " + err)
434    })
435  },
436
437  /**
438   * update
439   * @param valueBucket
440   * @param predicates
441   * @param callback
442   */
443  update(valueBucket, predicates, callback) {
444    if (!globalThis.rdbStore) {
445      return;
446    }
447    globalThis.rdbStore.update(valueBucket, predicates).then((affectedRowCount) => {
448      LogUtil.info(TAG, "update success, affectedRowCount is " + affectedRowCount)
449      if (callback != null) {
450        callback(affectedRowCount)
451      }
452    }).catch((err) => {
453      LogUtil.warn(TAG, "update error : " + err)
454    })
455  },
456
457  /**
458   * query
459   * @param columns
460   * @param predicates
461   * @param callback
462   */
463  query(columns, predicates, callback) {
464    globalThis.rdbStore.query(predicates, columns).then((resultSet) => {
465      LogUtil.info(TAG, "query success, row count : " + resultSet.rowCount)
466      if (callback != null) {
467        callback(resultSet)
468      }
469    }).catch((err) => {
470      LogUtil.warn(TAG, "query error : " + err)
471    })
472  },
473
474  /**
475   * get RdbPredicates by table name
476   * @param tableName
477   */
478  getRdbPredicates(tableName) {
479    return new ohosDataRdb.RdbPredicates(tableName)
480  },
481
482  updataNoteImage(noteData: NoteData): string {
483    let content_img = ""
484    let imgNameArray = this.getImgNameFromHtml(noteData)
485    if (imgNameArray.length == 0) {
486      return content_img
487    }
488    if (imgNameArray[0] == 'shuxue.png' || imgNameArray[0] == 'cake.png') {
489      content_img = "/res/" + imgNameArray[0]
490    } else {
491      content_img = noteData.content_img
492    }
493    LogUtil.info(TAG, "updataNoteImage, content_img : " + content_img)
494    return content_img
495  }
496}