mirror of
https://gitee.com/openharmony/distributeddatamgr_relational_store
synced 2024-11-27 01:01:02 +00:00
open read-only database
Signed-off-by: leiiyb <leiyanbo@huawei.com>
This commit is contained in:
parent
d55dec6fad
commit
f827d9821a
@ -42,6 +42,7 @@ struct RdbConfig {
|
||||
bool isAutoClean = false;
|
||||
bool vector = false;
|
||||
bool allowRebuild = false;
|
||||
bool isReadOnly = false;
|
||||
SecurityLevel securityLevel = SecurityLevel::LAST;
|
||||
std::string dataGroupId;
|
||||
std::string name;
|
||||
|
@ -315,6 +315,9 @@ int32_t Convert2Value(napi_env env, napi_value jsValue, RdbConfig &rdbConfig)
|
||||
|
||||
GetNamedProperty(env, jsValue, "allowRebuild", rdbConfig.allowRebuild, true);
|
||||
ASSERT(OK == status, "get allowRebuild failed.", napi_invalid_arg);
|
||||
|
||||
GetNamedProperty(env, jsValue, "isReadOnly", rdbConfig.isReadOnly, true);
|
||||
ASSERT(OK == status, "get isReadOnly failed.", napi_invalid_arg);
|
||||
return napi_ok;
|
||||
}
|
||||
|
||||
@ -423,6 +426,7 @@ RdbStoreConfig GetRdbStoreConfig(const RdbConfig &rdbConfig, const ContextParam
|
||||
rdbStoreConfig.SetName(rdbConfig.name);
|
||||
rdbStoreConfig.SetCustomDir(rdbConfig.customDir);
|
||||
rdbStoreConfig.SetAllowRebuild(rdbConfig.allowRebuild);
|
||||
rdbStoreConfig.SetReadOnly(rdbConfig.isReadOnly);
|
||||
|
||||
if (!param.bundleName.empty()) {
|
||||
rdbStoreConfig.SetBundleName(param.bundleName);
|
||||
|
@ -1284,6 +1284,7 @@ napi_value RdbStoreProxy::GetVersion(napi_env env, napi_callback_info info)
|
||||
env, rdbStoreProxy && rdbStoreProxy->GetInstance(), std::make_shared<ParamError>("RdbStore", "valid"));
|
||||
int32_t version = 0;
|
||||
int out = rdbStoreProxy->GetInstance()->GetVersion(version);
|
||||
RDB_NAPI_ASSERT(env, out == E_OK, std::make_shared<InnerError>(out));
|
||||
LOG_DEBUG("RdbStoreProxy::GetVersion out is : %{public}d", out);
|
||||
return JSUtils::Convert2JSValue(env, version);
|
||||
}
|
||||
@ -1313,6 +1314,7 @@ napi_value RdbStoreProxy::SetVersion(napi_env env, napi_callback_info info)
|
||||
napi_get_value_int32(env, args[0], &version);
|
||||
RDB_NAPI_ASSERT(env, version > 0, std::make_shared<ParamError>("version", "> 0"));
|
||||
int out = rdbStoreProxy->GetInstance()->SetVersion(version);
|
||||
RDB_NAPI_ASSERT(env, out == E_OK, std::make_shared<InnerError>(out));
|
||||
LOG_DEBUG("RdbStoreProxy::SetVersion out is : %{public}d", out);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -324,7 +324,7 @@ RdbStoreImpl::RdbStoreImpl(const RdbStoreConfig &config, int &errCode)
|
||||
{
|
||||
path_ = (config.GetRoleType() == VISITOR) ? config.GetVisitorDir() : config.GetPath();
|
||||
connectionPool_ = SqliteConnectionPool::Create(config_, errCode);
|
||||
if (connectionPool_ == nullptr && errCode == E_SQLITE_CORRUPT && config.GetAllowRebuild()) {
|
||||
if (connectionPool_ == nullptr && errCode == E_SQLITE_CORRUPT && config.GetAllowRebuild() && !config.IsReadOnly()) {
|
||||
auto realPath = config.GetPath();
|
||||
RemoveDbFiles(realPath);
|
||||
connectionPool_ = SqliteConnectionPool::Create(config_, errCode);
|
||||
@ -917,7 +917,7 @@ std::pair<int32_t, ValueObject> RdbStoreImpl::ExecuteEntry(const std::string &sq
|
||||
|
||||
auto connect = connectionPool_->AcquireConnection(false);
|
||||
if (connect == nullptr) {
|
||||
return { E_CON_OVER_LIMIT, object };
|
||||
return { E_DATABASE_BUSY, object };
|
||||
}
|
||||
|
||||
auto [errCode, statement] = GetStatement(sql, connect);
|
||||
@ -1211,7 +1211,7 @@ int RdbStoreImpl::AttachInner(
|
||||
std::pair<int32_t, int32_t> RdbStoreImpl::Attach(
|
||||
const RdbStoreConfig &config, const std::string &attachName, int32_t waitTime)
|
||||
{
|
||||
if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR)) {
|
||||
if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) {
|
||||
return { E_NOT_SUPPORT, 0 };
|
||||
}
|
||||
std::string dbPath;
|
||||
@ -1255,7 +1255,7 @@ std::pair<int32_t, int32_t> RdbStoreImpl::Attach(
|
||||
|
||||
std::pair<int32_t, int32_t> RdbStoreImpl::Detach(const std::string &attachName, int32_t waitTime)
|
||||
{
|
||||
if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR)) {
|
||||
if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) {
|
||||
return { E_NOT_SUPPORT, 0 };
|
||||
}
|
||||
if (!attachedInfo_.Contains(attachName)) {
|
||||
@ -1302,9 +1302,11 @@ int RdbStoreImpl::GetVersion(int &version)
|
||||
if (config_.GetDBType() == DB_VECTOR) {
|
||||
return E_NOT_SUPPORT;
|
||||
}
|
||||
auto [errCode, statement] = GetStatement(GlobalExpr::PRAGMA_VERSION, config_.GetRoleType() == VISITOR);
|
||||
|
||||
bool isRead = (config_.IsReadOnly()) || (config_.GetRoleType() == VISITOR);
|
||||
auto [errCode, statement] = GetStatement(GlobalExpr::PRAGMA_VERSION, isRead);
|
||||
if (statement == nullptr) {
|
||||
return E_CON_OVER_LIMIT;
|
||||
return errCode;
|
||||
}
|
||||
ValueObject value;
|
||||
std::tie(errCode, value) = statement->ExecuteForValue();
|
||||
@ -1327,7 +1329,7 @@ int RdbStoreImpl::SetVersion(int version)
|
||||
std::string sql = std::string(GlobalExpr::PRAGMA_VERSION) + " = " + std::to_string(version);
|
||||
auto [errCode, statement] = GetStatement(sql);
|
||||
if (statement == nullptr) {
|
||||
return E_CON_OVER_LIMIT;
|
||||
return errCode;
|
||||
}
|
||||
return statement->Execute();
|
||||
}
|
||||
@ -1346,7 +1348,7 @@ int RdbStoreImpl::BeginTransaction()
|
||||
BaseTransaction transaction(connectionPool_->GetTransactionStack().size());
|
||||
auto [errCode, statement] = GetStatement(transaction.GetTransactionStr());
|
||||
if (statement == nullptr) {
|
||||
return E_CON_OVER_LIMIT;
|
||||
return errCode;
|
||||
}
|
||||
errCode = statement->Execute();
|
||||
if (errCode != E_OK) {
|
||||
@ -1369,9 +1371,10 @@ int RdbStoreImpl::BeginTransaction()
|
||||
std::pair<int, int64_t> RdbStoreImpl::BeginTrans()
|
||||
{
|
||||
DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
|
||||
if (!config_.IsVector()) {
|
||||
if (!config_.IsVector() || config_.IsReadOnly()) {
|
||||
return {E_NOT_SUPPORT, 0};
|
||||
}
|
||||
|
||||
auto time = static_cast<uint64_t>(duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count());
|
||||
int64_t tmpTrxId = 0;
|
||||
auto [errCode, connection] = connectionPool_->CreateConnection(false);
|
||||
@ -1539,7 +1542,7 @@ int RdbStoreImpl::CheckAttach(const std::string &sql)
|
||||
|
||||
auto [errCode, statement] = GetStatement(GlobalExpr::PRAGMA_JOUR_MODE_EXP);
|
||||
if (statement == nullptr) {
|
||||
return E_CON_OVER_LIMIT;
|
||||
return errCode;
|
||||
}
|
||||
|
||||
errCode = statement->Execute();
|
||||
@ -1656,6 +1659,10 @@ int RdbStoreImpl::ConfigLocale(const std::string &localeStr)
|
||||
|
||||
int RdbStoreImpl::Restore(const std::string &backupPath, const std::vector<uint8_t> &newKey)
|
||||
{
|
||||
if (config_.IsReadOnly()) {
|
||||
return E_NOT_SUPPORT;
|
||||
}
|
||||
|
||||
if (!isOpen_) {
|
||||
LOG_ERROR("The connection pool has been closed.");
|
||||
return E_ERROR;
|
||||
@ -1715,7 +1722,7 @@ int RdbStoreImpl::SetDistributedTables(const std::vector<std::string> &tables, i
|
||||
const DistributedRdb::DistributedConfig &distributedConfig)
|
||||
{
|
||||
DISTRIBUTED_DATA_HITRACE(std::string(__FUNCTION__));
|
||||
if (config_.GetDBType() == DB_VECTOR) {
|
||||
if (config_.GetDBType() == DB_VECTOR || config_.IsReadOnly()) {
|
||||
return E_NOT_SUPPORT;
|
||||
}
|
||||
if (tables.empty()) {
|
||||
@ -1871,7 +1878,7 @@ int32_t RdbStoreImpl::SubscribeLocalDetail(const SubscribeOption &option,
|
||||
{
|
||||
auto connection = connectionPool_->AcquireConnection(false);
|
||||
if (connection == nullptr) {
|
||||
return E_CON_OVER_LIMIT;
|
||||
return E_DATABASE_BUSY;
|
||||
}
|
||||
int32_t errCode = connection->Subscribe(option.event, observer);
|
||||
if (errCode != E_OK) {
|
||||
@ -2004,7 +2011,7 @@ int32_t RdbStoreImpl::UnsubscribeLocalDetail(const SubscribeOption& option,
|
||||
{
|
||||
auto connection = connectionPool_->AcquireConnection(false);
|
||||
if (connection == nullptr) {
|
||||
return E_CON_OVER_LIMIT;
|
||||
return E_DATABASE_BUSY;
|
||||
}
|
||||
int32_t errCode = connection->Unsubscribe(option.event, observer);
|
||||
if (errCode != E_OK) {
|
||||
@ -2131,7 +2138,8 @@ int RdbStoreImpl::RegisterDataChangeCallback()
|
||||
if (!config_.IsSearchable()) {
|
||||
return E_OK;
|
||||
}
|
||||
if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR)) {
|
||||
|
||||
if ((config_.GetRoleType() == VISITOR) || (config_.GetDBType() == DB_VECTOR) || (config_.IsReadOnly())) {
|
||||
return E_NOT_SUPPORT;
|
||||
}
|
||||
InitDelayNotifier();
|
||||
@ -2229,7 +2237,7 @@ std::pair<int32_t, std::shared_ptr<Statement>> RdbStoreImpl::GetStatement(
|
||||
const std::string &sql, std::shared_ptr<Connection> conn) const
|
||||
{
|
||||
if (conn == nullptr) {
|
||||
return { E_CON_OVER_LIMIT, nullptr };
|
||||
return { E_DATABASE_BUSY, nullptr };
|
||||
}
|
||||
return conn->CreateStatement(sql, conn);
|
||||
}
|
||||
@ -2238,7 +2246,7 @@ std::pair<int32_t, std::shared_ptr<Statement>> RdbStoreImpl::GetStatement(const
|
||||
{
|
||||
auto conn = connectionPool_->AcquireConnection(read);
|
||||
if (conn == nullptr) {
|
||||
return { E_CON_OVER_LIMIT, nullptr };
|
||||
return { E_DATABASE_BUSY, nullptr };
|
||||
}
|
||||
return conn->CreateStatement(sql, conn);
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ std::shared_ptr<RdbStore> RdbStoreManager::GetRdbStore(const RdbStoreConfig &con
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (config.GetRoleType() == OWNER) {
|
||||
if (config.GetRoleType() == OWNER && !config.IsReadOnly()) {
|
||||
errCode = SetSecurityLabel(config);
|
||||
if (errCode != E_OK) {
|
||||
LOG_ERROR("fail, storeName:%{public}s security %{public}d errCode:%{public}d", config.GetName().c_str(),
|
||||
@ -210,11 +210,6 @@ int RdbStoreManager::ProcessOpenCallback(
|
||||
return openCallback.OnOpen(rdbStore);
|
||||
}
|
||||
|
||||
if (config.IsReadOnly()) {
|
||||
LOG_ERROR("RdbHelper ProcessOpenCallback Can't upgrade read-only store");
|
||||
return E_CANNOT_UPDATE_READONLY;
|
||||
}
|
||||
|
||||
if (currentVersion == 0) {
|
||||
errCode = openCallback.OnCreate(rdbStore);
|
||||
} else if (version > currentVersion) {
|
||||
|
@ -60,7 +60,7 @@ std::pair<int32_t, std::shared_ptr<Connection>> ConnPool::Init(const RdbStoreCon
|
||||
{
|
||||
std::pair<int32_t, std::shared_ptr<Connection>> result;
|
||||
auto &[errCode, conn] = result;
|
||||
if (config.GetRoleType() == OWNER) {
|
||||
if (config.GetRoleType() == OWNER && !config.IsReadOnly()) {
|
||||
// write connect count is 1
|
||||
std::shared_ptr<ConnPool::ConnNode> node;
|
||||
std::tie(errCode, node) = writers_.Initialize(
|
||||
|
@ -598,7 +598,7 @@ private:
|
||||
std::string customDir_;
|
||||
std::vector<uint8_t> encryptKey_{};
|
||||
std::map<std::string, ScalarFunctionInfo> customScalarFunctions;
|
||||
|
||||
|
||||
static constexpr int MAX_TIMEOUT = 300; // seconds
|
||||
static constexpr int MIN_TIMEOUT = 1; // seconds
|
||||
bool allowRebuilt_ = false;
|
||||
|
@ -229,7 +229,7 @@ private:
|
||||
std::string customDir_;
|
||||
std::vector<uint8_t> encryptKey_{};
|
||||
std::map<std::string, ScalarFunctionInfo> customScalarFunctions;
|
||||
|
||||
|
||||
static constexpr int MAX_TIMEOUT = 300; // seconds
|
||||
static constexpr int MIN_TIMEOUT = 1; // seconds
|
||||
bool allowRebuilt_ = false;
|
||||
|
@ -0,0 +1,302 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from '@ohos/hypium';
|
||||
import relationalStore from '@ohos.data.relationalStore';
|
||||
import featureAbility from '@ohos.ability.featureAbility'
|
||||
|
||||
let context = featureAbility.getContext();
|
||||
let store = undefined;
|
||||
|
||||
const TAG = "[RELATIONAL_STORE_JS_READ_ONLY_TEST]";
|
||||
|
||||
let STORE_CONFIG = {
|
||||
name: "store.db",
|
||||
securityLevel: relationalStore.SecurityLevel.S1,
|
||||
}
|
||||
let STORE_CONFIG1 = {
|
||||
name: "test.db",
|
||||
securityLevel: relationalStore.SecurityLevel.S1,
|
||||
isReadOnly: true,
|
||||
}
|
||||
|
||||
let STORE_CONFIG2 = {
|
||||
name: "readOnly.db",
|
||||
securityLevel: relationalStore.SecurityLevel.S1,
|
||||
isReadOnly: true,
|
||||
}
|
||||
|
||||
const valueBucket = {
|
||||
'name': 'zhangsan',
|
||||
'age': 18,
|
||||
'salary': 25000,
|
||||
'blobType': new Uint8Array([1, 2, 3]),
|
||||
};
|
||||
|
||||
describe('rdbStoreReadOnlyTest', function () {
|
||||
beforeAll(async function () {
|
||||
console.log(TAG + 'beforeAll');
|
||||
try {
|
||||
await relationalStore.deleteRdbStore(context, STORE_CONFIG);
|
||||
let rdbStore = await relationalStore.getRdbStore(context, STORE_CONFIG);
|
||||
expect(rdbStore === null).assertFalse();
|
||||
|
||||
const CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY AUTOINCREMENT, " +
|
||||
"name TEXT, age INTEGER, salary REAL, blobType BLOB)";
|
||||
await rdbStore.executeSql(CREATE_TABLE_SQL);
|
||||
|
||||
await rdbStore.insert('test', valueBucket);
|
||||
await rdbStore.insert('test', valueBucket);
|
||||
|
||||
rdbStore.backup(STORE_CONFIG2.name)
|
||||
await relationalStore.deleteRdbStore(context, STORE_CONFIG);
|
||||
|
||||
} catch (err) {
|
||||
console.error(TAG, `init database failed, errCode:${err.code}, message:${err.message}`);
|
||||
expect().assertFail();
|
||||
}
|
||||
})
|
||||
|
||||
beforeEach(async function () {
|
||||
store = await relationalStore.getRdbStore(context, STORE_CONFIG2);
|
||||
expect(store === null).assertFalse();
|
||||
console.info(TAG + 'beforeEach');
|
||||
})
|
||||
|
||||
afterEach(async function () {
|
||||
console.info(TAG + 'afterEach')
|
||||
})
|
||||
|
||||
afterAll(async function () {
|
||||
console.info(TAG + 'afterAll');
|
||||
await relationalStore.deleteRdbStore(context, STORE_CONFIG);
|
||||
await relationalStore.deleteRdbStore(context, STORE_CONFIG1);
|
||||
await relationalStore.deleteRdbStore(context, STORE_CONFIG2);
|
||||
})
|
||||
|
||||
console.info(TAG + "*************JS Test Begin*************");
|
||||
|
||||
/**
|
||||
* @tc.name open read-only database if the database is not exist
|
||||
* @tc.number readOnlyTest0001
|
||||
* @tc.desc 1. set isReadOnly as true
|
||||
* 2. open read-only database
|
||||
* @tc.size MediumTest
|
||||
* @tc.type Function
|
||||
* @tc.level Level 2
|
||||
*/
|
||||
it('readOnlyTest0001', 0, async function () {
|
||||
console.info(TAG + "************* readOnlyTest0001 start *************");
|
||||
try {
|
||||
await relationalStore.getRdbStore(context, STORE_CONFIG1);
|
||||
expect().assertFail();
|
||||
} catch (err) {
|
||||
console.error(TAG, `open read-only database failed, errCode:${err.code}, message:${err.message}`);
|
||||
expect(err.code == 14800030).assertTrue();
|
||||
}
|
||||
console.log(TAG + "************* readOnlyTest0001 end *************");
|
||||
})
|
||||
|
||||
/**
|
||||
* @tc.name insert data into read-only database
|
||||
* @tc.number readOnlyTest0002
|
||||
* @tc.desc insert data
|
||||
* @tc.size MediumTest
|
||||
* @tc.type Function
|
||||
* @tc.level Level 2
|
||||
*/
|
||||
it('readOnlyTest0002', 0, async function () {
|
||||
console.info(TAG + "************* readOnlyTest0002 start *************");
|
||||
try {
|
||||
await store.insert('test', valueBucket);
|
||||
expect().assertFail();
|
||||
} catch (err) {
|
||||
console.error(TAG, `insert failed, errCode:${err.code}, message:${err.message}`);
|
||||
expect(err.code == 14800015).assertTrue();
|
||||
}
|
||||
console.info(TAG + "************* readOnlyTest0002 end *************");
|
||||
})
|
||||
|
||||
/**
|
||||
* @tc.name update data in read-only database
|
||||
* @tc.number readOnlyTest0003
|
||||
* @tc.desc update data
|
||||
* @tc.size MediumTest
|
||||
* @tc.type Function
|
||||
* @tc.level Level 2
|
||||
*/
|
||||
it('readOnlyTest0003', 0, async function () {
|
||||
console.info(TAG + "************* readOnlyTest0003 start *************");
|
||||
try {
|
||||
let predicates = new relationalStore.RdbPredicates('test')
|
||||
predicates.equalTo('id', 1)
|
||||
await store.update(valueBucket, predicates);
|
||||
expect().assertFail();
|
||||
} catch (err) {
|
||||
console.error(TAG, `update failed, errCode:${err.code}, message:${err.message}`);
|
||||
expect(err.code == 14800015).assertTrue();
|
||||
}
|
||||
console.info(TAG + "************* readOnlyTest0003 end *************");
|
||||
})
|
||||
|
||||
/**
|
||||
* @tc.name delete data from read-only database
|
||||
* @tc.number readOnlyTest0004
|
||||
* @tc.desc delete data
|
||||
* @tc.size MediumTest
|
||||
* @tc.type Function
|
||||
* @tc.level Level 2
|
||||
*/
|
||||
it('readOnlyTest0004', 0, async function () {
|
||||
console.info(TAG + "************* readOnlyTest0004 start *************");
|
||||
try {
|
||||
let predicates = new relationalStore.RdbPredicates('test')
|
||||
await store.delete(predicates);
|
||||
expect().assertFail();
|
||||
} catch (err) {
|
||||
console.error(TAG, `delete failed, errCode:${err.code}, message:${err.message}`);
|
||||
expect(err.code == 14800015).assertTrue();
|
||||
}
|
||||
console.info(TAG + "************* readOnlyTest0004 end *************");
|
||||
})
|
||||
|
||||
/**
|
||||
* @tc.name execute transaction for read-only database
|
||||
* @tc.number readOnlyTest0005
|
||||
* @tc.desc begin transaction
|
||||
* @tc.size MediumTest
|
||||
* @tc.type Function
|
||||
* @tc.level Level 2
|
||||
*/
|
||||
it('readOnlyTest0005', 0, async function () {
|
||||
console.info(TAG + "************* readOnlyTest0005 start *************");
|
||||
try {
|
||||
store.beginTransaction();
|
||||
expect().assertFail();
|
||||
} catch (err) {
|
||||
console.error(TAG, `begin transaction failed, errCode:${err.code}, message:${err.message}`);
|
||||
expect(err.code == 14800015).assertTrue();
|
||||
}
|
||||
console.info(TAG + "************* readOnlyTest0005 end *************");
|
||||
})
|
||||
|
||||
/**
|
||||
* @tc.name get user_version from read-only database
|
||||
* @tc.number readOnlyTest0006
|
||||
* @tc.desc get user_version
|
||||
* @tc.size MediumTest
|
||||
* @tc.type Function
|
||||
* @tc.level Level 2
|
||||
*/
|
||||
it('readOnlyTest0006', 0, async function () {
|
||||
console.info(TAG + "************* readOnlyTest0006 start *************");
|
||||
try {
|
||||
expect(store.version === 0).assertTrue();
|
||||
let resultSet = await store.querySql('PRAGMA user_version');
|
||||
resultSet.goToFirstRow();
|
||||
expect(resultSet.getValue(0) === 0).assertTrue();
|
||||
} catch (err) {
|
||||
console.error(TAG, `restore failed, errCode:${err.code}, message:${err.message}`);
|
||||
expect().assertFail();
|
||||
}
|
||||
console.info(TAG + "************* readOnlyTest0006 end *************");
|
||||
})
|
||||
|
||||
/**
|
||||
* @tc.name query data from read-only database
|
||||
* @tc.number readOnlyTest0007
|
||||
* @tc.desc query data
|
||||
* @tc.size MediumTest
|
||||
* @tc.type Function
|
||||
* @tc.level Level 2
|
||||
*/
|
||||
it('readOnlyTest0007', 0, async function () {
|
||||
console.info(TAG + "************* readOnlyTest0007 start *************");
|
||||
try {
|
||||
let predicates = await new relationalStore.RdbPredicates('test')
|
||||
let resultSet = await store.query(predicates);
|
||||
expect(resultSet.rowCount == 2).assertTrue();
|
||||
} catch (err) {
|
||||
console.error(TAG, `query failed, errCode:${err.code}, message:${err.message}`);
|
||||
expect().assertFail();
|
||||
}
|
||||
console.info(TAG + "************* readOnlyTest0007 end *************");
|
||||
})
|
||||
|
||||
/**
|
||||
* @tc.name set user_version to read-only database
|
||||
* @tc.number readOnlyTest0008
|
||||
* @tc.desc test execute
|
||||
* @tc.size MediumTest
|
||||
* @tc.type Function
|
||||
* @tc.level Level 2
|
||||
*/
|
||||
it('readOnlyTest0008', 0, async function () {
|
||||
console.info(TAG + "************* readOnlyTest0008 start *************");
|
||||
try {
|
||||
expect(store.version === 0).assertTrue();
|
||||
await store.execute('PRAGMA user_version=5');
|
||||
expect().assertFail();
|
||||
} catch (err) {
|
||||
console.error(TAG, `get user_version failed, errCode:${err.code}, message:${err.message}`);
|
||||
expect(err.code == 14800015).assertTrue();
|
||||
}
|
||||
console.info(TAG + "************* readOnlyTest0008 end *************");
|
||||
})
|
||||
|
||||
/**
|
||||
* @tc.name set user_version to read-only database
|
||||
* @tc.number readOnlyTest009
|
||||
* @tc.desc test executeSql
|
||||
* @tc.size MediumTest
|
||||
* @tc.type Function
|
||||
* @tc.level Level 2
|
||||
*/
|
||||
it('readOnlyTest009', 0, async function () {
|
||||
console.info(TAG + "************* readOnlyTest009 start *************");
|
||||
try {
|
||||
expect(store.version === 0).assertTrue();
|
||||
await store.executeSql('PRAGMA user_version');
|
||||
expect().assertFail();
|
||||
} catch (err) {
|
||||
console.error(TAG, `set user_version failed, errCode:${err.code}, message:${err.message}`);
|
||||
expect(err.code == 14800015).assertTrue();
|
||||
}
|
||||
console.info(TAG + "************* readOnlyTest009 end *************");
|
||||
})
|
||||
|
||||
/**
|
||||
* @tc.name set user_version to read-only database
|
||||
* @tc.number readOnlyTest0010
|
||||
* @tc.desc set user_version by store
|
||||
* @tc.size MediumTest
|
||||
* @tc.type Function
|
||||
* @tc.level Level 2
|
||||
*/
|
||||
it('readOnlyTest010', 0, async function () {
|
||||
console.info(TAG + "************* readOnlyTest0010 start *************");
|
||||
try {
|
||||
store.version = 5;
|
||||
expect().assertFail();
|
||||
} catch (err) {
|
||||
console.error(TAG, `set user_version failed, errCode:${err.code}, message:${err.message}`);
|
||||
expect(err.code == 14800015).assertTrue();
|
||||
}
|
||||
console.info(TAG + "************* readOnlyTest0010 end *************");
|
||||
})
|
||||
|
||||
console.info(TAG + "*************Unit Test End*************");
|
||||
})
|
||||
|
@ -88,6 +88,7 @@ ohos_unittest("NativeRdbTest") {
|
||||
"unittest/rdb_predicates_join_b_test.cpp",
|
||||
"unittest/rdb_predicates_join_test.cpp",
|
||||
"unittest/rdb_predicates_test.cpp",
|
||||
"unittest/rdb_read_only_test.cpp",
|
||||
"unittest/rdb_sqlite_shared_result_set_test.cpp",
|
||||
"unittest/rdb_step_result_get_row_test.cpp",
|
||||
"unittest/rdb_step_result_set_test.cpp",
|
||||
|
505
test/native/rdb/unittest/rdb_read_only_test.cpp
Normal file
505
test/native/rdb/unittest/rdb_read_only_test.cpp
Normal file
@ -0,0 +1,505 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "common.h"
|
||||
#include "rdb_errno.h"
|
||||
#include "rdb_helper.h"
|
||||
#include "rdb_open_callback.h"
|
||||
|
||||
using namespace testing::ext;
|
||||
using namespace OHOS::NativeRdb;
|
||||
|
||||
class RdbReadOnlyTest : public testing::Test {
|
||||
public:
|
||||
static void SetUpTestCase(void);
|
||||
static void TearDownTestCase(void);
|
||||
void SetUp();
|
||||
void TearDown();
|
||||
|
||||
static const std::string READONLY_DATABASE_NAME;
|
||||
static const std::string READONLY_DATABASE_BAK_NAME;
|
||||
static const std::string DATABASE_NAME;
|
||||
static std::shared_ptr<RdbStore> readOnlyStore;
|
||||
};
|
||||
|
||||
const std::string RdbReadOnlyTest::DATABASE_NAME = RDB_TEST_PATH + "database.db";
|
||||
const std::string RdbReadOnlyTest::READONLY_DATABASE_NAME = RDB_TEST_PATH + "readOnly.db";
|
||||
const std::string RdbReadOnlyTest::READONLY_DATABASE_BAK_NAME = RDB_TEST_PATH + "readOnlyBak.db";
|
||||
std::shared_ptr<RdbStore> RdbReadOnlyTest::readOnlyStore = nullptr;
|
||||
|
||||
class ReadOnlyTestOpenCallback : public RdbOpenCallback {
|
||||
public:
|
||||
int OnCreate(RdbStore &store) override;
|
||||
int OnUpgrade(RdbStore &store, int oldVersion, int newVersion) override;
|
||||
static const std::string CREATE_TABLE_TEST;
|
||||
};
|
||||
|
||||
const std::string ReadOnlyTestOpenCallback::CREATE_TABLE_TEST = "CREATE TABLE IF NOT EXISTS test "
|
||||
"(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER, salary REAL, blobType BLOB)";
|
||||
|
||||
int ReadOnlyTestOpenCallback::OnCreate(RdbStore &store)
|
||||
{
|
||||
return store.ExecuteSql(CREATE_TABLE_TEST);
|
||||
}
|
||||
|
||||
int ReadOnlyTestOpenCallback::OnUpgrade(RdbStore &store, int oldVersion, int newVersion)
|
||||
{
|
||||
return E_OK;
|
||||
}
|
||||
|
||||
void RdbReadOnlyTest::SetUpTestCase(void)
|
||||
{
|
||||
int errCode = E_ERROR;
|
||||
RdbHelper::DeleteRdbStore(READONLY_DATABASE_NAME);
|
||||
RdbStoreConfig config(READONLY_DATABASE_NAME);
|
||||
config.SetBundleName("com.example.readOnly.rdb");
|
||||
ReadOnlyTestOpenCallback helper;
|
||||
// user_version is 1
|
||||
auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
|
||||
EXPECT_NE(nullptr, store);
|
||||
EXPECT_EQ(E_OK, errCode);
|
||||
|
||||
int64_t id;
|
||||
ValuesBucket values;
|
||||
values.PutString("name", "zhangSan");
|
||||
int ret = store->Insert(id, "test", values);
|
||||
EXPECT_EQ(E_OK, ret);
|
||||
// id is 1
|
||||
EXPECT_EQ(1, id);
|
||||
|
||||
RdbHelper::ClearCache();
|
||||
|
||||
RdbStoreConfig config1(READONLY_DATABASE_NAME);
|
||||
config1.SetBundleName("com.example.readOnly.rdb");
|
||||
config1.SetReadOnly(true);
|
||||
ReadOnlyTestOpenCallback helper1;
|
||||
// user_version is 1
|
||||
readOnlyStore = RdbHelper::GetRdbStore(config1, 1, helper1, errCode);
|
||||
EXPECT_NE(nullptr, readOnlyStore);
|
||||
EXPECT_EQ(E_OK, errCode);
|
||||
}
|
||||
|
||||
void RdbReadOnlyTest::TearDownTestCase(void)
|
||||
{
|
||||
readOnlyStore = nullptr;
|
||||
EXPECT_EQ(E_OK, RdbHelper::DeleteRdbStore(RdbReadOnlyTest::DATABASE_NAME));
|
||||
EXPECT_EQ(E_OK, RdbHelper::DeleteRdbStore(RdbReadOnlyTest::READONLY_DATABASE_NAME));
|
||||
EXPECT_EQ(E_OK, RdbHelper::DeleteRdbStore(RdbReadOnlyTest::READONLY_DATABASE_BAK_NAME));
|
||||
}
|
||||
|
||||
void RdbReadOnlyTest::SetUp()
|
||||
{
|
||||
}
|
||||
|
||||
void RdbReadOnlyTest::TearDown()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0001, open read-only database if the database is not exist
|
||||
* @tc.desc: 1. set isReadOnly as true
|
||||
* 2. open read-only database
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0001, TestSize.Level1)
|
||||
{
|
||||
int errCode = E_ERROR;
|
||||
RdbStoreConfig config(RdbReadOnlyTest::DATABASE_NAME);
|
||||
config.SetReadOnly(true);
|
||||
ReadOnlyTestOpenCallback helper;
|
||||
// create read-only database, user_version is 1
|
||||
auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
|
||||
EXPECT_EQ(nullptr, store);
|
||||
EXPECT_EQ(E_SQLITE_CANTOPEN, errCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0002, insert data
|
||||
* @tc.desc: insert data into read-only database
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0002, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
|
||||
|
||||
int64_t id;
|
||||
ValuesBucket values;
|
||||
values.PutString("name", "liSi");
|
||||
int ret = store->Insert(id, "test", values);
|
||||
EXPECT_EQ(E_DATABASE_BUSY, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0003, update data
|
||||
* @tc.desc: update data in read-only database
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0003, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
|
||||
|
||||
int changedRows;
|
||||
ValuesBucket values;
|
||||
// salary is 300.5
|
||||
values.PutDouble("salary", 300.5);
|
||||
auto ret = store->Update(changedRows, "test", values);
|
||||
EXPECT_EQ(E_DATABASE_BUSY, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0004, delete data
|
||||
* @tc.desc: delete data from read-only database
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0004, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
|
||||
|
||||
int deletedRows;
|
||||
auto ret = store->Delete(deletedRows, "test", "id = 1");
|
||||
EXPECT_EQ(E_DATABASE_BUSY, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0005
|
||||
* @tc.desc: execute transaction
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0005, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
|
||||
|
||||
auto ret = store->BeginTransaction();
|
||||
EXPECT_EQ(E_DATABASE_BUSY, ret);
|
||||
|
||||
ret = store->Commit();
|
||||
EXPECT_EQ(E_OK, ret);
|
||||
|
||||
ret = store->RollBack();
|
||||
EXPECT_EQ(E_NO_TRANSACTION_IN_SESSION, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0006
|
||||
* @tc.desc: batch insert data
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0006, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
|
||||
|
||||
int64_t number = 0;
|
||||
std::vector<ValuesBucket> valuesBuckets;
|
||||
ValuesBucket values;
|
||||
values.PutString("name", "zhangSan");
|
||||
valuesBuckets.push_back(std::move(values));
|
||||
int error = store->BatchInsert(number, "test", valuesBuckets);
|
||||
EXPECT_EQ(E_DATABASE_BUSY, error);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0007
|
||||
* @tc.desc: get user_version by querySql
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0007, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
|
||||
|
||||
auto resultSet = store->QuerySql("PRAGMA user_version");
|
||||
EXPECT_NE(nullptr, resultSet);
|
||||
EXPECT_EQ(E_OK, resultSet->GoToFirstRow());
|
||||
|
||||
int value = 0;
|
||||
// column index is 0
|
||||
EXPECT_EQ(E_OK, resultSet->GetInt(0, value));
|
||||
EXPECT_EQ(1, value);
|
||||
|
||||
EXPECT_EQ(E_OK, resultSet->Close());
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0008
|
||||
* @tc.desc: get user_version by execute
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0008, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
|
||||
|
||||
auto [ret, object] = store->Execute("PRAGMA user_version");
|
||||
EXPECT_EQ(E_DATABASE_BUSY, ret);
|
||||
|
||||
std::tie(ret, object) = store->Execute("PRAGMA user_version=2");
|
||||
EXPECT_EQ(E_DATABASE_BUSY, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0009
|
||||
* @tc.desc: query data
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0009, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
|
||||
|
||||
auto resultSet = store->QuerySql("SELECT * FROM test");
|
||||
|
||||
int count = 0;
|
||||
EXPECT_EQ(E_OK, resultSet->GetRowCount(count));
|
||||
// count is 1
|
||||
EXPECT_EQ(1, count);
|
||||
|
||||
EXPECT_EQ(E_OK, resultSet->Close());
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0010
|
||||
* @tc.desc: get user_version by executeSql
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0010, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
|
||||
|
||||
auto ret = store->ExecuteSql("PRAGMA user_version");
|
||||
EXPECT_EQ(E_DATABASE_BUSY, ret);
|
||||
|
||||
ret = store->ExecuteSql("SELECT * FROM test");
|
||||
EXPECT_EQ(E_OK, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0011
|
||||
* @tc.desc: replace data
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0011, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
|
||||
|
||||
int64_t id;
|
||||
ValuesBucket values;
|
||||
values.PutString("name", "zhangSan");
|
||||
int ret = store->Replace(id, "test", values);
|
||||
EXPECT_EQ(E_DATABASE_BUSY, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0012
|
||||
* @tc.desc: test ExecuteAndGetLong
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0012, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
|
||||
|
||||
int64_t count;
|
||||
int ret = store->ExecuteAndGetLong(count, "SELECT COUNT(*) FROM test");
|
||||
EXPECT_EQ(E_OK, ret);
|
||||
|
||||
ret = store->ExecuteAndGetLong(count, "PRAGMA user_version");
|
||||
EXPECT_EQ(E_DATABASE_BUSY, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0013
|
||||
* @tc.desc: test ExecuteAndGetString
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0013, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
|
||||
|
||||
std::string count;
|
||||
int ret = store->ExecuteAndGetString(count, "SELECT COUNT(*) FROM test");
|
||||
EXPECT_EQ(E_OK, ret);
|
||||
|
||||
ret = store->ExecuteAndGetString(count, "PRAGMA user_version");
|
||||
EXPECT_EQ(E_DATABASE_BUSY, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0014
|
||||
* @tc.desc: test ExecuteForLastInsertedRowId
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0014, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
|
||||
|
||||
int64_t outValue;
|
||||
int ret = store->ExecuteForLastInsertedRowId(outValue, "", {});
|
||||
EXPECT_EQ(E_DATABASE_BUSY, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0015
|
||||
* @tc.desc: test ExecuteForChangedRowCount
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0015, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
|
||||
|
||||
int64_t outValue;
|
||||
int ret = store->ExecuteForChangedRowCount(outValue, "", {});
|
||||
EXPECT_EQ(E_DATABASE_BUSY, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0016
|
||||
* @tc.desc: get user_version by GetVersion
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0016, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
|
||||
|
||||
int version = -1;
|
||||
auto ret = store->GetVersion(version);
|
||||
EXPECT_EQ(E_OK, ret);
|
||||
// version is 1
|
||||
EXPECT_EQ(1, version);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0017
|
||||
* @tc.desc: set user_version by SetVersion
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0017, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
|
||||
|
||||
int version = 2;
|
||||
auto ret = store->SetVersion(version);
|
||||
EXPECT_EQ(E_DATABASE_BUSY, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0018
|
||||
* @tc.desc: test vector db
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0018, TestSize.Level1)
|
||||
{
|
||||
int errCode = E_ERROR;
|
||||
RdbStoreConfig config(RdbReadOnlyTest::READONLY_DATABASE_NAME);
|
||||
config.SetBundleName("com.example.readOnly.rdb");
|
||||
config.SetReadOnly(true);
|
||||
config.SetIsVector(true);
|
||||
ReadOnlyTestOpenCallback helper;
|
||||
// user_version is 1
|
||||
auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
|
||||
EXPECT_NE(nullptr, store);
|
||||
|
||||
auto [ret, id] = store->BeginTrans();
|
||||
EXPECT_EQ(E_NOT_SUPPORT, ret);
|
||||
|
||||
// id is 1
|
||||
ret = store->Commit(1);
|
||||
EXPECT_EQ(E_NOT_SUPPORT, ret);
|
||||
|
||||
// id is 1
|
||||
ret = store->RollBack(1);
|
||||
EXPECT_EQ(E_NOT_SUPPORT, ret);
|
||||
|
||||
ValueObject obj;
|
||||
// id is 1
|
||||
std::tie(ret, obj) = store->Execute("PRAGMA user_version", {}, 1);
|
||||
EXPECT_EQ(E_DATABASE_BUSY, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0019
|
||||
* @tc.desc: test encrypt db
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0019, TestSize.Level1)
|
||||
{
|
||||
int errCode = E_ERROR;
|
||||
RdbStoreConfig config(RdbReadOnlyTest::DATABASE_NAME);
|
||||
config.SetBundleName("com.example.encrypt.rdb");
|
||||
config.SetEncryptStatus(true);
|
||||
ReadOnlyTestOpenCallback helper;
|
||||
// user_version is 1
|
||||
auto store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
|
||||
EXPECT_NE(nullptr, store);
|
||||
|
||||
RdbHelper::ClearCache();
|
||||
|
||||
RdbStoreConfig config1(RdbReadOnlyTest::DATABASE_NAME);
|
||||
config1.SetBundleName("com.example.encrypt.rdb");
|
||||
config1.SetReadOnly(true);
|
||||
config1.SetEncryptStatus(true);
|
||||
// user_version is 1
|
||||
store = RdbHelper::GetRdbStore(config, 1, helper, errCode);
|
||||
EXPECT_NE(nullptr, store);
|
||||
|
||||
EXPECT_EQ(E_OK, RdbHelper::DeleteRdbStore(RdbReadOnlyTest::DATABASE_NAME));
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0020
|
||||
* @tc.desc: test attach and detach
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0020, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
|
||||
|
||||
RdbStoreConfig config(RdbReadOnlyTest::READONLY_DATABASE_NAME);
|
||||
auto [ret, size] = store->Attach(config, RdbReadOnlyTest::DATABASE_NAME);
|
||||
EXPECT_EQ(E_NOT_SUPPORT, ret);
|
||||
|
||||
std::tie(ret, size) = store->Detach(RdbReadOnlyTest::DATABASE_NAME);
|
||||
EXPECT_EQ(E_NOT_SUPPORT, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0021
|
||||
* @tc.desc: test SetDistributedTables
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0021, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
|
||||
|
||||
AbsRdbPredicates predicates("test");
|
||||
OHOS::DistributedRdb::DistributedConfig config;
|
||||
// type is 0
|
||||
auto ret = store->SetDistributedTables({}, 0, config);
|
||||
EXPECT_EQ(E_NOT_SUPPORT, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @tc.name: RdbStore_ReadOnly_0022
|
||||
* @tc.desc: test CleanDirtyData
|
||||
* @tc.type: FUNC
|
||||
*/
|
||||
HWTEST_F(RdbReadOnlyTest, RdbStore_ReadOnly_0022, TestSize.Level1)
|
||||
{
|
||||
std::shared_ptr<RdbStore> &store = RdbReadOnlyTest::readOnlyStore;
|
||||
|
||||
uint64_t cursor = 1;
|
||||
auto ret = store->CleanDirtyData("test", cursor);
|
||||
EXPECT_EQ(E_DATABASE_BUSY, ret);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user