1 /*
2  * Copyright (C) 2009, Nokia <ivan.frade@nokia.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA  02110-1301, USA.
18  */
19 
20 #include "config.h"
21 
22 #include <string.h>
23 #include <stdlib.h>
24 
25 #include <glib.h>
26 
27 #include <libtracker-sparql/tracker-sparql.h>
28 
29 #include "tracker-namespace.h"
30 #include "tracker-ontologies.h"
31 #include "tracker-property.h"
32 
33 #define XSD_BOOLEAN  TRACKER_PREFIX_XSD "boolean"
34 #define XSD_DATE     TRACKER_PREFIX_XSD "date"
35 #define XSD_DATETIME TRACKER_PREFIX_XSD "dateTime"
36 #define XSD_DOUBLE   TRACKER_PREFIX_XSD "double"
37 #define XSD_INTEGER  TRACKER_PREFIX_XSD "integer"
38 #define XSD_STRING   TRACKER_PREFIX_XSD "string"
39 
40 typedef struct _TrackerPropertyPrivate TrackerPropertyPrivate;
41 
42 struct _TrackerPropertyPrivate {
43 	gchar         *uri;
44 	gchar         *name;
45 	gchar         *table_name;
46 
47 	gboolean       use_gvdb;
48 
49 	TrackerPropertyType  data_type;
50 	TrackerClass   *domain;
51 	TrackerClass   *domain_index;
52 	TrackerClass   *range;
53 	gint           weight;
54 	gint           id;
55 	gboolean       indexed;
56 	TrackerProperty *secondary_index;
57 	gboolean       orig_fulltext_indexed;
58 	gboolean       fulltext_indexed;
59 	gboolean       multiple_values;
60 	gboolean       last_multiple_values;
61 	gboolean       transient;
62 	gboolean       is_inverse_functional_property;
63 	gboolean       is_new;
64 	gboolean       db_schema_changed;
65 	gboolean       writeback;
66 	gchar         *default_value;
67 	GPtrArray     *is_new_domain_index;
68 	gboolean       force_journal;
69 
70 	GArray        *super_properties;
71 	GArray        *domain_indexes;
72 	GArray        *last_super_properties;
73 	gboolean       cardinality_changed;
74 	gboolean       orig_multiple_values;
75 
76 	TrackerOntologies *ontologies;
77 };
78 
79 static void property_finalize     (GObject      *object);
80 
81 GType
tracker_property_type_get_type(void)82 tracker_property_type_get_type (void)
83 {
84 	static GType etype = 0;
85 
86 	if (etype == 0) {
87 		static const GEnumValue values[] = {
88 			{ TRACKER_PROPERTY_TYPE_UNKNOWN,
89 			  "TRACKER_PROPERTY_TYPE_UNKNOWN",
90 			  "unknown" },
91 			{ TRACKER_PROPERTY_TYPE_STRING,
92 			  "TRACKER_PROPERTY_TYPE_STRING",
93 			  "string" },
94 			{ TRACKER_PROPERTY_TYPE_BOOLEAN,
95 			  "TRACKER_PROPERTY_TYPE_BOOLEAN",
96 			  "boolean" },
97 			{ TRACKER_PROPERTY_TYPE_INTEGER,
98 			  "TRACKER_PROPERTY_TYPE_INTEGER",
99 			  "integer" },
100 			{ TRACKER_PROPERTY_TYPE_DOUBLE,
101 			  "TRACKER_PROPERTY_TYPE_DOUBLE",
102 			  "double" },
103 			{ TRACKER_PROPERTY_TYPE_DATE,
104 			  "TRACKER_PROPERTY_TYPE_DATE",
105 			  "date" },
106 			{ TRACKER_PROPERTY_TYPE_DATETIME,
107 			  "TRACKER_PROPERTY_TYPE_DATETIME",
108 			  "datetime" },
109 			{ TRACKER_PROPERTY_TYPE_RESOURCE,
110 			  "TRACKER_PROPERTY_TYPE_RESOURCE",
111 			  "resource" },
112 			{ 0, NULL, NULL }
113 		};
114 
115 		etype = g_enum_register_static ("TrackerPropertyType", values);
116 	}
117 
118 	return etype;
119 }
120 
121 G_DEFINE_TYPE_WITH_PRIVATE (TrackerProperty, tracker_property, G_TYPE_OBJECT);
122 
123 static void
tracker_property_class_init(TrackerPropertyClass * klass)124 tracker_property_class_init (TrackerPropertyClass *klass)
125 {
126 	GObjectClass *object_class = G_OBJECT_CLASS (klass);
127 
128 	object_class->finalize = property_finalize;
129 }
130 
131 static void
tracker_property_init(TrackerProperty * property)132 tracker_property_init (TrackerProperty *property)
133 {
134 	TrackerPropertyPrivate *priv;
135 
136 	priv = tracker_property_get_instance_private (property);
137 
138 	priv->id = 0;
139 	priv->weight = 1;
140 	priv->transient = FALSE;
141 	priv->multiple_values = TRUE;
142 	priv->force_journal = TRUE;
143 	priv->super_properties = g_array_new (TRUE, TRUE, sizeof (TrackerProperty *));
144 	priv->domain_indexes = g_array_new (TRUE, TRUE, sizeof (TrackerClass *));
145 	priv->last_super_properties = NULL;
146 	priv->cardinality_changed = FALSE;
147 }
148 
149 static void
property_finalize(GObject * object)150 property_finalize (GObject *object)
151 {
152 	TrackerPropertyPrivate *priv;
153 
154 	priv = tracker_property_get_instance_private (TRACKER_PROPERTY (object));
155 
156 	g_free (priv->uri);
157 	g_free (priv->name);
158 	g_free (priv->table_name);
159 
160 	if (priv->is_new_domain_index) {
161 		g_ptr_array_unref (priv->is_new_domain_index);
162 	}
163 
164 	if (priv->domain) {
165 		g_object_unref (priv->domain);
166 	}
167 
168 	if (priv->range) {
169 		g_object_unref (priv->range);
170 	}
171 
172 	if (priv->secondary_index) {
173 		g_object_unref (priv->secondary_index);
174 	}
175 
176 	if (priv->last_super_properties) {
177 		g_array_free (priv->last_super_properties, TRUE);
178 	}
179 
180 	g_array_free (priv->super_properties, TRUE);
181 	g_array_free (priv->domain_indexes, TRUE);
182 
183 	g_free (priv->default_value);
184 
185 	(G_OBJECT_CLASS (tracker_property_parent_class)->finalize) (object);
186 }
187 
188 /**
189  * tracker_property_new:
190  *
191  * Creates a new #TrackerProperty instance.
192  *
193  * Returns: The newly created #TrackerProperty
194  **/
195 TrackerProperty *
tracker_property_new(gboolean use_gvdb)196 tracker_property_new (gboolean use_gvdb)
197 {
198 	TrackerProperty *property;
199 	TrackerPropertyPrivate *priv;
200 
201 	property = g_object_new (TRACKER_TYPE_PROPERTY, NULL);
202 
203 	if (use_gvdb) {
204 		priv = tracker_property_get_instance_private (property);
205 		priv->use_gvdb = use_gvdb;
206 	}
207 
208 	return property;
209 }
210 
211 const gchar *
tracker_property_get_uri(TrackerProperty * property)212 tracker_property_get_uri (TrackerProperty *property)
213 {
214 	TrackerPropertyPrivate *priv;
215 
216 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), NULL);
217 
218 	priv = tracker_property_get_instance_private (property);
219 
220 	return priv->uri;
221 }
222 
223 gboolean
tracker_property_get_transient(TrackerProperty * property)224 tracker_property_get_transient (TrackerProperty *property)
225 {
226 	TrackerPropertyPrivate *priv;
227 
228 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), FALSE);
229 
230 	priv = tracker_property_get_instance_private (property);
231 
232 	return priv->transient;
233 }
234 
235 
236 const gchar *
tracker_property_get_name(TrackerProperty * property)237 tracker_property_get_name (TrackerProperty *property)
238 {
239 	TrackerPropertyPrivate *priv;
240 
241 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), NULL);
242 
243 	priv = tracker_property_get_instance_private (property);
244 
245 	return priv->name;
246 }
247 
248 const gchar *
tracker_property_get_table_name(TrackerProperty * property)249 tracker_property_get_table_name (TrackerProperty *property)
250 {
251 	TrackerPropertyPrivate *priv;
252 
253 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), NULL);
254 
255 	priv = tracker_property_get_instance_private (property);
256 
257 	if (!priv->table_name) {
258 		if (tracker_property_get_multiple_values (property)) {
259 			priv->table_name = g_strdup_printf ("%s_%s",
260 				tracker_class_get_name (tracker_property_get_domain (property)),
261 				tracker_property_get_name (property));
262 		} else {
263 			priv->table_name = g_strdup (tracker_class_get_name (tracker_property_get_domain (property)));
264 		}
265 	}
266 
267 	return priv->table_name;
268 }
269 
270 TrackerPropertyType
tracker_property_get_data_type(TrackerProperty * property)271 tracker_property_get_data_type (TrackerProperty *property)
272 {
273 	TrackerPropertyPrivate *priv;
274 
275 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), TRACKER_PROPERTY_TYPE_STRING); //FIXME
276 
277 	priv = tracker_property_get_instance_private (property);
278 
279 	if (priv->use_gvdb) {
280 		const gchar *range_uri;
281 
282 		range_uri = tracker_ontologies_get_property_string_gvdb (priv->ontologies, priv->uri, "range");
283 		if (strcmp (range_uri, XSD_STRING) == 0) {
284 			priv->data_type = TRACKER_PROPERTY_TYPE_STRING;
285 		} else if (strcmp (range_uri, XSD_BOOLEAN) == 0) {
286 			priv->data_type = TRACKER_PROPERTY_TYPE_BOOLEAN;
287 		} else if (strcmp (range_uri, XSD_INTEGER) == 0) {
288 			priv->data_type = TRACKER_PROPERTY_TYPE_INTEGER;
289 		} else if (strcmp (range_uri, XSD_DOUBLE) == 0) {
290 			priv->data_type = TRACKER_PROPERTY_TYPE_DOUBLE;
291 		} else if (strcmp (range_uri, XSD_DATE) == 0) {
292 			priv->data_type = TRACKER_PROPERTY_TYPE_DATE;
293 		} else if (strcmp (range_uri, XSD_DATETIME) == 0) {
294 			priv->data_type = TRACKER_PROPERTY_TYPE_DATETIME;
295 		} else {
296 			priv->data_type = TRACKER_PROPERTY_TYPE_RESOURCE;
297 		}
298 	}
299 
300 	return priv->data_type;
301 }
302 
303 TrackerClass *
tracker_property_get_domain(TrackerProperty * property)304 tracker_property_get_domain (TrackerProperty *property)
305 {
306 	TrackerPropertyPrivate *priv;
307 
308 	/* Removed for performance:
309 	 g_return_val_if_fail (TRACKER_IS_PROPERTY (property), NULL); */
310 
311 	g_return_val_if_fail (property != NULL, NULL);
312 
313 	priv = tracker_property_get_instance_private (property);
314 
315 	if (!priv->domain && priv->use_gvdb) {
316 		const gchar *domain_uri;
317 
318 		domain_uri = tracker_ontologies_get_property_string_gvdb (priv->ontologies, priv->uri, "domain");
319 		priv->domain = g_object_ref (tracker_ontologies_get_class_by_uri (priv->ontologies, domain_uri));
320 	}
321 
322 	return priv->domain;
323 }
324 
325 TrackerClass **
tracker_property_get_domain_indexes(TrackerProperty * property)326 tracker_property_get_domain_indexes (TrackerProperty *property)
327 {
328 	TrackerPropertyPrivate *priv;
329 
330 	/* Removed for performance:
331 	 g_return_val_if_fail (TRACKER_IS_PROPERTY (property), NULL); */
332 
333 	g_return_val_if_fail (property != NULL, NULL);
334 
335 	priv = tracker_property_get_instance_private (property);
336 
337 	if (priv->use_gvdb) {
338 		TrackerClass *domain_index;
339 		GVariant *variant;
340 
341 		tracker_property_reset_domain_indexes (property);
342 
343 		variant = tracker_ontologies_get_property_value_gvdb (priv->ontologies, priv->uri, "domain-indexes");
344 		if (variant) {
345 			GVariantIter iter;
346 			const gchar *uri;
347 
348 			g_variant_iter_init (&iter, variant);
349 			while (g_variant_iter_loop (&iter, "&s", &uri)) {
350 				domain_index = tracker_ontologies_get_class_by_uri (priv->ontologies, uri);
351 
352 				tracker_property_add_domain_index (property, domain_index);
353 			}
354 
355 			g_variant_unref (variant);
356 		}
357 	}
358 
359 	return (TrackerClass ** ) priv->domain_indexes->data;
360 }
361 
362 TrackerProperty **
tracker_property_get_last_super_properties(TrackerProperty * property)363 tracker_property_get_last_super_properties (TrackerProperty *property)
364 {
365 	TrackerPropertyPrivate *priv;
366 
367 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), NULL);
368 	g_return_val_if_fail (property != NULL, NULL);
369 
370 	priv = tracker_property_get_instance_private (property);
371 
372 	return (TrackerProperty **) (priv->last_super_properties ? priv->last_super_properties->data : NULL);
373 }
374 
375 void
tracker_property_reset_super_properties(TrackerProperty * property)376 tracker_property_reset_super_properties (TrackerProperty *property)
377 {
378 	TrackerPropertyPrivate *priv;
379 
380 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
381 
382 	priv = tracker_property_get_instance_private (property);
383 
384 	if (priv->last_super_properties) {
385 		g_array_free (priv->last_super_properties, TRUE);
386 	}
387 
388 	priv->last_super_properties = priv->super_properties;
389 	priv->super_properties = g_array_new (TRUE, TRUE, sizeof (TrackerProperty *));
390 }
391 
392 
393 TrackerClass *
tracker_property_get_range(TrackerProperty * property)394 tracker_property_get_range (TrackerProperty *property)
395 {
396 	TrackerPropertyPrivate *priv;
397 
398 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), NULL);
399 
400 	priv = tracker_property_get_instance_private (property);
401 
402 	if (!priv->range && priv->use_gvdb) {
403 		const gchar *range_uri;
404 
405 		range_uri = tracker_ontologies_get_property_string_gvdb (priv->ontologies, priv->uri, "range");
406 		priv->range = g_object_ref (tracker_ontologies_get_class_by_uri (priv->ontologies, range_uri));
407 	}
408 
409 	return priv->range;
410 }
411 
412 gint
tracker_property_get_weight(TrackerProperty * property)413 tracker_property_get_weight (TrackerProperty *property)
414 {
415 	TrackerPropertyPrivate *priv;
416 
417 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), -1);
418 
419 	priv = tracker_property_get_instance_private (property);
420 
421 	return priv->weight;
422 }
423 
424 gint
tracker_property_get_id(TrackerProperty * property)425 tracker_property_get_id (TrackerProperty *property)
426 {
427 	TrackerPropertyPrivate *priv;
428 
429 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), 0);
430 
431 	priv = tracker_property_get_instance_private (property);
432 
433 	return priv->id;
434 }
435 
436 gboolean
tracker_property_get_indexed(TrackerProperty * property)437 tracker_property_get_indexed (TrackerProperty *property)
438 {
439 	TrackerPropertyPrivate *priv;
440 
441 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), FALSE);
442 
443 	priv = tracker_property_get_instance_private (property);
444 
445 	return priv->indexed;
446 }
447 
448 TrackerProperty *
tracker_property_get_secondary_index(TrackerProperty * property)449 tracker_property_get_secondary_index (TrackerProperty *property)
450 {
451 	TrackerPropertyPrivate *priv;
452 
453 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), NULL);
454 
455 	priv = tracker_property_get_instance_private (property);
456 
457 	return priv->secondary_index;
458 }
459 
460 gboolean
tracker_property_get_fulltext_indexed(TrackerProperty * property)461 tracker_property_get_fulltext_indexed (TrackerProperty *property)
462 {
463 	TrackerPropertyPrivate *priv;
464 
465 	/* Removed for performance:
466 	 g_return_val_if_fail (TRACKER_IS_PROPERTY (property), NULL); */
467 
468 	g_return_val_if_fail (property != NULL, FALSE);
469 
470 	priv = tracker_property_get_instance_private (property);
471 
472 	if (priv->use_gvdb) {
473 		GVariant *value;
474 		gboolean result;
475 
476 		value = tracker_ontologies_get_property_value_gvdb (priv->ontologies, priv->uri, "fulltext-indexed");
477 		if (value != NULL) {
478 			result = g_variant_get_boolean (value);
479 			g_variant_unref (value);
480 		} else {
481 			result = FALSE;
482 		}
483 
484 		return result;
485 	}
486 
487 	return priv->fulltext_indexed;
488 }
489 
490 gboolean
tracker_property_get_orig_fulltext_indexed(TrackerProperty * property)491 tracker_property_get_orig_fulltext_indexed (TrackerProperty *property)
492 {
493 	TrackerPropertyPrivate *priv;
494 
495 	g_return_val_if_fail (property != NULL, FALSE);
496 
497 	priv = tracker_property_get_instance_private (property);
498 
499 	return priv->orig_fulltext_indexed;
500 }
501 
502 gboolean
tracker_property_get_is_new(TrackerProperty * property)503 tracker_property_get_is_new (TrackerProperty *property)
504 {
505 	TrackerPropertyPrivate *priv;
506 
507 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), FALSE);
508 
509 	priv = tracker_property_get_instance_private (property);
510 
511 	return priv->is_new;
512 }
513 
514 gboolean
tracker_property_get_is_new_domain_index(TrackerProperty * property,TrackerClass * class)515 tracker_property_get_is_new_domain_index (TrackerProperty *property,
516                                           TrackerClass    *class)
517 {
518 	TrackerPropertyPrivate *priv;
519 	guint i;
520 
521 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), FALSE);
522 	g_return_val_if_fail (TRACKER_IS_CLASS (class), FALSE);
523 
524 	priv = tracker_property_get_instance_private (property);
525 
526 	if (!priv->is_new_domain_index) {
527 		return FALSE;
528 	}
529 
530 	for (i = 0; i < priv->is_new_domain_index->len; i++) {
531 		if (g_ptr_array_index (priv->is_new_domain_index, i) == class) {
532 			return TRUE;
533 		}
534 	}
535 
536 	return FALSE;
537 }
538 
539 gboolean
tracker_property_get_writeback(TrackerProperty * property)540 tracker_property_get_writeback (TrackerProperty *property)
541 {
542 	TrackerPropertyPrivate *priv;
543 
544 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), FALSE);
545 
546 	priv = tracker_property_get_instance_private (property);
547 
548 	return priv->writeback;
549 }
550 
551 gboolean
tracker_property_get_db_schema_changed(TrackerProperty * property)552 tracker_property_get_db_schema_changed (TrackerProperty *property)
553 {
554 	TrackerPropertyPrivate *priv;
555 
556 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), FALSE);
557 
558 	priv = tracker_property_get_instance_private (property);
559 
560 	return priv->db_schema_changed;
561 }
562 
563 gboolean
tracker_property_get_cardinality_changed(TrackerProperty * property)564 tracker_property_get_cardinality_changed (TrackerProperty *property)
565 {
566 	TrackerPropertyPrivate *priv;
567 
568 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), FALSE);
569 
570 	priv = tracker_property_get_instance_private (property);
571 
572 	return priv->cardinality_changed;
573 }
574 
575 gboolean
tracker_property_get_multiple_values(TrackerProperty * property)576 tracker_property_get_multiple_values (TrackerProperty *property)
577 {
578 	TrackerPropertyPrivate *priv;
579 
580 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), FALSE);
581 
582 	priv = tracker_property_get_instance_private (property);
583 
584 	if (priv->use_gvdb) {
585 		GVariant *value;
586 		gboolean result;
587 
588 		value = tracker_ontologies_get_property_value_gvdb (priv->ontologies, priv->uri, "max-cardinality");
589 		if (value != NULL) {
590 			result = FALSE;
591 			g_variant_unref (value);
592 		} else {
593 			result = TRUE;
594 		}
595 
596 		return result;
597 	}
598 
599 	return priv->multiple_values;
600 }
601 
602 gboolean
tracker_property_get_last_multiple_values(TrackerProperty * property)603 tracker_property_get_last_multiple_values (TrackerProperty *property)
604 {
605 	TrackerPropertyPrivate *priv;
606 
607 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), FALSE);
608 
609 	priv = tracker_property_get_instance_private (property);
610 
611 	return priv->last_multiple_values;
612 }
613 
614 gboolean
tracker_property_get_orig_multiple_values(TrackerProperty * property)615 tracker_property_get_orig_multiple_values (TrackerProperty *property)
616 {
617 	TrackerPropertyPrivate *priv;
618 
619 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), FALSE);
620 
621 	priv = tracker_property_get_instance_private (property);
622 
623 	return priv->orig_multiple_values;
624 }
625 
626 gboolean
tracker_property_get_is_inverse_functional_property(TrackerProperty * property)627 tracker_property_get_is_inverse_functional_property (TrackerProperty *property)
628 {
629 	TrackerPropertyPrivate *priv;
630 
631 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), FALSE);
632 
633 	priv = tracker_property_get_instance_private (property);
634 
635 	if (priv->use_gvdb) {
636 		GVariant *value;
637 		gboolean result;
638 
639 		value = tracker_ontologies_get_property_value_gvdb (priv->ontologies, priv->uri, "inverse-functional");
640 		if (value != NULL) {
641 			result = g_variant_get_boolean (value);
642 			g_variant_unref (value);
643 		} else {
644 			result = FALSE;
645 		}
646 
647 		return result;
648 	}
649 
650 	return priv->is_inverse_functional_property;
651 }
652 
653 gboolean
tracker_property_get_force_journal(TrackerProperty * property)654 tracker_property_get_force_journal (TrackerProperty *property)
655 {
656 	TrackerPropertyPrivate *priv;
657 
658 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), FALSE);
659 
660 	priv = tracker_property_get_instance_private (property);
661 
662 	return priv->force_journal;
663 }
664 
665 TrackerProperty **
tracker_property_get_super_properties(TrackerProperty * property)666 tracker_property_get_super_properties (TrackerProperty *property)
667 {
668 	TrackerPropertyPrivate *priv;
669 
670 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), NULL);
671 
672 	priv = tracker_property_get_instance_private (property);
673 
674 	return (TrackerProperty **) priv->super_properties->data;
675 }
676 
677 const gchar *
tracker_property_get_default_value(TrackerProperty * property)678 tracker_property_get_default_value (TrackerProperty *property)
679 {
680 	TrackerPropertyPrivate *priv;
681 
682 	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), NULL);
683 
684 	priv = tracker_property_get_instance_private (property);
685 
686 	return priv->default_value;
687 }
688 
689 void
tracker_property_set_uri(TrackerProperty * property,const gchar * value)690 tracker_property_set_uri (TrackerProperty *property,
691                           const gchar     *value)
692 {
693 	TrackerPropertyPrivate *priv;
694 
695 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
696 
697 	priv = tracker_property_get_instance_private (property);
698 
699 	g_free (priv->uri);
700 	g_free (priv->name);
701 	priv->uri = NULL;
702 	priv->name = NULL;
703 
704 	if (value) {
705 		TrackerNamespace *namespace;
706 		gchar *namespace_uri, *hash;
707 
708 		priv->uri = g_strdup (value);
709 
710 		hash = strrchr (priv->uri, '#');
711 		if (hash == NULL) {
712 			/* support ontologies whose namespace uri does not end in a hash, e.g. dc */
713 			hash = strrchr (priv->uri, '/');
714 		}
715 		if (hash == NULL) {
716 			g_critical ("Unknown namespace of property %s", priv->uri);
717 		} else {
718 			namespace_uri = g_strndup (priv->uri, hash - priv->uri + 1);
719 			namespace = tracker_ontologies_get_namespace_by_uri (priv->ontologies, namespace_uri);
720 			if (namespace == NULL) {
721 				g_critical ("Unknown namespace %s of property %s", namespace_uri, priv->uri);
722 			} else {
723 				priv->name = g_strdup_printf ("%s:%s", tracker_namespace_get_prefix (namespace), hash + 1);
724 			}
725 			g_free (namespace_uri);
726 		}
727 	}
728 }
729 
730 void
tracker_property_set_transient(TrackerProperty * property,gboolean value)731 tracker_property_set_transient (TrackerProperty *property,
732                                 gboolean         value)
733 {
734 	TrackerPropertyPrivate *priv;
735 
736 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
737 
738 	priv = tracker_property_get_instance_private (property);
739 
740 	priv->transient = value;
741 }
742 
743 void
tracker_property_set_domain(TrackerProperty * property,TrackerClass * value)744 tracker_property_set_domain (TrackerProperty *property,
745                              TrackerClass    *value)
746 {
747 	TrackerPropertyPrivate *priv;
748 
749 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
750 
751 	priv = tracker_property_get_instance_private (property);
752 
753 	if (priv->domain) {
754 		g_object_unref (priv->domain);
755 		priv->domain = NULL;
756 	}
757 
758 	if (value) {
759 		priv->domain = g_object_ref (value);
760 	}
761 }
762 
763 void
tracker_property_add_domain_index(TrackerProperty * property,TrackerClass * value)764 tracker_property_add_domain_index (TrackerProperty *property,
765                                    TrackerClass    *value)
766 {
767 	TrackerPropertyPrivate *priv;
768 
769 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
770 	g_return_if_fail (TRACKER_IS_CLASS (value));
771 
772 	priv = tracker_property_get_instance_private (property);
773 
774 	g_array_append_val (priv->domain_indexes, value);
775 }
776 
777 void
tracker_property_del_domain_index(TrackerProperty * property,TrackerClass * value)778 tracker_property_del_domain_index (TrackerProperty *property,
779                                    TrackerClass    *value)
780 {
781 	TrackerClass **classes;
782 	TrackerPropertyPrivate *priv;
783 	gint i = 0, found = -1;
784 
785 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
786 	g_return_if_fail (TRACKER_IS_CLASS (value));
787 
788 	priv = tracker_property_get_instance_private (property);
789 
790 	classes = (TrackerClass **) priv->domain_indexes->data;
791 	while (*classes) {
792 		if (*classes == value) {
793 			found = i;
794 			break;
795 		}
796 		i++;
797 		classes++;
798 	}
799 
800 	if (found != -1) {
801 		g_array_remove_index (priv->domain_indexes, found);
802 	}
803 }
804 
805 void
tracker_property_reset_domain_indexes(TrackerProperty * property)806 tracker_property_reset_domain_indexes (TrackerProperty *property)
807 {
808 	TrackerPropertyPrivate *priv;
809 
810 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
811 
812 	priv = tracker_property_get_instance_private (property);
813 	g_array_free (priv->domain_indexes, TRUE);
814 	priv->domain_indexes = g_array_new (TRUE, TRUE, sizeof (TrackerClass *));
815 }
816 
817 void
tracker_property_set_secondary_index(TrackerProperty * property,TrackerProperty * value)818 tracker_property_set_secondary_index (TrackerProperty *property,
819                                       TrackerProperty *value)
820 {
821 	TrackerPropertyPrivate *priv;
822 
823 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
824 
825 	priv = tracker_property_get_instance_private (property);
826 
827 	if (priv->secondary_index) {
828 		g_object_unref (priv->secondary_index);
829 		priv->secondary_index = NULL;
830 	}
831 
832 	if (value) {
833 		priv->secondary_index = g_object_ref (value);
834 	}
835 }
836 
837 void
tracker_property_set_range(TrackerProperty * property,TrackerClass * value)838 tracker_property_set_range (TrackerProperty *property,
839                             TrackerClass     *value)
840 {
841 	TrackerPropertyPrivate *priv;
842 	const gchar *range_uri;
843 
844 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
845 	g_return_if_fail (TRACKER_IS_CLASS (value));
846 
847 	priv = tracker_property_get_instance_private (property);
848 
849 	if (priv->range) {
850 		g_object_unref (priv->range);
851 	}
852 
853 	priv->range = g_object_ref (value);
854 
855 	range_uri = tracker_class_get_uri (priv->range);
856 	if (strcmp (range_uri, XSD_STRING) == 0) {
857 		priv->data_type = TRACKER_PROPERTY_TYPE_STRING;
858 	} else if (strcmp (range_uri, XSD_BOOLEAN) == 0) {
859 		priv->data_type = TRACKER_PROPERTY_TYPE_BOOLEAN;
860 	} else if (strcmp (range_uri, XSD_INTEGER) == 0) {
861 		priv->data_type = TRACKER_PROPERTY_TYPE_INTEGER;
862 	} else if (strcmp (range_uri, XSD_DOUBLE) == 0) {
863 		priv->data_type = TRACKER_PROPERTY_TYPE_DOUBLE;
864 	} else if (strcmp (range_uri, XSD_DATE) == 0) {
865 		priv->data_type = TRACKER_PROPERTY_TYPE_DATE;
866 	} else if (strcmp (range_uri, XSD_DATETIME) == 0) {
867 		priv->data_type = TRACKER_PROPERTY_TYPE_DATETIME;
868 	} else {
869 		priv->data_type = TRACKER_PROPERTY_TYPE_RESOURCE;
870 	}
871 }
872 
873 void
tracker_property_set_weight(TrackerProperty * property,gint value)874 tracker_property_set_weight (TrackerProperty *property,
875                              gint             value)
876 {
877 	TrackerPropertyPrivate *priv;
878 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
879 
880 	priv = tracker_property_get_instance_private (property);
881 
882 	priv->weight = value;
883 }
884 
885 
886 void
tracker_property_set_id(TrackerProperty * property,gint value)887 tracker_property_set_id (TrackerProperty *property,
888                          gint             value)
889 {
890 	TrackerPropertyPrivate *priv;
891 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
892 
893 	priv = tracker_property_get_instance_private (property);
894 
895 	priv->id = value;
896 }
897 
898 void
tracker_property_set_indexed(TrackerProperty * property,gboolean value)899 tracker_property_set_indexed (TrackerProperty *property,
900                               gboolean         value)
901 {
902 	TrackerPropertyPrivate *priv;
903 
904 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
905 
906 	priv = tracker_property_get_instance_private (property);
907 
908 	priv->indexed = value;
909 }
910 
911 void
tracker_property_set_is_new(TrackerProperty * property,gboolean value)912 tracker_property_set_is_new (TrackerProperty *property,
913                              gboolean         value)
914 {
915 	TrackerPropertyPrivate *priv;
916 
917 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
918 
919 	priv = tracker_property_get_instance_private (property);
920 
921 	priv->is_new = value;
922 }
923 
924 void
tracker_property_set_is_new_domain_index(TrackerProperty * property,TrackerClass * class,gboolean value)925 tracker_property_set_is_new_domain_index (TrackerProperty *property,
926                                           TrackerClass    *class,
927                                           gboolean         value)
928 {
929 	TrackerPropertyPrivate *priv;
930 
931 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
932 
933 	if (class) {
934 		g_return_if_fail (TRACKER_IS_CLASS (class));
935 	}
936 
937 	priv = tracker_property_get_instance_private (property);
938 
939 	if (value) {
940 		if (!priv->is_new_domain_index) {
941 			priv->is_new_domain_index = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
942 		}
943 		g_ptr_array_add (priv->is_new_domain_index, g_object_ref (class));
944 	} else {
945 		guint i;
946 		gboolean found = FALSE;
947 
948 		if (!priv->is_new_domain_index) {
949 			return;
950 		}
951 
952 		if (!class) {
953 			g_ptr_array_unref (priv->is_new_domain_index);
954 			priv->is_new_domain_index = NULL;
955 			return;
956 		}
957 
958 		for (i = 0; i < priv->is_new_domain_index->len; i++) {
959 			if (g_ptr_array_index (priv->is_new_domain_index, i) == class) {
960 				found = TRUE;
961 				break;
962 			}
963 		}
964 
965 		if (found) {
966 			g_ptr_array_remove_index (priv->is_new_domain_index, i);
967 		}
968 	}
969 }
970 
971 void
tracker_property_set_writeback(TrackerProperty * property,gboolean value)972 tracker_property_set_writeback (TrackerProperty *property,
973                                 gboolean         value)
974 {
975 	TrackerPropertyPrivate *priv;
976 
977 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
978 
979 	priv = tracker_property_get_instance_private (property);
980 
981 	priv->writeback = value;
982 }
983 
984 void
tracker_property_set_db_schema_changed(TrackerProperty * property,gboolean value)985 tracker_property_set_db_schema_changed (TrackerProperty *property,
986                                         gboolean         value)
987 {
988 	TrackerPropertyPrivate *priv;
989 
990 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
991 
992 	priv = tracker_property_get_instance_private (property);
993 
994 	priv->db_schema_changed = value;
995 }
996 
997 void
tracker_property_set_cardinality_changed(TrackerProperty * property,gboolean value)998 tracker_property_set_cardinality_changed (TrackerProperty *property,
999                                           gboolean         value)
1000 {
1001 	TrackerPropertyPrivate *priv;
1002 
1003 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
1004 
1005 	priv = tracker_property_get_instance_private (property);
1006 
1007 	priv->cardinality_changed = value;
1008 }
1009 
1010 void
tracker_property_set_orig_fulltext_indexed(TrackerProperty * property,gboolean value)1011 tracker_property_set_orig_fulltext_indexed (TrackerProperty *property,
1012                                             gboolean         value)
1013 {
1014 	TrackerPropertyPrivate *priv;
1015 
1016 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
1017 
1018 	priv = tracker_property_get_instance_private (property);
1019 
1020 	priv->orig_fulltext_indexed = value;
1021 }
1022 
1023 void
tracker_property_set_fulltext_indexed(TrackerProperty * property,gboolean value)1024 tracker_property_set_fulltext_indexed (TrackerProperty *property,
1025                                        gboolean         value)
1026 {
1027 	TrackerPropertyPrivate *priv;
1028 
1029 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
1030 
1031 	priv = tracker_property_get_instance_private (property);
1032 
1033 	priv->fulltext_indexed = value;
1034 }
1035 
1036 void
tracker_property_set_multiple_values(TrackerProperty * property,gboolean value)1037 tracker_property_set_multiple_values (TrackerProperty *property,
1038                                       gboolean         value)
1039 {
1040 	TrackerPropertyPrivate *priv;
1041 
1042 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
1043 
1044 	priv = tracker_property_get_instance_private (property);
1045 
1046 	priv->multiple_values = value;
1047 	g_clear_pointer (&priv->table_name, g_free);
1048 }
1049 
1050 void
tracker_property_set_last_multiple_values(TrackerProperty * property,gboolean value)1051 tracker_property_set_last_multiple_values (TrackerProperty *property,
1052                                            gboolean         value)
1053 {
1054 	TrackerPropertyPrivate *priv;
1055 
1056 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
1057 
1058 	priv = tracker_property_get_instance_private (property);
1059 
1060 	priv->last_multiple_values = value;
1061 }
1062 
1063 void
tracker_property_set_orig_multiple_values(TrackerProperty * property,gboolean value)1064 tracker_property_set_orig_multiple_values (TrackerProperty *property,
1065                                            gboolean         value)
1066 {
1067 	TrackerPropertyPrivate *priv;
1068 
1069 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
1070 
1071 	priv = tracker_property_get_instance_private (property);
1072 
1073 	priv->orig_multiple_values = value;
1074 }
1075 
1076 
1077 void
tracker_property_set_is_inverse_functional_property(TrackerProperty * property,gboolean value)1078 tracker_property_set_is_inverse_functional_property (TrackerProperty *property,
1079                                                      gboolean         value)
1080 {
1081 	TrackerPropertyPrivate *priv;
1082 
1083 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
1084 
1085 	priv = tracker_property_get_instance_private (property);
1086 
1087 	priv->is_inverse_functional_property = value;
1088 }
1089 
1090 void
tracker_property_set_force_journal(TrackerProperty * property,gboolean value)1091 tracker_property_set_force_journal (TrackerProperty *property,
1092                                     gboolean         value)
1093 {
1094 	TrackerPropertyPrivate *priv;
1095 
1096 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
1097 
1098 	priv = tracker_property_get_instance_private (property);
1099 
1100 	priv->force_journal = value;
1101 }
1102 
1103 void
tracker_property_add_super_property(TrackerProperty * property,TrackerProperty * value)1104 tracker_property_add_super_property (TrackerProperty *property,
1105                                      TrackerProperty *value)
1106 {
1107 	TrackerPropertyPrivate *priv;
1108 
1109 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
1110 	g_return_if_fail (TRACKER_IS_PROPERTY (value));
1111 
1112 	priv = tracker_property_get_instance_private (property);
1113 
1114 	g_array_append_val (priv->super_properties, value);
1115 }
1116 
1117 void
tracker_property_del_super_property(TrackerProperty * property,TrackerProperty * value)1118 tracker_property_del_super_property (TrackerProperty *property,
1119                                      TrackerProperty *value)
1120 {
1121 	TrackerPropertyPrivate *priv;
1122 	guint i;
1123 
1124 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
1125 	g_return_if_fail (TRACKER_IS_PROPERTY (value));
1126 
1127 	priv = tracker_property_get_instance_private (property);
1128 
1129 	for (i = 0; priv->super_properties->len; i++) {
1130 		TrackerProperty *c_value = g_array_index (priv->super_properties, TrackerProperty*, i);
1131 
1132 		if (c_value == value) {
1133 			priv->super_properties = g_array_remove_index (priv->super_properties, i);
1134 			return;
1135 		}
1136 	}
1137 }
1138 
1139 void
tracker_property_set_default_value(TrackerProperty * property,const gchar * value)1140 tracker_property_set_default_value (TrackerProperty *property,
1141                                     const gchar     *value)
1142 {
1143 	TrackerPropertyPrivate *priv;
1144 
1145 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
1146 
1147 	priv = tracker_property_get_instance_private (property);
1148 
1149 	g_free (priv->default_value);
1150 	priv->default_value = g_strdup (value);
1151 }
1152 
1153 void
tracker_property_set_ontologies(TrackerProperty * property,TrackerOntologies * ontologies)1154 tracker_property_set_ontologies (TrackerProperty   *property,
1155                                  TrackerOntologies *ontologies)
1156 {
1157 	TrackerPropertyPrivate *priv;
1158 
1159 	g_return_if_fail (TRACKER_IS_PROPERTY (property));
1160 	g_return_if_fail (ontologies != NULL);
1161 	priv = tracker_property_get_instance_private (property);
1162 
1163 	priv->ontologies = ontologies;
1164 }
1165