• 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 */
15import dataRdb from '@ohos.data.rdb'
16import featureAbility from '@ohos.ability.featureAbility'
17import Contact from '../model/Contact'
18import Logger from '../model/Logger'
19import { TABLE_NAME, SQL_CREATE_TABLE, COLUMNS, STORE_CONFIG } from '../model/RdbConst'
20
21const TAG = 'RdbModel'
22
23class RdbModel {
24    private rdbStore: dataRdb.RdbStore = undefined
25    private tableName: string = ''
26    private sqlCreateTable: string = ''
27    private columns: Array<string> = []
28    private distributedTable: string = ''
29    private dataChangeCallback = null
30    private isCreateDbDone: boolean = false
31
32    constructor(tableName: string, sqlCreateTable: string, columns: Array<string>) {
33        this.tableName = tableName
34        this.sqlCreateTable = sqlCreateTable
35        this.columns = columns
36    }
37
38    async getRdbStore() {
39        Logger.info(TAG, 'getRdbStore begin')
40        if (this.isCreateDbDone) {
41            return
42        }
43        this.rdbStore = await dataRdb.getRdbStore(featureAbility.getContext(), STORE_CONFIG, 1)
44        Logger.info(TAG, 'getRdbStore end')
45        await this.rdbStore.executeSql(this.sqlCreateTable)
46        await this.rdbStore.setDistributedTables([this.tableName])
47        this.isCreateDbDone = true
48        Logger.info(TAG, 'create table done')
49    }
50
51    async insertData(contact: Contact) {
52        const valueBucket = {
53            'name': contact.name,
54            'gender': contact.gender,
55            'phone': contact.phone,
56            'remark': contact.remark
57        }
58        let ret = await this.rdbStore.insert(this.tableName, valueBucket)
59        Logger.info(TAG, `insert done:${ret}`)
60    }
61
62    async updateData(contact: Contact) {
63        const valueBucket = {
64            'name': contact.name,
65            'gender': contact.gender,
66            'phone': contact.phone,
67            'remark': contact.remark
68        }
69        let predicates = new dataRdb.RdbPredicates(this.tableName)
70        Logger.info(TAG, `updateData id=${contact.id}`)
71        predicates.equalTo('id', contact.id)
72        let ret = await this.rdbStore.update(valueBucket, predicates)
73        Logger.info(TAG, `updated row count: ${ret}`)
74    }
75
76    async deleteContacts(contacts: Array<Contact>) {
77        let predicates = new dataRdb.RdbPredicates(this.tableName)
78        contacts.forEach((contact) => {
79            predicates.or()
80                .equalTo('id', contact.id)
81        })
82        let rows = await this.rdbStore.delete(predicates)
83        Logger.info(TAG, `delete rows: ${rows}`)
84    }
85
86    async query(predicates) {
87        Logger.info(TAG, 'query start')
88        let resultSet = await this.rdbStore.query(predicates, this.columns)
89        return this.getListFromResultSet(resultSet)
90    }
91
92    async syncData(predicates) {
93        Logger.info(TAG, 'syncData')
94        let result = await this.rdbStore.sync(dataRdb.SyncMode.SYNC_MODE_PUSH, predicates)
95        for (let i = 0; i < result.length; i++) {
96            Logger.info(TAG, `device=${result[i][0]}, status = ${result[i][1]}`)
97        }
98    }
99
100    async onDataChange(device, callback) {
101        this.distributedTable = await this.rdbStore.obtainDistributedTableName(device, this.tableName)
102        Logger.info(TAG, `obtainDistributedTableName,distributedTable=` + this.distributedTable)
103        this.dataChangeCallback = callback
104        await this.pullData()
105        this.rdbStore.on('dataChange', dataRdb.SubscribeType.SUBSCRIBE_TYPE_REMOTE, async (devices) => {
106            Logger.info(TAG, `on dataChange, callback`)
107            await this.pullData()
108        })
109    }
110
111    async pullData() {
112        await this.rdbStore.executeSql('delete from ' + this.tableName)
113        let predicates = new dataRdb.RdbPredicates(this.distributedTable)
114        let resultSet = await this.rdbStore.query(predicates, this.columns)
115        let result = this.getListFromResultSet(resultSet)
116        Logger.info(TAG, `on dataChange,result.length=${result.length}`)
117        for (let i = 0; i < result.length; i++) {
118            Logger.info(TAG, `on dataChange,insert${result[i].name}`)
119            let predicate = new dataRdb.RdbPredicates(this.tableName)
120            predicate.equalTo('name', result[i].name)
121            let exit = await this.rdbStore.query(predicate, this.columns)
122            exit.goToFirstRow()
123            if (exit.rowCount === 0) {
124                await this.insertData(result[i])
125            } else {
126                result[i].id = exit.getDouble(resultSet.getColumnIndex('id'))
127                await this.updateData(result[i])
128            }
129        }
130        this.dataChangeCallback(result)
131    }
132
133    offDataChange() {
134        this.rdbStore.off('dataChange', dataRdb.SubscribeType.SUBSCRIBE_TYPE_REMOTE, (devices) => {
135            for (let i = 0; i < devices.length; i++) {
136                Logger.info(TAG, `device=${devices[i]} off data changed`)
137            }
138        })
139    }
140
141    getListFromResultSet(resultSet) {
142        Logger.info(TAG, 'getListFromResultSet')
143        let contacts: Array<Contact> = []
144        Logger.info(TAG, `resultSet column names:${resultSet.columnNames}`)
145        Logger.info(TAG, `row count:${resultSet.rowCount}`)
146        Logger.info(TAG, `resultSet goToFirstRow:${resultSet.goToFirstRow()}`)
147        while (!resultSet.isEnded) {
148            let contact = new Contact(resultSet.getDouble(resultSet.getColumnIndex('id'))
149                , resultSet.getString(resultSet.getColumnIndex('name'))
150                , resultSet.getDouble(resultSet.getColumnIndex('gender'))
151                , resultSet.getString(resultSet.getColumnIndex('phone'))
152                , resultSet.getString(resultSet.getColumnIndex('remark')))
153            if (!contacts.includes(contact)) {
154                contacts.push(contact)
155            }
156            resultSet.goToNextRow()
157        }
158        resultSet.close()
159        return contacts
160    }
161}
162
163export default new RdbModel(TABLE_NAME, SQL_CREATE_TABLE, COLUMNS)