1use crate::{ffi, SparqlConnection, SparqlCursor};
7#[cfg(feature = "v3_3")]
8#[cfg_attr(docsrs, doc(cfg(feature = "v3_3")))]
9use crate::{RdfFormat, SerializeFlags};
10use glib::{prelude::*, translate::*};
11use std::{boxed::Box as Box_, pin::Pin};
12
13glib::wrapper! {
14 #[doc(alias = "TrackerSparqlStatement")]
15 pub struct SparqlStatement(Object<ffi::TrackerSparqlStatement, ffi::TrackerSparqlStatementClass>);
16
17 match fn {
18 type_ => || ffi::tracker_sparql_statement_get_type(),
19 }
20}
21
22impl SparqlStatement {
23 #[doc(alias = "tracker_sparql_statement_bind_boolean")]
24 pub fn bind_boolean(&self, name: &str, value: bool) {
25 unsafe {
26 ffi::tracker_sparql_statement_bind_boolean(
27 self.to_glib_none().0,
28 name.to_glib_none().0,
29 value.into_glib(),
30 );
31 }
32 }
33
34 #[cfg(feature = "v3_2")]
35 #[cfg_attr(docsrs, doc(cfg(feature = "v3_2")))]
36 #[doc(alias = "tracker_sparql_statement_bind_datetime")]
37 pub fn bind_datetime(&self, name: &str, value: &glib::DateTime) {
38 unsafe {
39 ffi::tracker_sparql_statement_bind_datetime(
40 self.to_glib_none().0,
41 name.to_glib_none().0,
42 value.to_glib_none().0,
43 );
44 }
45 }
46
47 #[doc(alias = "tracker_sparql_statement_bind_double")]
48 pub fn bind_double(&self, name: &str, value: f64) {
49 unsafe {
50 ffi::tracker_sparql_statement_bind_double(
51 self.to_glib_none().0,
52 name.to_glib_none().0,
53 value,
54 );
55 }
56 }
57
58 #[doc(alias = "tracker_sparql_statement_bind_int")]
59 pub fn bind_int(&self, name: &str, value: i64) {
60 unsafe {
61 ffi::tracker_sparql_statement_bind_int(
62 self.to_glib_none().0,
63 name.to_glib_none().0,
64 value,
65 );
66 }
67 }
68
69 #[cfg(feature = "v3_7")]
70 #[cfg_attr(docsrs, doc(cfg(feature = "v3_7")))]
71 #[doc(alias = "tracker_sparql_statement_bind_langstring")]
72 pub fn bind_langstring(&self, name: &str, value: &str, langtag: &str) {
73 unsafe {
74 ffi::tracker_sparql_statement_bind_langstring(
75 self.to_glib_none().0,
76 name.to_glib_none().0,
77 value.to_glib_none().0,
78 langtag.to_glib_none().0,
79 );
80 }
81 }
82
83 #[doc(alias = "tracker_sparql_statement_bind_string")]
84 pub fn bind_string(&self, name: &str, value: &str) {
85 unsafe {
86 ffi::tracker_sparql_statement_bind_string(
87 self.to_glib_none().0,
88 name.to_glib_none().0,
89 value.to_glib_none().0,
90 );
91 }
92 }
93
94 #[doc(alias = "tracker_sparql_statement_clear_bindings")]
95 pub fn clear_bindings(&self) {
96 unsafe {
97 ffi::tracker_sparql_statement_clear_bindings(self.to_glib_none().0);
98 }
99 }
100
101 #[doc(alias = "tracker_sparql_statement_execute")]
102 pub fn execute(
103 &self,
104 cancellable: Option<&impl IsA<gio::Cancellable>>,
105 ) -> Result<SparqlCursor, glib::Error> {
106 unsafe {
107 let mut error = std::ptr::null_mut();
108 let ret = ffi::tracker_sparql_statement_execute(
109 self.to_glib_none().0,
110 cancellable.map(|p| p.as_ref()).to_glib_none().0,
111 &mut error,
112 );
113 if error.is_null() {
114 Ok(from_glib_full(ret))
115 } else {
116 Err(from_glib_full(error))
117 }
118 }
119 }
120
121 #[doc(alias = "tracker_sparql_statement_execute_async")]
122 pub fn execute_async<P: FnOnce(Result<SparqlCursor, glib::Error>) + 'static>(
123 &self,
124 cancellable: Option<&impl IsA<gio::Cancellable>>,
125 callback: P,
126 ) {
127 let main_context = glib::MainContext::ref_thread_default();
128 let is_main_context_owner = main_context.is_owner();
129 let has_acquired_main_context = (!is_main_context_owner)
130 .then(|| main_context.acquire().ok())
131 .flatten();
132 assert!(
133 is_main_context_owner || has_acquired_main_context.is_some(),
134 "Async operations only allowed if the thread is owning the MainContext"
135 );
136
137 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
138 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
139 unsafe extern "C" fn execute_async_trampoline<
140 P: FnOnce(Result<SparqlCursor, glib::Error>) + 'static,
141 >(
142 _source_object: *mut glib::gobject_ffi::GObject,
143 res: *mut gio::ffi::GAsyncResult,
144 user_data: glib::ffi::gpointer,
145 ) {
146 unsafe {
147 let mut error = std::ptr::null_mut();
148 let ret = ffi::tracker_sparql_statement_execute_finish(
149 _source_object as *mut _,
150 res,
151 &mut error,
152 );
153 let result = if error.is_null() {
154 Ok(from_glib_full(ret))
155 } else {
156 Err(from_glib_full(error))
157 };
158 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
159 Box_::from_raw(user_data as *mut _);
160 let callback: P = callback.into_inner();
161 callback(result);
162 }
163 }
164 let callback = execute_async_trampoline::<P>;
165 unsafe {
166 ffi::tracker_sparql_statement_execute_async(
167 self.to_glib_none().0,
168 cancellable.map(|p| p.as_ref()).to_glib_none().0,
169 Some(callback),
170 Box_::into_raw(user_data) as *mut _,
171 );
172 }
173 }
174
175 pub fn execute_future(
176 &self,
177 ) -> Pin<Box_<dyn std::future::Future<Output = Result<SparqlCursor, glib::Error>> + 'static>>
178 {
179 Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
180 obj.execute_async(Some(cancellable), move |res| {
181 send.resolve(res);
182 });
183 }))
184 }
185
186 #[doc(alias = "tracker_sparql_statement_get_connection")]
187 #[doc(alias = "get_connection")]
188 pub fn connection(&self) -> Option<SparqlConnection> {
189 unsafe {
190 from_glib_none(ffi::tracker_sparql_statement_get_connection(
191 self.to_glib_none().0,
192 ))
193 }
194 }
195
196 #[doc(alias = "tracker_sparql_statement_get_sparql")]
197 #[doc(alias = "get_sparql")]
198 pub fn sparql(&self) -> Option<glib::GString> {
199 unsafe {
200 from_glib_none(ffi::tracker_sparql_statement_get_sparql(
201 self.to_glib_none().0,
202 ))
203 }
204 }
205
206 #[cfg(feature = "v3_3")]
207 #[cfg_attr(docsrs, doc(cfg(feature = "v3_3")))]
208 #[doc(alias = "tracker_sparql_statement_serialize_async")]
209 pub fn serialize_async<P: FnOnce(Result<gio::InputStream, glib::Error>) + 'static>(
210 &self,
211 flags: SerializeFlags,
212 format: RdfFormat,
213 cancellable: Option<&impl IsA<gio::Cancellable>>,
214 callback: P,
215 ) {
216 let main_context = glib::MainContext::ref_thread_default();
217 let is_main_context_owner = main_context.is_owner();
218 let has_acquired_main_context = (!is_main_context_owner)
219 .then(|| main_context.acquire().ok())
220 .flatten();
221 assert!(
222 is_main_context_owner || has_acquired_main_context.is_some(),
223 "Async operations only allowed if the thread is owning the MainContext"
224 );
225
226 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
227 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
228 unsafe extern "C" fn serialize_async_trampoline<
229 P: FnOnce(Result<gio::InputStream, glib::Error>) + 'static,
230 >(
231 _source_object: *mut glib::gobject_ffi::GObject,
232 res: *mut gio::ffi::GAsyncResult,
233 user_data: glib::ffi::gpointer,
234 ) {
235 unsafe {
236 let mut error = std::ptr::null_mut();
237 let ret = ffi::tracker_sparql_statement_serialize_finish(
238 _source_object as *mut _,
239 res,
240 &mut error,
241 );
242 let result = if error.is_null() {
243 Ok(from_glib_full(ret))
244 } else {
245 Err(from_glib_full(error))
246 };
247 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
248 Box_::from_raw(user_data as *mut _);
249 let callback: P = callback.into_inner();
250 callback(result);
251 }
252 }
253 let callback = serialize_async_trampoline::<P>;
254 unsafe {
255 ffi::tracker_sparql_statement_serialize_async(
256 self.to_glib_none().0,
257 flags.into_glib(),
258 format.into_glib(),
259 cancellable.map(|p| p.as_ref()).to_glib_none().0,
260 Some(callback),
261 Box_::into_raw(user_data) as *mut _,
262 );
263 }
264 }
265
266 #[cfg(feature = "v3_3")]
267 #[cfg_attr(docsrs, doc(cfg(feature = "v3_3")))]
268 pub fn serialize_future(
269 &self,
270 flags: SerializeFlags,
271 format: RdfFormat,
272 ) -> Pin<Box_<dyn std::future::Future<Output = Result<gio::InputStream, glib::Error>> + 'static>>
273 {
274 Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
275 obj.serialize_async(flags, format, Some(cancellable), move |res| {
276 send.resolve(res);
277 });
278 }))
279 }
280
281 #[cfg(feature = "v3_5")]
282 #[cfg_attr(docsrs, doc(cfg(feature = "v3_5")))]
283 #[doc(alias = "tracker_sparql_statement_update")]
284 pub fn update(
285 &self,
286 cancellable: Option<&impl IsA<gio::Cancellable>>,
287 ) -> Result<(), glib::Error> {
288 unsafe {
289 let mut error = std::ptr::null_mut();
290 let is_ok = ffi::tracker_sparql_statement_update(
291 self.to_glib_none().0,
292 cancellable.map(|p| p.as_ref()).to_glib_none().0,
293 &mut error,
294 );
295 debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
296 if error.is_null() {
297 Ok(())
298 } else {
299 Err(from_glib_full(error))
300 }
301 }
302 }
303
304 #[cfg(feature = "v3_5")]
305 #[cfg_attr(docsrs, doc(cfg(feature = "v3_5")))]
306 #[doc(alias = "tracker_sparql_statement_update_async")]
307 pub fn update_async<P: FnOnce(Result<(), glib::Error>) + 'static>(
308 &self,
309 cancellable: Option<&impl IsA<gio::Cancellable>>,
310 callback: P,
311 ) {
312 let main_context = glib::MainContext::ref_thread_default();
313 let is_main_context_owner = main_context.is_owner();
314 let has_acquired_main_context = (!is_main_context_owner)
315 .then(|| main_context.acquire().ok())
316 .flatten();
317 assert!(
318 is_main_context_owner || has_acquired_main_context.is_some(),
319 "Async operations only allowed if the thread is owning the MainContext"
320 );
321
322 let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
323 Box_::new(glib::thread_guard::ThreadGuard::new(callback));
324 unsafe extern "C" fn update_async_trampoline<
325 P: FnOnce(Result<(), glib::Error>) + 'static,
326 >(
327 _source_object: *mut glib::gobject_ffi::GObject,
328 res: *mut gio::ffi::GAsyncResult,
329 user_data: glib::ffi::gpointer,
330 ) {
331 unsafe {
332 let mut error = std::ptr::null_mut();
333 ffi::tracker_sparql_statement_update_finish(
334 _source_object as *mut _,
335 res,
336 &mut error,
337 );
338 let result = if error.is_null() {
339 Ok(())
340 } else {
341 Err(from_glib_full(error))
342 };
343 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
344 Box_::from_raw(user_data as *mut _);
345 let callback: P = callback.into_inner();
346 callback(result);
347 }
348 }
349 let callback = update_async_trampoline::<P>;
350 unsafe {
351 ffi::tracker_sparql_statement_update_async(
352 self.to_glib_none().0,
353 cancellable.map(|p| p.as_ref()).to_glib_none().0,
354 Some(callback),
355 Box_::into_raw(user_data) as *mut _,
356 );
357 }
358 }
359
360 #[cfg(feature = "v3_5")]
361 #[cfg_attr(docsrs, doc(cfg(feature = "v3_5")))]
362 pub fn update_future(
363 &self,
364 ) -> Pin<Box_<dyn std::future::Future<Output = Result<(), glib::Error>> + 'static>> {
365 Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
366 obj.update_async(Some(cancellable), move |res| {
367 send.resolve(res);
368 });
369 }))
370 }
371}