/src/libxmlb/src/xb-query-context.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- |
2 | | * vi:set noexpandtab tabstop=8 shiftwidth=8: |
3 | | * |
4 | | * Copyright 2020 Endless OS Foundation LLC |
5 | | * |
6 | | * Author: Philip Withnall <withnall@endlessm.com> |
7 | | * |
8 | | * SPDX-License-Identifier: LGPL-2.1-or-later |
9 | | */ |
10 | | |
11 | 0 | #define G_LOG_DOMAIN "XbQueryContext" |
12 | | |
13 | | #include "config.h" |
14 | | |
15 | | #include <glib.h> |
16 | | |
17 | | #include "xb-query-context.h" |
18 | | #include "xb-query.h" |
19 | | #include "xb-value-bindings.h" |
20 | | |
21 | | /* Why are #XbQueryContext and #XbValueBindings not the same object? |
22 | | * #XbQueryContext is associated with a query, but the #XbValueBindings is |
23 | | * associated with a query *and* the #XbMachine which runs for it. Once an |
24 | | * #XbQuery is turned into an #XbMachine to be evaluated, the #XbQueryContext is |
25 | | * ignored and only the #XbValueBindings are taken forward to be used, copied |
26 | | * and subsetted for various parts of the #XbMachine. */ |
27 | | typedef struct { |
28 | | guint limit; |
29 | | XbQueryFlags flags; |
30 | | XbValueBindings bindings; |
31 | | gpointer dummy[5]; |
32 | | } RealQueryContext; |
33 | | |
34 | | G_STATIC_ASSERT(sizeof(XbQueryContext) == sizeof(RealQueryContext)); |
35 | | |
36 | | G_DEFINE_BOXED_TYPE(XbQueryContext, xb_query_context, xb_query_context_copy, xb_query_context_free) |
37 | | |
38 | | /** |
39 | | * xb_query_context_init: |
40 | | * @self: an uninitialised #XbQueryContext to initialise |
41 | | * |
42 | | * Initialise a stack-allocated #XbQueryContext struct so it can be used. |
43 | | * |
44 | | * Stack-allocated #XbQueryContext instances should be freed once finished |
45 | | * with, using xb_query_context_clear() (or `g_auto(XbQueryContext)`, which is |
46 | | * equivalent). |
47 | | * |
48 | | * Since: 0.3.0 |
49 | | */ |
50 | | void |
51 | | xb_query_context_init(XbQueryContext *self) |
52 | 0 | { |
53 | 0 | RealQueryContext *_self = (RealQueryContext *)self; |
54 | |
|
55 | 0 | _self->limit = 0; |
56 | 0 | _self->flags = XB_QUERY_FLAG_NONE; |
57 | 0 | xb_value_bindings_init(&_self->bindings); |
58 | 0 | } |
59 | | |
60 | | /** |
61 | | * xb_query_context_clear: |
62 | | * @self: an #XbQueryContext |
63 | | * |
64 | | * Clear an #XbQueryContext, freeing any allocated memory it points to. |
65 | | * |
66 | | * After this function has been called, the contents of the #XbQueryContext are |
67 | | * undefined, and it’s only safe to call xb_query_context_init() on it. |
68 | | * |
69 | | * Since: 0.3.0 |
70 | | */ |
71 | | void |
72 | | xb_query_context_clear(XbQueryContext *self) |
73 | 0 | { |
74 | 0 | RealQueryContext *_self = (RealQueryContext *)self; |
75 | |
|
76 | 0 | xb_value_bindings_clear(&_self->bindings); |
77 | 0 | } |
78 | | |
79 | | /** |
80 | | * xb_query_context_copy: |
81 | | * @self: an #XbQueryContext |
82 | | * |
83 | | * Copy @self into a new heap-allocated #XbQueryContext instance. |
84 | | * |
85 | | * Returns: (transfer full): a copy of @self |
86 | | * Since: 0.3.0 |
87 | | */ |
88 | | XbQueryContext * |
89 | | xb_query_context_copy(XbQueryContext *self) |
90 | 0 | { |
91 | 0 | RealQueryContext *_self = (RealQueryContext *)self; |
92 | 0 | g_autoptr(XbQueryContext) copy = g_new0(XbQueryContext, 1); |
93 | 0 | RealQueryContext *_copy = (RealQueryContext *)copy; |
94 | 0 | gsize i = 0; |
95 | |
|
96 | 0 | xb_query_context_init(copy); |
97 | |
|
98 | 0 | _copy->limit = _self->limit; |
99 | 0 | _copy->flags = _self->flags; |
100 | |
|
101 | 0 | while (xb_value_bindings_copy_binding(&_self->bindings, i, &_copy->bindings, i)) |
102 | 0 | i++; |
103 | |
|
104 | 0 | return g_steal_pointer(©); |
105 | 0 | } |
106 | | |
107 | | /** |
108 | | * xb_query_context_free: |
109 | | * @self: a heap-allocated #XbQueryContext |
110 | | * |
111 | | * Free a heap-allocated #XbQueryContext instance. This should be used on |
112 | | * #XbQueryContext instances created with xb_query_context_copy(). |
113 | | * |
114 | | * For stack-allocated instances, xb_query_context_clear() should be used |
115 | | * instead. |
116 | | * |
117 | | * Since: 0.3.0 |
118 | | */ |
119 | | void |
120 | | xb_query_context_free(XbQueryContext *self) |
121 | 0 | { |
122 | 0 | g_return_if_fail(self != NULL); |
123 | | |
124 | 0 | xb_query_context_clear(self); |
125 | 0 | g_free(self); |
126 | 0 | } |
127 | | |
128 | | /** |
129 | | * xb_query_context_get_bindings: |
130 | | * @self: an #XbQueryContext |
131 | | * |
132 | | * Get the #XbValueBindings for this query context. |
133 | | * |
134 | | * Returns: (transfer none) (not nullable): bindings |
135 | | * Since: 0.3.0 |
136 | | */ |
137 | | XbValueBindings * |
138 | | xb_query_context_get_bindings(XbQueryContext *self) |
139 | 0 | { |
140 | 0 | RealQueryContext *_self = (RealQueryContext *)self; |
141 | |
|
142 | 0 | g_return_val_if_fail(self != NULL, NULL); |
143 | | |
144 | 0 | return &_self->bindings; |
145 | 0 | } |
146 | | |
147 | | /** |
148 | | * xb_query_context_get_limit: |
149 | | * @self: an #XbQueryContext |
150 | | * |
151 | | * Get the limit on the number of query results. See |
152 | | * xb_query_context_set_limit(). |
153 | | * |
154 | | * Returns: limit on results, or `0` if unlimited |
155 | | * Since: 0.3.0 |
156 | | */ |
157 | | guint |
158 | | xb_query_context_get_limit(XbQueryContext *self) |
159 | 0 | { |
160 | 0 | RealQueryContext *_self = (RealQueryContext *)self; |
161 | |
|
162 | 0 | g_return_val_if_fail(self != NULL, 0); |
163 | | |
164 | 0 | return _self->limit; |
165 | 0 | } |
166 | | |
167 | | /** |
168 | | * xb_query_context_set_limit: |
169 | | * @self: an #XbQueryContext |
170 | | * @limit: number of query results to return, or `0` for unlimited |
171 | | * |
172 | | * Set the limit on the number of results to return from the query. |
173 | | * |
174 | | * Since: 0.3.0 |
175 | | */ |
176 | | void |
177 | | xb_query_context_set_limit(XbQueryContext *self, guint limit) |
178 | 0 | { |
179 | 0 | RealQueryContext *_self = (RealQueryContext *)self; |
180 | |
|
181 | 0 | g_return_if_fail(self != NULL); |
182 | | |
183 | 0 | _self->limit = limit; |
184 | 0 | } |
185 | | |
186 | | /** |
187 | | * xb_query_context_get_flags: |
188 | | * @self: an #XbQueryContext |
189 | | * |
190 | | * Get the flags set on the context. See xb_query_context_set_flags(). |
191 | | * |
192 | | * Returns: query flags |
193 | | * Since: 0.3.0 |
194 | | */ |
195 | | XbQueryFlags |
196 | | xb_query_context_get_flags(XbQueryContext *self) |
197 | 0 | { |
198 | 0 | RealQueryContext *_self = (RealQueryContext *)self; |
199 | |
|
200 | 0 | g_return_val_if_fail(self != NULL, XB_QUERY_FLAG_NONE); |
201 | | |
202 | 0 | return _self->flags; |
203 | 0 | } |
204 | | |
205 | | /** |
206 | | * xb_query_context_set_flags: |
207 | | * @self: an #XbQueryContext |
208 | | * @flags: query flags, or %XB_QUERY_FLAG_NONE for none |
209 | | * |
210 | | * Set flags which affect the behaviour of the query. |
211 | | * |
212 | | * Since: 0.3.0 |
213 | | */ |
214 | | void |
215 | | xb_query_context_set_flags(XbQueryContext *self, XbQueryFlags flags) |
216 | 0 | { |
217 | 0 | RealQueryContext *_self = (RealQueryContext *)self; |
218 | |
|
219 | 0 | g_return_if_fail(self != NULL); |
220 | | |
221 | 0 | _self->flags = flags; |
222 | 0 | } |