Skip to content

Commit 2fcaccb

Browse files
committed
bump sqlite-loadable=0.0.6-alpha.2, add ->> overload to regex_captures
1 parent 8bfcac5 commit 2fcaccb

File tree

12 files changed

+135
-102
lines changed

12 files changed

+135
-102
lines changed

Cargo.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ keywords = ["sqlite", "sqlite-extension"]
1010
license = "MIT/Apache-2.0"
1111

1212
[dependencies]
13-
sqlite-loadable = "0.0.5"
13+
sqlite-loadable = "0.0.6-alpha.2"
1414
regex = "1"
1515

1616
[lib]

src/captures.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use regex::{Captures, Regex};
22
use sqlite_loadable::{
33
api,
4-
table::{ConstraintOperator, IndexInfo, VTab, VTabArguments, VTabCursor},
4+
scalar::scalar_function_raw,
5+
table::{ConstraintOperator, IndexInfo, VTab, VTabArguments, VTabCursor, VTabFind},
56
BestIndexError, Result,
67
};
78
use sqlite_loadable::{prelude::*, Error};
@@ -90,6 +91,19 @@ impl<'vtab> VTab<'vtab> for RegexCapturesTable {
9091
}
9192
}
9293

94+
impl<'vtab> VTabFind<'vtab> for RegexCapturesTable {
95+
fn find_function(
96+
&mut self,
97+
argc: i32,
98+
name: &str,
99+
) -> Option<unsafe extern "C" fn(*mut sqlite3_context, i32, *mut *mut sqlite3_value)> {
100+
if name == "->>" && argc == 2 {
101+
return Some(scalar_function_raw(crate::regex_capture2));
102+
}
103+
None
104+
}
105+
}
106+
93107
#[repr(C)]
94108
pub struct RegexCapturesCursor<'vtab> {
95109
/// Base class. Must be first
@@ -122,6 +136,7 @@ impl VTabCursor for RegexCapturesCursor<'_> {
122136
.get(0)
123137
.ok_or_else(|| Error::new_message("expected 1st argument as regex"))?,
124138
)?;
139+
let r = unsafe { &*r };
125140
let contents = api::value_text_notnull(
126141
values
127142
.get(1)
@@ -132,8 +147,7 @@ impl VTabCursor for RegexCapturesCursor<'_> {
132147
for captures in r.captures_iter(contents) {
133148
res.push(captures)
134149
}
135-
self.r_clone = Some((*r).clone());
136-
Box::into_raw(r);
150+
self.r_clone = Some((r).clone());
137151
self.all_captures = Some(res);
138152
self.curr = 0;
139153
Ok(())

src/find_all.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ impl VTabCursor for RegexFindAllCursor<'_> {
127127
.get(0)
128128
.ok_or_else(|| Error::new_message("expected 1st argument as regex"))?,
129129
)?;
130+
let r = unsafe { &*r };
130131
let contents = api::value_text_notnull(
131132
values
132133
.get(1)
@@ -137,7 +138,6 @@ impl VTabCursor for RegexFindAllCursor<'_> {
137138
for m in r.find_iter(contents) {
138139
res.push((m.start(), m.end(), m.as_str().to_string()))
139140
}
140-
Box::into_raw(r);
141141
self.matches = Some(res);
142142
self.curr = 0;
143143
Ok(())

src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ mod utils;
1010
use regexset_matches::RegexSetMatchesTable;
1111
use sqlite_loadable::prelude::*;
1212
use sqlite_loadable::{
13-
define_scalar_function, define_table_function, errors::Result, FunctionFlags,
13+
define_scalar_function, define_table_function, errors::Result,
14+
table::define_table_function_with_find, FunctionFlags,
1415
};
1516

1617
use crate::{
@@ -43,7 +44,7 @@ pub fn sqlite3_regex_init(db: *mut sqlite3) -> Result<()> {
4344

4445
define_table_function::<RegexFindAllTable>(db, "regex_find_all", None)?;
4546
define_table_function::<RegexSplitTable>(db, "regex_split", None)?;
46-
define_table_function::<RegexCapturesTable>(db, "regex_captures", None)?;
47+
define_table_function_with_find::<RegexCapturesTable>(db, "regex_captures", None)?;
4748

4849
define_scalar_function(db, "regexset", -1, regexset, flags)?;
4950
define_scalar_function(db, "regexset_print", 1, regexset_print, flags)?;

src/regex.rs

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use sqlite_loadable::{api, Error, Result};
1010
// regex(pattern [, flags])
1111
pub fn regex_print(context: *mut sqlite3_context, values: &[*mut sqlite3_value]) -> Result<()> {
1212
let regex = value_regex(values.get(0).ok_or("asdf")?)?;
13+
let regex = unsafe { &mut *regex };
1314
api::result_text(context, regex.as_str())?;
14-
Box::into_raw(regex);
1515
Ok(())
1616
}
1717

@@ -28,10 +28,11 @@ pub fn regex(context: *mut sqlite3_context, values: &[*mut sqlite3_value]) -> Re
2828
/// regex_matches(regex, text)
2929
pub fn regex_matches(context: *mut sqlite3_context, values: &[*mut sqlite3_value]) -> Result<()> {
3030
let (regex, input_type) = regex_from_value_or_cache(context, values, 0)?;
31+
let regex = unsafe { &mut *regex };
3132
let content =
3233
api::value_text_notnull(values.get(1).ok_or("expected 2nd argument as contents")?)?;
3334

34-
api::result_bool(context, regex.as_ref().is_match(content));
35+
api::result_bool(context, regex.is_match(content));
3536
cleanup_regex_value_cached(context, regex, input_type);
3637
Ok(())
3738
}
@@ -56,13 +57,13 @@ pub fn regex_valid(context: *mut sqlite3_context, values: &[*mut sqlite3_value])
5657
/// regex_find(regex, contents)
5758
pub fn regex_find(context: *mut sqlite3_context, values: &[*mut sqlite3_value]) -> Result<()> {
5859
let (regex, input_type) = regex_from_value_or_cache(context, values, 0)?;
59-
60+
let regex = unsafe { &mut *regex };
6061
let arg_content = values
6162
.get(1)
6263
.ok_or_else(|| Error::new_message("expected 2nd argument as contents"))?;
6364

6465
let content = api::value_text_notnull(arg_content)?;
65-
match regex.as_ref().find(content) {
66+
match regex.find(content) {
6667
Some(m) => {
6768
api::result_text(context, m.as_str())?;
6869
}
@@ -78,7 +79,7 @@ pub fn regex_find(context: *mut sqlite3_context, values: &[*mut sqlite3_value])
7879
/// regex_find_at(regex, contents, offset)
7980
pub fn regex_find_at(context: *mut sqlite3_context, values: &[*mut sqlite3_value]) -> Result<()> {
8081
let (regex, input_type) = regex_from_value_or_cache(context, values, 0)?;
81-
82+
let regex = unsafe { &mut *regex };
8283
let arg_content = values
8384
.get(1)
8485
.ok_or_else(|| Error::new_message("expected 2nd argument as contents"))?;
@@ -88,7 +89,7 @@ pub fn regex_find_at(context: *mut sqlite3_context, values: &[*mut sqlite3_value
8889

8990
let content = api::value_text_notnull(arg_content)?;
9091
let offset = api::value_int(arg_offset) as usize;
91-
match regex.as_ref().find_at(content, offset) {
92+
match regex.find_at(content, offset) {
9293
Some(m) => {
9394
api::result_text(context, m.as_str())?;
9495
}
@@ -105,7 +106,7 @@ pub fn regex_find_at(context: *mut sqlite3_context, values: &[*mut sqlite3_value
105106
/// regex_replace(regex, contents, replacement)
106107
pub fn regex_replace(context: *mut sqlite3_context, values: &[*mut sqlite3_value]) -> Result<()> {
107108
let (regex, input_type) = regex_from_value_or_cache(context, values, 0)?;
108-
109+
let regex = unsafe { &mut *regex };
109110
let content = api::value_text_notnull(
110111
values
111112
.get(1)
@@ -117,9 +118,9 @@ pub fn regex_replace(context: *mut sqlite3_context, values: &[*mut sqlite3_value
117118
.ok_or_else(|| Error::new_message("expected 3rd argument as replacement"))?,
118119
)?;
119120

120-
let result = regex.as_ref().replace(content, replacement);
121+
let result = regex.replace(content, replacement);
121122

122-
api::result_text(context, &result)?;
123+
api::result_text(context, result)?;
123124
cleanup_regex_value_cached(context, regex, input_type);
124125

125126
Ok(())
@@ -131,7 +132,7 @@ pub fn regex_replace_all(
131132
values: &[*mut sqlite3_value],
132133
) -> Result<()> {
133134
let (regex, input_type) = regex_from_value_or_cache(context, values, 0)?;
134-
135+
let regex = unsafe { &mut *regex };
135136
let content = api::value_text_notnull(
136137
values
137138
.get(1)
@@ -142,8 +143,8 @@ pub fn regex_replace_all(
142143
.get(2)
143144
.ok_or_else(|| Error::new_message("expected 3rd argument as replacement"))?,
144145
)?;
145-
let result = regex.as_ref().replace_all(content, replacement);
146-
api::result_text(context, &result)?;
146+
let result = regex.replace_all(content, replacement);
147+
api::result_text(context, result)?;
147148

148149
cleanup_regex_value_cached(context, regex, input_type);
149150
Ok(())
@@ -152,7 +153,7 @@ pub fn regex_replace_all(
152153
/// regex_capture(regex, contents, group)
153154
pub fn regex_capture(context: *mut sqlite3_context, values: &[*mut sqlite3_value]) -> Result<()> {
154155
let (regex, input_type) = regex_from_value_or_cache(context, values, 0)?;
155-
156+
let regex = unsafe { &mut *regex };
156157
let content = api::value_text_notnull(
157158
values
158159
.get(1)
@@ -162,7 +163,7 @@ pub fn regex_capture(context: *mut sqlite3_context, values: &[*mut sqlite3_value
162163
.get(2)
163164
.ok_or_else(|| Error::new_message("expected 3rd argument as group index or name"))?;
164165

165-
let result = regex.as_ref().captures(content);
166+
let result = regex.captures(content);
166167
match result {
167168
None => api::result_null(context),
168169
Some(captures) => {
@@ -185,13 +186,14 @@ pub fn regex_capture(context: *mut sqlite3_context, values: &[*mut sqlite3_value
185186
Ok(())
186187
}
187188

188-
/// regex_capture(regex, contents, group)
189+
/// regex_capture(captures, group)
189190
pub fn regex_capture2(context: *mut sqlite3_context, values: &[*mut sqlite3_value]) -> Result<()> {
190191
let captures = value_regex_captures(
191192
values
192193
.get(0)
193194
.ok_or_else(|| Error::new_message("expected 1st argument as capture group"))?,
194195
)?;
196+
let captures = unsafe { &*captures };
195197
let group_arg = values
196198
.get(1)
197199
.ok_or_else(|| Error::new_message("expected 3rd argument as group index or name"))?;
@@ -225,6 +227,5 @@ pub fn regex_capture2(context: *mut sqlite3_context, values: &[*mut sqlite3_valu
225227
None => api::result_null(context),
226228
},
227229
}
228-
Box::into_raw(captures);
229230
Ok(())
230231
}

src/regexset.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ pub fn regexset(context: *mut sqlite3_context, values: &[*mut sqlite3_value]) ->
1919
/// regexset_print(regexset)
2020
pub fn regexset_print(context: *mut sqlite3_context, values: &[*mut sqlite3_value]) -> Result<()> {
2121
let regexset = value_regexset(values.get(0).ok_or_else(|| Error::new_message(""))?)?;
22+
let regexset = unsafe { &*regexset };
2223
api::result_json(context, regexset.patterns().into())?;
23-
Box::into_raw(regexset);
2424
Ok(())
2525
}
2626

@@ -30,8 +30,8 @@ pub fn regexset_is_match(
3030
values: &[*mut sqlite3_value],
3131
) -> Result<()> {
3232
let regexset = value_regexset(values.get(0).ok_or_else(|| Error::new_message(""))?)?;
33+
let regexset = unsafe { &*regexset };
3334
let text = api::value_text_notnull(values.get(1).ok_or_else(|| Error::new_message(""))?)?;
3435
api::result_bool(context, regexset.is_match(text));
35-
Box::into_raw(regexset);
3636
Ok(())
3737
}

src/regexset_matches.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,13 +123,14 @@ impl VTabCursor for RegexSetMatchesCursor {
123123
let r = value_regexset(values.get(0).ok_or_else(|| {
124124
Error::new_message("internal error: pattern not passed into xFilter")
125125
})?)?;
126+
let r = unsafe { &mut *r };
126127
let contents = api::value_text_notnull(values.get(1).ok_or_else(|| {
127128
Error::new_message("internal error: contents not passed into xFilter")
128129
})?)?;
129-
self.regex_set = Some((*r).clone());
130+
131+
self.regex_set = Some(r.clone());
130132
self.matches = Some(r.matches(contents).into_iter().collect());
131133
self.rowid = 0;
132-
Box::into_raw(r);
133134
Ok(())
134135
}
135136

src/split.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ impl VTabCursor for RegexSplitCursor<'_> {
123123
.get(0)
124124
.ok_or_else(|| Error::new_message("expected 1st argument as regex"))?,
125125
)?;
126+
let r = unsafe { &*r };
126127
let contents = api::value_text_notnull(
127128
values
128129
.get(1)
@@ -131,7 +132,6 @@ impl VTabCursor for RegexSplitCursor<'_> {
131132

132133
let split = r.split(contents);
133134
self.split = Some(split.map(|i| i.to_string()).collect());
134-
Box::into_raw(r);
135135
self.rowid = 0;
136136
self.contents = Some(contents.to_owned());
137137
Ok(())

0 commit comments

Comments
 (0)