-
Notifications
You must be signed in to change notification settings - Fork 91
/
Copy pathmain.cc
148 lines (132 loc) · 4.92 KB
/
main.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include <sqlite3.h>
#include <chrono>
#include <iostream>
#include <sstream>
#ifdef _WIN32
#include <direct.h>
#define GetCurrentDir _getcwd
#else
#include <unistd.h>
#define GetCurrentDir getcwd
#endif
using namespace std;
using Clock = std::chrono::system_clock;
using ms = std::chrono::duration<double, std::milli>;
// https://www.tutorialspoint.com/find-out-the-current-working-directory-in-c-cplusplus
string get_current_dir() {
char buff[FILENAME_MAX]; // create string buffer to hold path
GetCurrentDir(buff, FILENAME_MAX);
string current_working_dir(buff);
return current_working_dir;
}
// Create a callback function
int callback(void *NotUsed, int argc, char **argv, char **azColName) {
// int argc: holds the number of results
// (array) azColName: holds each column returned
// (array) argv: holds each value
for (int i = 0; i < argc; i++) {
// Show column name, value, and newline
cout << azColName[i] << ": " << argv[i] << endl;
}
if (argc > 0) {
cout << endl;
}
// Return successful
return 0;
}
void handle_rc(sqlite3 *db, int rc) {
if (rc != SQLITE_OK) {
cout << "sqlite3 rc: " << rc << ", error: " << sqlite3_errmsg(db) << endl;
exit(rc);
}
}
int main() {
// Pointer to SQLite connection
sqlite3 *db;
// Save any error messages
char *zErrMsg = 0;
// Save the connection result
int rc = sqlite3_open(":memory:", &db);
handle_rc(db, rc);
auto before = Clock::now();
// load simple
rc = sqlite3_enable_load_extension(db, 1);
handle_rc(db, rc);
rc = sqlite3_load_extension(db, "libsimple", NULL, NULL);
handle_rc(db, rc);
ms load_extension = Clock::now() - before;
std::cout << "It took " << load_extension.count() << "ms to load extension" << std::endl;
// warm-up
before = Clock::now();
string sql = "select simple_query('pinyin')";
rc = sqlite3_exec(db, sql.c_str(), callback, 0, &zErrMsg);
handle_rc(db, rc);
ms pinyin = Clock::now() - before;
std::cout << "It took " << pinyin.count() << "ms to init pinyin" << std::endl;
before = Clock::now();
sql = "select jieba_query('结巴')";
rc = sqlite3_exec(db, sql.c_str(), callback, 0, &zErrMsg);
handle_rc(db, rc);
ms warm_up = Clock::now() - before;
std::cout << "It took " << warm_up.count() << "ms to init jieba" << std::endl;
before = Clock::now();
// create fts table
sql = "CREATE VIRTUAL TABLE t1 USING fts5(x, tokenize = 'simple')";
rc = sqlite3_exec(db, sql.c_str(), callback, 0, &zErrMsg);
handle_rc(db, rc);
// insert some data
sql = R"V0G0N(
insert into t1(x) values ('周杰伦 Jay Chou:最美的不是下雨天,是曾与你躲过雨的屋檐'),
('I love China! 我爱中国!'),
('@English &special _characters."''bacon-&and''-eggs%')
)V0G0N";
rc = sqlite3_exec(db, sql.c_str(), callback, 0, &zErrMsg);
handle_rc(db, rc);
// case 1: match pinyin
sql = "select simple_highlight(t1, 0, '[', ']') as matched_pinyin from t1 where x match simple_query('zhoujiel')";
rc = sqlite3_exec(db, sql.c_str(), callback, 0, &zErrMsg);
handle_rc(db, rc);
// case 2: match special chars
sql =
"select simple_highlight(t1, 0, '[', ']') as matched_no_single_quote_special_chars from t1 where x match "
"simple_query('@\"._-&%')";
rc = sqlite3_exec(db, sql.c_str(), callback, 0, &zErrMsg);
handle_rc(db, rc);
// case 3: single quote, will match!
sql =
"select simple_highlight(t1, 0, '[', ']') as matched_simple_query_special_chars from t1 where x match "
"simple_query('@\"._''-&%')";
rc = sqlite3_exec(db, sql.c_str(), callback, 0, &zErrMsg);
handle_rc(db, rc);
#ifdef USE_JIEBA
// set dict path manually
string dict_path = get_current_dir() + "/dict";
sql = "select jieba_dict('" + dict_path + "')";
rc = sqlite3_exec(db, sql.c_str(), callback, 0, &zErrMsg);
handle_rc(db, rc);
// case 4: jieba, no match
sql = "select simple_highlight(t1, 0, '[', ']') as no_matched_jieba from t1 where x match jieba_query('国中')";
rc = sqlite3_exec(db, sql.c_str(), callback, 0, &zErrMsg);
handle_rc(db, rc);
// case 5: jieba, match
sql = "select simple_highlight(t1, 0, '[', ']') as matched_jieba from t1 where x match jieba_query('中国')";
rc = sqlite3_exec(db, sql.c_str(), callback, 0, &zErrMsg);
handle_rc(db, rc);
#endif
// case 6: use highlight_pos
sql =
"select simple_highlight_pos(t1, 0) as matched_simple_query_special_chars from t1 where x match "
"simple_query('shi')";
rc = sqlite3_exec(db, sql.c_str(), callback, 0, &zErrMsg);
handle_rc(db, rc);
sql =
"select simple_highlight_pos(t1, 0) as matched_simple_query_special_chars from t1 where x match "
"simple_query('special')";
rc = sqlite3_exec(db, sql.c_str(), callback, 0, &zErrMsg);
handle_rc(db, rc);
ms last_query = Clock::now() - before;
std::cout << "It took " << last_query.count() << "ms for all query" << std::endl;
// Close the connection
sqlite3_close(db);
return (0);
}