1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3 /* e-source-backend-summary-setup.c - Backend Summary Data Configuration.
4 *
5 * Copyright (C) 2012 Intel Corporation
6 *
7 * This library is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation.
10 *
11 * This library is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
14 * for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this library. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * Authors: Tristan Van Berkom <tristanvb@openismus.com>
20 */
21
22 /**
23 * SECTION: e-source-backend-summary-setup
24 * @include: libebook-contacts/libebook-contacts.h
25 * @short_description: #ESource extension to configure summary fields
26 *
27 * The #ESourceBackendSummarySetup extension configures which #EContactFields
28 * should be in the summary and which of those fields should be optimized for
29 * quicker search results.
30 *
31 * Access the extension as follows:
32 *
33 * |[
34 * #include <libebook-contacts/libebook-contacts.h>
35 *
36 * ESourceBackendSummarySetup *extension;
37 *
38 * extension = e_source_get_extension (source, E_SOURCE_EXTENSION_BACKEND_SUMMARY_SETUP);
39 * ]|
40 *
41 * <note><para>The summary configuration is expected to be setup in only one way for
42 * a given #ESource at creation time. Any configurations made after creation of the
43 * book in question will be ignored.</para></note>
44 *
45 **/
46
47 #include "e-source-backend-summary-setup.h"
48 #include "e-book-contacts-enumtypes.h"
49
50 struct _ESourceBackendSummarySetupPrivate {
51 GMutex property_lock;
52 gchar *summary_fields;
53 gchar *indexed_fields;
54 };
55
56 enum {
57 PROP_0,
58 PROP_SUMMARY_FIELDS,
59 PROP_INDEXED_FIELDS
60 };
61
G_DEFINE_TYPE_WITH_PRIVATE(ESourceBackendSummarySetup,e_source_backend_summary_setup,E_TYPE_SOURCE_EXTENSION)62 G_DEFINE_TYPE_WITH_PRIVATE (
63 ESourceBackendSummarySetup,
64 e_source_backend_summary_setup,
65 E_TYPE_SOURCE_EXTENSION)
66
67 static gchar *
68 source_backend_summary_setup_dup_literal_fields (ESourceBackendSummarySetup *extension,
69 gint which)
70 {
71 gchar *duplicate = NULL;
72
73 g_mutex_lock (&extension->priv->property_lock);
74
75 switch (which) {
76 case PROP_SUMMARY_FIELDS:
77 duplicate = g_strdup (extension->priv->summary_fields);
78 break;
79 case PROP_INDEXED_FIELDS:
80 duplicate = g_strdup (extension->priv->indexed_fields);
81 break;
82 default:
83 g_return_val_if_reached (NULL);
84 break;
85 }
86
87 g_mutex_unlock (&extension->priv->property_lock);
88
89 return duplicate;
90 }
91
92 static void
source_backend_summary_setup_set_literal_fields(ESourceBackendSummarySetup * extension,const gchar * literal_fields,gint which)93 source_backend_summary_setup_set_literal_fields (ESourceBackendSummarySetup *extension,
94 const gchar *literal_fields,
95 gint which)
96 {
97 const gchar *property_name;
98 gchar **target;
99
100 switch (which) {
101 case PROP_SUMMARY_FIELDS:
102 target = &(extension->priv->summary_fields);
103 property_name = "summary-fields";
104 break;
105 case PROP_INDEXED_FIELDS:
106 target = &(extension->priv->indexed_fields);
107 property_name = "indexed-fields";
108 break;
109 default:
110 g_return_if_reached ();
111 break;
112 }
113
114 g_mutex_lock (&extension->priv->property_lock);
115
116 if (e_util_strcmp0 (*target, literal_fields) == 0) {
117 g_mutex_unlock (&extension->priv->property_lock);
118 return;
119 }
120
121 g_free (*target);
122 *target = e_util_strdup_strip (literal_fields);
123
124 g_mutex_unlock (&extension->priv->property_lock);
125
126 g_object_notify (G_OBJECT (extension), property_name);
127 }
128
129 static void
source_backend_summary_setup_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)130 source_backend_summary_setup_set_property (GObject *object,
131 guint property_id,
132 const GValue *value,
133 GParamSpec *pspec)
134 {
135 switch (property_id) {
136 case PROP_SUMMARY_FIELDS:
137 case PROP_INDEXED_FIELDS:
138 source_backend_summary_setup_set_literal_fields (
139 E_SOURCE_BACKEND_SUMMARY_SETUP (object),
140 g_value_get_string (value), property_id);
141 return;
142 }
143
144 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
145 }
146
147 static void
source_backend_summary_setup_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)148 source_backend_summary_setup_get_property (GObject *object,
149 guint property_id,
150 GValue *value,
151 GParamSpec *pspec)
152 {
153 switch (property_id) {
154 case PROP_SUMMARY_FIELDS:
155 case PROP_INDEXED_FIELDS:
156 g_value_take_string (
157 value,
158 source_backend_summary_setup_dup_literal_fields (
159 E_SOURCE_BACKEND_SUMMARY_SETUP (object),
160 property_id));
161 return;
162 }
163
164 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
165 }
166
167 static void
source_backend_summary_setup_finalize(GObject * object)168 source_backend_summary_setup_finalize (GObject *object)
169 {
170 ESourceBackendSummarySetupPrivate *priv;
171
172 priv = E_SOURCE_BACKEND_SUMMARY_SETUP (object)->priv;
173
174 g_mutex_clear (&priv->property_lock);
175 g_free (priv->summary_fields);
176 g_free (priv->indexed_fields);
177
178 /* Chain up to parent's finalize() method. */
179 G_OBJECT_CLASS (e_source_backend_summary_setup_parent_class)->
180 finalize (object);
181 }
182
183 static void
e_source_backend_summary_setup_class_init(ESourceBackendSummarySetupClass * class)184 e_source_backend_summary_setup_class_init (ESourceBackendSummarySetupClass *class)
185 {
186 GObjectClass *object_class;
187 ESourceExtensionClass *extension_class;
188
189 object_class = G_OBJECT_CLASS (class);
190 object_class->get_property = source_backend_summary_setup_get_property;
191 object_class->set_property = source_backend_summary_setup_set_property;
192 object_class->finalize = source_backend_summary_setup_finalize;
193
194 extension_class = E_SOURCE_EXTENSION_CLASS (class);
195 extension_class->name = E_SOURCE_EXTENSION_BACKEND_SUMMARY_SETUP;
196
197 g_object_class_install_property (
198 object_class,
199 PROP_SUMMARY_FIELDS,
200 g_param_spec_string (
201 "summary-fields",
202 "Summary Fields",
203 "The list of quick reference summary fields",
204 NULL,
205 G_PARAM_READWRITE |
206 G_PARAM_CONSTRUCT |
207 G_PARAM_EXPLICIT_NOTIFY |
208 G_PARAM_STATIC_STRINGS |
209 E_SOURCE_PARAM_SETTING));
210
211 g_object_class_install_property (
212 object_class,
213 PROP_INDEXED_FIELDS,
214 g_param_spec_string (
215 "indexed-fields",
216 "Indexed Fields",
217 "The list of summary fields which are to be "
218 "given indexes in the underlying database",
219 NULL,
220 G_PARAM_READWRITE |
221 G_PARAM_CONSTRUCT |
222 G_PARAM_EXPLICIT_NOTIFY |
223 G_PARAM_STATIC_STRINGS |
224 E_SOURCE_PARAM_SETTING));
225 }
226
227 static void
e_source_backend_summary_setup_init(ESourceBackendSummarySetup * extension)228 e_source_backend_summary_setup_init (ESourceBackendSummarySetup *extension)
229 {
230 extension->priv = e_source_backend_summary_setup_get_instance_private (extension);
231 g_mutex_init (&extension->priv->property_lock);
232 }
233
234 static EContactField *
source_backend_summary_setup_get_fields_array(ESourceBackendSummarySetup * extension,gint * n_fields,gint which)235 source_backend_summary_setup_get_fields_array (ESourceBackendSummarySetup *extension,
236 gint *n_fields,
237 gint which)
238 {
239 EContactField field;
240 EContactField *fields = NULL;
241 gchar *literal_fields;
242 gchar **split = NULL;
243 gint n_ret_fields = 0, i;
244
245 literal_fields = source_backend_summary_setup_dup_literal_fields (extension, which);
246
247 if (literal_fields)
248 split = g_strsplit (literal_fields, ":", 0);
249
250 if (split) {
251 n_ret_fields = g_strv_length (split);
252 fields = g_new (EContactField, n_ret_fields);
253
254 for (i = 0; i < n_ret_fields; i++) {
255 field = e_contact_field_id (split[i]);
256
257 if (field == 0)
258 g_warning ("Unrecognized field '%s' in ESourceBackendSummarySetup fields", split[i]);
259
260 fields[i] = field;
261 }
262
263 g_strfreev (split);
264 }
265
266 g_free (literal_fields);
267
268 *n_fields = n_ret_fields;
269
270 return fields;
271 }
272
273 static void
e_source_backend_summary_setup_set_fields_array(ESourceBackendSummarySetup * extension,EContactField * fields,gint n_fields,gint which)274 e_source_backend_summary_setup_set_fields_array (ESourceBackendSummarySetup *extension,
275 EContactField *fields,
276 gint n_fields,
277 gint which)
278 {
279 gint i;
280 GString *string;
281 gboolean malformed = FALSE;
282
283 string = g_string_new ("");
284
285 for (i = 0; i < n_fields; i++) {
286 const gchar *field_name = e_contact_field_name (fields[i]);
287
288 if (field_name == NULL) {
289 g_warning ("Invalid EContactField given to ESourceBackendSummarySetup");
290 malformed = TRUE;
291 break;
292 }
293
294 if (i > 0)
295 g_string_append_c (string, ':');
296
297 g_string_append (string, field_name);
298 }
299
300 if (malformed == FALSE)
301 source_backend_summary_setup_set_literal_fields (extension, string->str, which);
302
303 g_string_free (string, TRUE);
304 }
305
306 static void
e_source_backend_summary_setup_set_fields_va_list(ESourceBackendSummarySetup * extension,va_list var_args,gint which)307 e_source_backend_summary_setup_set_fields_va_list (ESourceBackendSummarySetup *extension,
308 va_list var_args,
309 gint which)
310 {
311 GString *string;
312 gboolean malformed = FALSE, first_field = TRUE;
313 EContactField field;
314
315 string = g_string_new ("");
316
317 field = va_arg (var_args, EContactField);
318 while (field > 0) {
319 const gchar *field_name = e_contact_field_name (field);
320
321 if (field_name == NULL) {
322 g_warning ("Invalid EContactField given to ESourceBackendSummarySetup");
323 malformed = TRUE;
324 break;
325 }
326
327 if (!first_field)
328 g_string_append_c (string, ':');
329 else
330 first_field = FALSE;
331
332 g_string_append (string, field_name);
333
334 field = va_arg (var_args, EContactField);
335 }
336
337 if (malformed == FALSE)
338 source_backend_summary_setup_set_literal_fields (extension, string->str, which);
339
340 g_string_free (string, TRUE);
341 }
342
343 /**
344 * e_source_backend_summary_setup_get_summary_fields:
345 * @extension: An #ESourceBackendSummarySetup
346 * @n_fields: (out): A return location for the number of #EContactFields in the returned array.
347 *
348 * Fetches the #EContactFields which are configured to be a part of the summary.
349 *
350 * <note><para>If there are no configured summary fields, the default configuration is assumed</para></note>
351 *
352 * Returns: (transfer full): An array of #EContactFields @n_fields long, should be freed with g_free() when done.
353 *
354 * Since: 3.8
355 */
356 EContactField *
e_source_backend_summary_setup_get_summary_fields(ESourceBackendSummarySetup * extension,gint * n_fields)357 e_source_backend_summary_setup_get_summary_fields (ESourceBackendSummarySetup *extension,
358 gint *n_fields)
359 {
360 g_return_val_if_fail (E_IS_SOURCE_BACKEND_SUMMARY_SETUP (extension), NULL);
361 g_return_val_if_fail (n_fields != NULL, NULL);
362
363 return source_backend_summary_setup_get_fields_array (extension, n_fields, PROP_SUMMARY_FIELDS);
364 }
365
366 /**
367 * e_source_backend_summary_setup_set_summary_fieldsv:
368 * @extension: An #ESourceBackendSummarySetup
369 * @fields: The array of #EContactFields to set as summary fields
370 * @n_fields: The number of #EContactFields in @fields
371 *
372 * Sets the summary fields configured for the given addressbook.
373 *
374 * The fields %E_CONTACT_UID and %E_CONTACT_REV are not optional,
375 * they will be stored in the summary regardless of the configured summary.
376 *
377 * An empty summary configuration is assumed to be the default summary
378 * configuration.
379 *
380 * <note><para>Only #EContactFields with the type #G_TYPE_STRING or #G_TYPE_BOOLEAN
381 * are currently supported as summary fields.</para></note>
382 *
383 * Since: 3.8
384 */
385 void
e_source_backend_summary_setup_set_summary_fieldsv(ESourceBackendSummarySetup * extension,EContactField * fields,gint n_fields)386 e_source_backend_summary_setup_set_summary_fieldsv (ESourceBackendSummarySetup *extension,
387 EContactField *fields,
388 gint n_fields)
389 {
390 g_return_if_fail (E_IS_SOURCE_BACKEND_SUMMARY_SETUP (extension));
391 g_return_if_fail (n_fields >= 0);
392
393 e_source_backend_summary_setup_set_fields_array (extension, fields, n_fields, PROP_SUMMARY_FIELDS);
394 }
395
396 /**
397 * e_source_backend_summary_setup_set_summary_fields:
398 * @extension: An #ESourceBackendSummarySetup
399 * @...: A 0 terminated list of #EContactFields to set as summary fields
400 *
401 * Like e_source_backend_summary_setup_set_summary_fieldsv(), but takes a literal
402 * list of #EContactFields for convenience.
403 *
404 * To configure the address book summary fields with main phone nubmer fields:
405 *
406 * |[
407 * #include <libebook/libebook.h>
408 *
409 * ESourceBackendSummarySetup *extension;
410 *
411 * extension = e_source_get_extension (source, E_SOURCE_EXTENSION_BACKEND_SUMMARY_SETUP);
412 *
413 * e_source_backend_summary_setup_set_summary_fields (extension, E_CONTACT_FULL_NAME, E_CONTACT_EMAIL, 0);
414 * ]|
415 *
416 * Since: 3.8
417 */
418 void
e_source_backend_summary_setup_set_summary_fields(ESourceBackendSummarySetup * extension,...)419 e_source_backend_summary_setup_set_summary_fields (ESourceBackendSummarySetup *extension,
420 ...)
421 {
422 va_list var_args;
423
424 g_return_if_fail (E_IS_SOURCE_BACKEND_SUMMARY_SETUP (extension));
425
426 va_start (var_args, extension);
427 e_source_backend_summary_setup_set_fields_va_list (extension, var_args, PROP_SUMMARY_FIELDS);
428 va_end (var_args);
429 }
430
431 /**
432 * e_source_backend_summary_setup_get_indexed_fields:
433 * @extension: An #ESourceBackendSummarySetup
434 * @types: (out) (transfer full): A return location for the set of #EBookIndexTypes corresponding
435 * to each returned field, should be freed with g_free() when no longer needed.
436 * @n_fields: (out): The number of elements in the returned arrays.
437 *
438 * Fetches the #EContactFields configured to be indexed, with thier respective #EBookIndexTypes.
439 *
440 * Returns: (transfer full): The array of indexed #EContactFields.
441 *
442 * Since: 3.8
443 */
444 EContactField *
e_source_backend_summary_setup_get_indexed_fields(ESourceBackendSummarySetup * extension,EBookIndexType ** types,gint * n_fields)445 e_source_backend_summary_setup_get_indexed_fields (ESourceBackendSummarySetup *extension,
446 EBookIndexType **types,
447 gint *n_fields)
448 {
449 EContactField *ret_fields;
450 EBookIndexType *ret_types;
451 gboolean malformed = FALSE;
452 gchar **split, **index_split;
453 gchar *literal_indexes;
454 gint ret_n_fields;
455 gint i;
456
457 g_return_val_if_fail (E_IS_SOURCE_BACKEND_SUMMARY_SETUP (extension), NULL);
458 g_return_val_if_fail (types != NULL, NULL);
459 g_return_val_if_fail (n_fields != NULL, NULL);
460
461 literal_indexes = source_backend_summary_setup_dup_literal_fields (extension, PROP_INDEXED_FIELDS);
462 if (!literal_indexes) {
463 *types = NULL;
464 *n_fields = 0;
465 return NULL;
466 }
467
468 split = g_strsplit (literal_indexes, ":", 0);
469 ret_n_fields = g_strv_length (split);
470
471 ret_fields = g_new0 (EContactField, ret_n_fields);
472 ret_types = g_new0 (EBookIndexType, ret_n_fields);
473
474 for (i = 0; i < ret_n_fields && malformed == FALSE; i++) {
475
476 index_split = g_strsplit (split[i], ",", 2);
477
478 if (index_split[0] && index_split[1]) {
479 gint interpreted_enum = 0;
480
481 ret_fields[i] = e_contact_field_id (index_split[0]);
482
483 if (!e_enum_from_string (E_TYPE_BOOK_INDEX_TYPE,
484 index_split[1], &interpreted_enum)) {
485 g_warning ("Unknown index type '%s' encountered in indexed fields", index_split[1]);
486 malformed = TRUE;
487 }
488
489 if (ret_fields[i] <= 0 || ret_fields[i] >= E_CONTACT_FIELD_LAST) {
490 g_warning ("Unknown contact field '%s' encountered in indexed fields", index_split[0]);
491 malformed = TRUE;
492 }
493
494 ret_types[i] = interpreted_enum;
495 } else {
496 g_warning ("Malformed index definition '%s'", split[i]);
497 malformed = TRUE;
498 }
499
500 g_strfreev (index_split);
501 }
502
503 if (malformed) {
504 g_free (ret_fields);
505 g_free (ret_types);
506
507 ret_n_fields = 0;
508 ret_fields = NULL;
509 ret_types = NULL;
510 }
511
512 g_strfreev (split);
513 g_free (literal_indexes);
514
515 *n_fields = ret_n_fields;
516 *types = ret_types;
517
518 return ret_fields;
519 }
520
521 /**
522 * e_source_backend_summary_setup_set_indexed_fieldsv:
523 * @extension: An #ESourceBackendSummarySetup
524 * @fields: The array of #EContactFields to set indexes for
525 * @types: The array of #EBookIndexTypes defining what types of indexes to create
526 * @n_fields: The number elements in the passed @fields, @rule_types and @rules arrays.
527 *
528 * Defines indexes for quick reference for the given given #EContactFields in the addressbook.
529 *
530 * The same #EContactField may be specified multiple times to create multiple indexes
531 * with different characteristics. If an #E_BOOK_INDEX_PREFIX index is created it will
532 * be used for #E_BOOK_QUERY_BEGINS_WITH queries. An #E_BOOK_INDEX_SUFFIX index
533 * will be constructed efficiently for suffix matching and will be used for
534 * #E_BOOK_QUERY_ENDS_WITH queries. Similar an #E_BOOK_INDEX_PHONE index will optimize
535 * #E_BOOK_QUERY_EQUALS_PHONE_NUMBER searches.
536 *
537 * <note><para>The specified indexed fields must also be a part of the summary, any indexed fields
538 * specified that are not already a part of the summary will be ignored.</para></note>
539 *
540 * Since: 3.8
541 */
542 void
e_source_backend_summary_setup_set_indexed_fieldsv(ESourceBackendSummarySetup * extension,EContactField * fields,EBookIndexType * types,gint n_fields)543 e_source_backend_summary_setup_set_indexed_fieldsv (ESourceBackendSummarySetup *extension,
544 EContactField *fields,
545 EBookIndexType *types,
546 gint n_fields)
547 {
548 GString *string;
549 gboolean malformed = FALSE;
550 gint i;
551
552 g_return_if_fail (E_IS_SOURCE_BACKEND_SUMMARY_SETUP (extension));
553 g_return_if_fail (types != NULL || n_fields <= 0);
554 g_return_if_fail (fields != NULL || n_fields <= 0);
555
556 if (n_fields <= 0) {
557 source_backend_summary_setup_set_literal_fields (extension, NULL, PROP_INDEXED_FIELDS);
558 return;
559 }
560
561 string = g_string_new (NULL);
562
563 for (i = 0; i < n_fields && malformed == FALSE; i++) {
564 const gchar *field;
565 const gchar *type;
566
567 field = e_contact_field_name (fields[i]);
568 type = e_enum_to_string (E_TYPE_BOOK_INDEX_TYPE, types[i]);
569
570 if (!field) {
571 g_warning ("Invalid contact field specified in indexed fields");
572 malformed = TRUE;
573 } else if (!type) {
574 g_warning ("Invalid index type specified in indexed fields");
575 malformed = TRUE;
576 } else {
577 if (i > 0)
578 g_string_append_c (string, ':');
579 g_string_append_printf (string, "%s,%s", field, type);
580 }
581 }
582
583 if (!malformed)
584 source_backend_summary_setup_set_literal_fields (extension, string->str, PROP_INDEXED_FIELDS);
585
586 g_string_free (string, TRUE);
587 }
588
589 /**
590 * e_source_backend_summary_setup_set_indexed_fields:
591 * @extension: An #ESourceBackendSummarySetup
592 * @...: A list of #EContactFields, #EBookIndexType pairs terminated by 0.
593 *
594 * Like e_source_backend_summary_setup_set_indexed_fieldsv(), but takes a literal list of
595 * of indexes.
596 *
597 * To give the 'fullname' field an index for prefix and suffix searches:
598 *
599 * |[
600 * #include <libebook/libebook.h>
601 *
602 * ESourceBackendSummarySetup *extension;
603 *
604 * extension = e_source_get_extension (source, E_SOURCE_EXTENSION_BACKEND_SUMMARY_SETUP);
605 *
606 * e_source_backend_summary_setup_set_indexed_fields (extension,
607 * E_CONTACT_FULL_NAME, E_BOOK_INDEX_PREFIX,
608 * E_CONTACT_FULL_NAME, E_BOOK_INDEX_SUFFIX,
609 * 0);
610 * ]|
611 *
612 * Since: 3.8
613 */
614 void
e_source_backend_summary_setup_set_indexed_fields(ESourceBackendSummarySetup * extension,...)615 e_source_backend_summary_setup_set_indexed_fields (ESourceBackendSummarySetup *extension,
616 ...)
617 {
618 GString *string;
619 gboolean malformed = FALSE, first = TRUE;
620 va_list var_args;
621 EContactField field_in;
622 EBookIndexType type_in;
623
624 g_return_if_fail (E_IS_SOURCE_BACKEND_SUMMARY_SETUP (extension));
625
626 string = g_string_new (NULL);
627
628 va_start (var_args, extension);
629
630 field_in = va_arg (var_args, EContactField);
631 while (field_in > 0 && malformed == FALSE) {
632 const gchar *field;
633 const gchar *type;
634
635 field = e_contact_field_name (field_in);
636 if (field == NULL) {
637 g_warning ("Invalid contact field specified in "
638 "e_source_backend_summary_setup_set_indexed_fields()");
639 malformed = TRUE;
640 break;
641 }
642
643 type_in = va_arg (var_args, EBookIndexType);
644 type = e_enum_to_string (E_TYPE_BOOK_INDEX_TYPE, type_in);
645 if (type == NULL) {
646 g_warning ("Invalid index type "
647 "e_source_backend_summary_setup_set_indexed_fields()");
648 malformed = TRUE;
649 break;
650 }
651
652 if (!first)
653 g_string_append_c (string, ':');
654 else
655 first = FALSE;
656
657 g_string_append_printf (string, "%s,%s", field, type);
658
659 /* Continue loop until first 0 found... */
660 field_in = va_arg (var_args, EContactField);
661 }
662 va_end (var_args);
663
664 if (!malformed)
665 source_backend_summary_setup_set_literal_fields (extension, string->str, PROP_INDEXED_FIELDS);
666
667 g_string_free (string, TRUE);
668 }
669