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 #define LOG_TAG "ICUCollect"
16 #include "icu_collect.h"
17
18 #include <sqlite3sym.h>
19 #include <unicode/ucol.h>
20
21 #include "logger.h"
22 #include "rdb_errno.h"
23 #include "rdb_visibility.h"
24 #include "sqlite3.h"
25
26 API_EXPORT int32_t ConfigICULocal(sqlite3 *, const std::string &str) asm("ConfigICULocal");
ConfigICULocal(sqlite3 * handle,const std::string & str)27 int32_t ConfigICULocal(sqlite3 *handle, const std::string &str)
28 {
29 return OHOS::NativeRdb::ICUCollect::Local(handle, str);
30 }
31
32 namespace OHOS::NativeRdb {
33 using namespace OHOS::Rdb;
34
Collate8Compare(void * p,int n1,const void * v1,int n2,const void * v2)35 int ICUCollect::Collate8Compare(void *p, int n1, const void *v1, int n2, const void *v2)
36 {
37 UCollator *coll = reinterpret_cast<UCollator *>(p);
38 UCharIterator i1;
39 UCharIterator i2;
40 UErrorCode status = U_ZERO_ERROR;
41
42 uiter_setUTF8(&i1, (const char *)v1, n1);
43 uiter_setUTF8(&i2, (const char *)v2, n2);
44
45 UCollationResult result = ucol_strcollIter(coll, &i1, &i2, &status);
46
47 if (U_FAILURE(status)) {
48 LOG_ERROR("Ucol strcoll error.");
49 }
50
51 if (result == UCOL_LESS) {
52 return -1;
53 } else if (result == UCOL_GREATER) {
54 return 1;
55 }
56 return 0;
57 }
58
LocalizedCollatorDestroy(void * collator)59 void ICUCollect::LocalizedCollatorDestroy(void *collator)
60 {
61 ucol_close(reinterpret_cast<UCollator *>(collator));
62 }
63
Local(sqlite3 * dbHandle,const std::string & str)64 int32_t ICUCollect::Local(sqlite3 *dbHandle, const std::string &str)
65 {
66 LOG_ERROR("bai:local success");
67 UErrorCode status = U_ZERO_ERROR;
68 UCollator *collator = ucol_open(str.c_str(), &status);
69 if (U_FAILURE(status)) {
70 LOG_ERROR("Can not open collator.");
71 return E_ERROR;
72 }
73 ucol_setAttribute(collator, UCOL_STRENGTH, UCOL_PRIMARY, &status);
74 if (U_FAILURE(status)) {
75 LOG_ERROR("Set attribute of collator failed.");
76 return E_ERROR;
77 }
78 int err = sqlite3_create_collation_v2(dbHandle, "LOCALES", SQLITE_UTF8, collator, ICUCollect::Collate8Compare,
79 (void (*)(void *))ICUCollect::LocalizedCollatorDestroy);
80 if (err != SQLITE_OK) {
81 LOG_ERROR("SCreate collator in sqlite3 failed.");
82 return err;
83 }
84 return E_OK;
85 }
86
87 } // namespace OHOS::NativeRdb
88