Skip to content

Commit

Permalink
impr: text - index function
Browse files Browse the repository at this point in the history
  • Loading branch information
nalgeon committed Jun 4, 2023
1 parent 79ba775 commit 6fe0990
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 0 deletions.
65 changes: 65 additions & 0 deletions src/sqlite3-text.c
Expand Up @@ -14,6 +14,8 @@

SQLITE_EXTENSION_INIT1

#pragma region Substrings

// Extracts a substring starting at the `start` position (1-based).
// text_substring(str, start)
static void sqlite3_substring2(sqlite3_context* context, int argc, sqlite3_value** argv) {
Expand Down Expand Up @@ -285,6 +287,62 @@ static void sqlite3_reverse(sqlite3_context* context, int argc, sqlite3_value**
rstring.free(s_res);
}

#pragma endregion

#pragma region Search and match

// Returns the first index of the substring in the original string.
// text_index(str, other)
static void sqlite3_index(sqlite3_context* context, int argc, sqlite3_value** argv) {
assert(argc == 2);

const char* src = (char*)sqlite3_value_text(argv[0]);
if (src == NULL) {
sqlite3_result_null(context);
return;
}

const char* other = (char*)sqlite3_value_text(argv[1]);
if (other == NULL) {
sqlite3_result_null(context);
return;
}

RuneString s_src = rstring.from_cstring(src);
RuneString s_other = rstring.from_cstring(other);
int idx = rstring.index(s_src, s_other);
sqlite3_result_int64(context, idx + 1);
rstring.free(s_src);
rstring.free(s_other);
}

// Returns the last index of the substring in the original string.
// text_last_index(str, other)
static void sqlite3_last_index(sqlite3_context* context, int argc, sqlite3_value** argv) {
assert(argc == 2);

const char* src = (char*)sqlite3_value_text(argv[0]);
if (src == NULL) {
sqlite3_result_null(context);
return;
}

const char* other = (char*)sqlite3_value_text(argv[1]);
if (other == NULL) {
sqlite3_result_null(context);
return;
}

RuneString s_src = rstring.from_cstring(src);
RuneString s_other = rstring.from_cstring(other);
int idx = rstring.last_index(s_src, s_other);
sqlite3_result_int64(context, idx + 1);
rstring.free(s_src);
rstring.free(s_other);
}

#pragma endregion

// substring
// utf8 text_slice(str, start [,end])
// utf8 text_substring(str, start [,length])
Expand Down Expand Up @@ -327,12 +385,19 @@ __declspec(dllexport)
(void)errmsg_ptr;
SQLITE_EXTENSION_INIT2(api);
static const int flags = SQLITE_UTF8 | SQLITE_INNOCUOUS | SQLITE_DETERMINISTIC;

// substrings
sqlite3_create_function(db, "text_substring", 2, flags, 0, sqlite3_substring2, 0, 0);
sqlite3_create_function(db, "text_substring", 3, flags, 0, sqlite3_substring3, 0, 0);
sqlite3_create_function(db, "text_slice", 2, flags, 0, sqlite3_slice2, 0, 0);
sqlite3_create_function(db, "text_slice", 3, flags, 0, sqlite3_slice3, 0, 0);
sqlite3_create_function(db, "text_left", 2, flags, 0, sqlite3_left, 0, 0);
sqlite3_create_function(db, "text_right", 2, flags, 0, sqlite3_right, 0, 0);

// search and match
sqlite3_create_function(db, "text_index", 2, flags, 0, sqlite3_index, 0, 0);
sqlite3_create_function(db, "text_last_index", 2, flags, 0, sqlite3_last_index, 0, 0);

sqlite3_create_function(db, "text_reverse", 1, flags, 0, sqlite3_reverse, 0, 0);
sqlite3_create_function(db, "reverse", 1, flags, 0, sqlite3_reverse, 0, 0);
sqlite3_create_function(db, "text_split", 3, flags, 0, sqlite3_split, 0, 0);
Expand Down
16 changes: 16 additions & 0 deletions test/text.sql
Expand Up @@ -134,6 +134,22 @@ select '4_10', text_right('hello world', -10) = 'd';
select '4_11', text_right('hello world', -11) = '';
select '4_12', text_right('hello world', -15) = '';

-- Index
select '4_01', text_index(null, 'ello') is null;
select '4_02', text_index('hello yellow', null) is null;
select '4_03', text_index('hello yellow', 'hello') = 1;
select '4_04', text_index('hello yellow', 'yellow') = 7;
select '4_05', text_index('hello yellow', 'ello') = 2;
select '4_06', text_index('hello yellow', 'x') = 0;

-- Last index
select '5_01', text_last_index(null, 'ello') is null;
select '5_02', text_last_index('hello yellow', null) is null;
select '5_03', text_last_index('hello yellow', 'hello') = 1;
select '5_04', text_last_index('hello yellow', 'yellow') = 7;
select '5_05', text_last_index('hello yellow', 'ello') = 8;
select '5_06', text_last_index('hello yellow', 'x') = 0;

-- Reverse string
select 'x_01', text_reverse(null) is NULL;
select 'x_02', text_reverse('hello') = 'olleh';
Expand Down

0 comments on commit 6fe0990

Please sign in to comment.