Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GDAL
4 : * Purpose: Represent table relationships
5 : * Author: Nyall Dawson, <nyall dot dawson at gmail dot com>
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 2022, Nyall Dawson <nyall dot dawson at gmail dot comg>
9 : *
10 : * SPDX-License-Identifier: MIT
11 : ****************************************************************************/
12 :
13 : #include "cpl_port.h"
14 : #include "gdal.h"
15 : #include "gdal_priv.h"
16 :
17 : /**
18 : * \class GDALRelationship
19 : *
20 : * Definition of a table relationship.
21 : *
22 : * GDALRelationship describes the relationship between two tables, including
23 : * properties such as the cardinality of the relationship and the participating
24 : * tables.
25 : *
26 : * Not all relationship properties are supported by all data formats.
27 : *
28 : * @since GDAL 3.6
29 : */
30 :
31 : /************************************************************************/
32 : /* GDALRelationshipCreate() */
33 : /************************************************************************/
34 :
35 : /**
36 : * \brief Creates a new relationship.
37 : *
38 : * This function is the same as the C++ method
39 : * GDALRelationship::GDALRelationship()
40 : *
41 : * @param pszName relationship name
42 : * @param pszLeftTableName left table name
43 : * @param pszRightTableName right table name
44 : * @param eCardinality cardinality of relationship
45 : *
46 : * @return a new handle that should be freed with GDALDestroyRelationship(),
47 : * or NULL in case of error.
48 : */
49 : GDALRelationshipH
50 29 : GDALRelationshipCreate(const char *pszName, const char *pszLeftTableName,
51 : const char *pszRightTableName,
52 : GDALRelationshipCardinality eCardinality)
53 : {
54 29 : VALIDATE_POINTER1(pszName, __func__, nullptr);
55 29 : VALIDATE_POINTER1(pszLeftTableName, __func__, nullptr);
56 29 : VALIDATE_POINTER1(pszRightTableName, __func__, nullptr);
57 :
58 87 : return GDALRelationship::ToHandle(new GDALRelationship(
59 58 : pszName, pszLeftTableName, pszRightTableName, eCardinality));
60 : }
61 :
62 : /************************************************************************/
63 : /* GDALDestroyRelationship() */
64 : /************************************************************************/
65 :
66 : /**
67 : * \brief Destroys a relationship.
68 : *
69 : * This function is the same as the C++ method
70 : * GDALRelationship::~GDALRelationship()
71 : */
72 29 : void CPL_STDCALL GDALDestroyRelationship(GDALRelationshipH hRelationship)
73 : {
74 29 : if (hRelationship != nullptr)
75 29 : delete GDALRelationship::FromHandle(hRelationship);
76 29 : }
77 :
78 : /************************************************************************/
79 : /* GDALRelationshipGetName() */
80 : /************************************************************************/
81 :
82 : /**
83 : * \brief Get the name of the relationship.
84 : *
85 : * This function is the same as the C++ method
86 : * GDALRelationship::GetName().
87 : *
88 : * @return name.
89 : */
90 31 : const char *GDALRelationshipGetName(GDALRelationshipH hRelationship)
91 : {
92 31 : VALIDATE_POINTER1(hRelationship, "GDALRelationshipGetName", nullptr);
93 :
94 31 : return GDALRelationship::FromHandle(hRelationship)->GetName().c_str();
95 : }
96 :
97 : /************************************************************************/
98 : /* GDALRelationshipGetCardinality() */
99 : /************************************************************************/
100 :
101 : /**
102 : * \brief Get the cardinality of the relationship.
103 : *
104 : * This function is the same as the C++ method
105 : * GDALRelationship::GetCardinality().
106 : *
107 : * @return cardinality.
108 : */
109 : GDALRelationshipCardinality
110 47 : GDALRelationshipGetCardinality(GDALRelationshipH hRelationship)
111 : {
112 47 : return GDALRelationship::FromHandle(hRelationship)->GetCardinality();
113 : }
114 :
115 : /************************************************************************/
116 : /* GDALRelationshipGetLeftTableName() */
117 : /************************************************************************/
118 :
119 : /**
120 : * \brief Get the name of the left (or base/origin) table in the relationship.
121 : *
122 : * This function is the same as the C++ method
123 : * GDALRelationship::GetLeftTableName().
124 : *
125 : * @return left table name.
126 : */
127 47 : const char *GDALRelationshipGetLeftTableName(GDALRelationshipH hRelationship)
128 : {
129 47 : VALIDATE_POINTER1(hRelationship, "GDALRelationshipGetLeftTableName",
130 : nullptr);
131 :
132 : return GDALRelationship::FromHandle(hRelationship)
133 47 : ->GetLeftTableName()
134 47 : .c_str();
135 : }
136 :
137 : /************************************************************************/
138 : /* GDALRelationshipGetRightTableName() */
139 : /************************************************************************/
140 :
141 : /**
142 : * \brief Get the name of the right (or related/destination) table in the
143 : * relationship.
144 : *
145 : * This function is the same as the C++ method
146 : * GDALRelationship::GetRightTableName().
147 : *
148 : * @return right table name.
149 : */
150 47 : const char *GDALRelationshipGetRightTableName(GDALRelationshipH hRelationship)
151 : {
152 47 : VALIDATE_POINTER1(hRelationship, "GDALRelationshipGetRightTableName",
153 : nullptr);
154 :
155 : return GDALRelationship::FromHandle(hRelationship)
156 47 : ->GetRightTableName()
157 47 : .c_str();
158 : }
159 :
160 : /************************************************************************/
161 : /* GDALRelationshipGetMappingTableName() */
162 : /************************************************************************/
163 :
164 : /**
165 : * \brief Get the name of the mapping table for many-to-many relationships.
166 : *
167 : * This function is the same as the C++ method
168 : * GDALRelationship::GetMappingTableName().
169 : *
170 : * @return mapping table name.
171 : *
172 : * @see GDALRelationshipSetMappingTableName
173 : */
174 32 : const char *GDALRelationshipGetMappingTableName(GDALRelationshipH hRelationship)
175 : {
176 32 : VALIDATE_POINTER1(hRelationship, "GDALRelationshipGetMappingTableName",
177 : nullptr);
178 :
179 : return GDALRelationship::FromHandle(hRelationship)
180 32 : ->GetMappingTableName()
181 32 : .c_str();
182 : }
183 :
184 : /************************************************************************/
185 : /* GDALRelationshipSetMappingTableName() */
186 : /************************************************************************/
187 : /**
188 : * \brief Sets the name of the mapping table for many-to-many relationships.
189 : *
190 : * This function is the same as the CPP method
191 : * GDALRelationship::SetMappingTableName().
192 : *
193 : * @param hRelationship handle to the relationship to apply the new mapping name
194 : * to.
195 : * @param pszName the mapping table name to set.
196 : *
197 : * @see GDALRelationshipGetMappingTableName
198 : */
199 14 : void GDALRelationshipSetMappingTableName(GDALRelationshipH hRelationship,
200 : const char *pszName)
201 :
202 : {
203 14 : GDALRelationship::FromHandle(hRelationship)->SetMappingTableName(pszName);
204 14 : }
205 :
206 : /************************************************************************/
207 : /* GDALRelationshipGetLeftTableFields() */
208 : /************************************************************************/
209 :
210 : /**
211 : * \brief Get the names of the participating fields from the left table in the
212 : * relationship.
213 : *
214 : * This function is the same as the C++ method
215 : * GDALRelationship::GetLeftTableFields().
216 : *
217 : * @return the field names, to be freed with CSLDestroy()
218 : *
219 : * @see GDALRelationshipGetRightTableFields
220 : * @see GDALRelationshipSetLeftTableFields
221 : */
222 48 : char **GDALRelationshipGetLeftTableFields(GDALRelationshipH hRelationship)
223 : {
224 48 : VALIDATE_POINTER1(hRelationship, "GDALRelationshipGetLeftTableFields",
225 : nullptr);
226 :
227 : const auto &fields =
228 48 : GDALRelationship::FromHandle(hRelationship)->GetLeftTableFields();
229 48 : return CPLStringList(fields).StealList();
230 : }
231 :
232 : /************************************************************************/
233 : /* GDALRelationshipGetRightTableFields() */
234 : /************************************************************************/
235 :
236 : /**
237 : * \brief Get the names of the participating fields from the right table in the
238 : * relationship.
239 : *
240 : * This function is the same as the C++ method
241 : * GDALRelationship::GetRightTableFields().
242 : *
243 : * @return the field names, to be freed with CSLDestroy()
244 : *
245 : * @see GDALRelationshipGetLeftTableFields
246 : * @see GDALRelationshipSetRightTableFields
247 : */
248 48 : char **GDALRelationshipGetRightTableFields(GDALRelationshipH hRelationship)
249 : {
250 48 : VALIDATE_POINTER1(hRelationship, "GDALRelationshipGetRightTableFields",
251 : nullptr);
252 :
253 : const auto &fields =
254 48 : GDALRelationship::FromHandle(hRelationship)->GetRightTableFields();
255 48 : return CPLStringList(fields).StealList();
256 : }
257 :
258 : /************************************************************************/
259 : /* GDALRelationshipSetLeftTableFields() */
260 : /************************************************************************/
261 :
262 : /**
263 : * \brief Sets the names of the participating fields from the left table in the
264 : * relationship.
265 : *
266 : * This function is the same as the C++ method
267 : * GDALRelationship::GetLeftTableFields().
268 : *
269 : * @param hRelationship handle to the relationship to apply the left table
270 : * fields to.
271 : * @param papszFields the names of the fields.
272 : *
273 : * @see GDALRelationshipGetLeftTableFields
274 : * @see GDALRelationshipSetRightTableFields
275 : */
276 37 : void GDALRelationshipSetLeftTableFields(GDALRelationshipH hRelationship,
277 : CSLConstList papszFields)
278 : {
279 : GDALRelationship::FromHandle(hRelationship)
280 37 : ->SetLeftTableFields(cpl::ToVector(papszFields));
281 37 : }
282 :
283 : /************************************************************************/
284 : /* GDALRelationshipSetRightTableFields() */
285 : /************************************************************************/
286 :
287 : /**
288 : * \brief Sets the names of the participating fields from the right table in the
289 : * relationship.
290 : *
291 : * This function is the same as the C++ method
292 : * GDALRelationship::SetRightTableFields().
293 : *
294 : * @param hRelationship handle to the relationship to apply the right table
295 : * fields to.
296 : * @param papszFields the names of the fields.
297 : *
298 : * @see GDALRelationshipGetRightTableFields
299 : * @see GDALRelationshipSetLeftTableFields
300 : */
301 38 : void GDALRelationshipSetRightTableFields(GDALRelationshipH hRelationship,
302 : CSLConstList papszFields)
303 : {
304 : GDALRelationship::FromHandle(hRelationship)
305 38 : ->SetRightTableFields(cpl::ToVector(papszFields));
306 38 : }
307 :
308 : /************************************************************************/
309 : /* GDALRelationshipGetLeftMappingTableFields() */
310 : /************************************************************************/
311 :
312 : /**
313 : * \brief Get the names of the mapping table fields which correspond to the
314 : * participating fields from the left table in the relationship.
315 : *
316 : * This function is the same as the C++ method
317 : * GDALRelationship::GetLeftMappingTableFields().
318 : *
319 : * @return the field names, to be freed with CSLDestroy()
320 : *
321 : * @see GDALRelationshipGetRightMappingTableFields
322 : * @see GDALRelationshipSetLeftMappingTableFields
323 : */
324 : char **
325 23 : GDALRelationshipGetLeftMappingTableFields(GDALRelationshipH hRelationship)
326 : {
327 23 : VALIDATE_POINTER1(hRelationship,
328 : "GDALRelationshipGetLeftMappingTableFields", nullptr);
329 :
330 : const auto &fields = GDALRelationship::FromHandle(hRelationship)
331 23 : ->GetLeftMappingTableFields();
332 23 : return CPLStringList(fields).StealList();
333 : }
334 :
335 : /************************************************************************/
336 : /* GDALRelationshipGetRightMappingTableFields() */
337 : /************************************************************************/
338 :
339 : /**
340 : * \brief Get the names of the mapping table fields which correspond to the
341 : * participating fields from the right table in the relationship.
342 : *
343 : * This function is the same as the C++ method
344 : * GDALRelationship::GetRightMappingTableFields().
345 : *
346 : * @return the field names, to be freed with CSLDestroy()
347 : *
348 : * @see GDALRelationshipGetLeftMappingTableFields
349 : * @see GDALRelationshipSetRightMappingTableFields
350 : */
351 : char **
352 23 : GDALRelationshipGetRightMappingTableFields(GDALRelationshipH hRelationship)
353 : {
354 23 : VALIDATE_POINTER1(hRelationship,
355 : "GDALRelationshipGetRightMappingTableFields", nullptr);
356 :
357 : const auto &fields = GDALRelationship::FromHandle(hRelationship)
358 23 : ->GetRightMappingTableFields();
359 23 : return CPLStringList(fields).StealList();
360 : }
361 :
362 : /************************************************************************/
363 : /* GDALRelationshipSetLeftMappingTableFields() */
364 : /************************************************************************/
365 :
366 : /**
367 : * \brief Sets the names of the mapping table fields which correspond to the
368 : * participating fields from the left table in the relationship.
369 : *
370 : * This function is the same as the C++ method
371 : * GDALRelationship::SetLeftMappingTableFields().
372 : *
373 : * @param hRelationship handle to the relationship to apply the left table
374 : * fields to.
375 : * @param papszFields the names of the fields.
376 : *
377 : * @see GDALRelationshipGetLeftMappingTableFields
378 : * @see GDALRelationshipSetRightMappingTableFields
379 : */
380 9 : void GDALRelationshipSetLeftMappingTableFields(GDALRelationshipH hRelationship,
381 : CSLConstList papszFields)
382 : {
383 : GDALRelationship::FromHandle(hRelationship)
384 9 : ->SetLeftMappingTableFields(cpl::ToVector(papszFields));
385 9 : }
386 :
387 : /************************************************************************/
388 : /* GDALRelationshipSetRightMappingTableFields() */
389 : /************************************************************************/
390 :
391 : /**
392 : * \brief Sets the names of the mapping table fields which correspond to the
393 : * participating fields from the right table in the relationship.
394 : *
395 : * This function is the same as the C++ method
396 : * GDALRelationship::SetRightMappingTableFields().
397 : *
398 : * @param hRelationship handle to the relationship to apply the right table
399 : * fields to.
400 : * @param papszFields the names of the fields.
401 : *
402 : * @see GDALRelationshipGetRightMappingTableFields
403 : * @see GDALRelationshipSetLeftMappingTableFields
404 : */
405 9 : void GDALRelationshipSetRightMappingTableFields(GDALRelationshipH hRelationship,
406 : CSLConstList papszFields)
407 : {
408 : GDALRelationship::FromHandle(hRelationship)
409 9 : ->SetRightMappingTableFields(cpl::ToVector(papszFields));
410 9 : }
411 :
412 : /************************************************************************/
413 : /* GDALRelationshipGetType() */
414 : /************************************************************************/
415 :
416 : /**
417 : * \brief Get the type of the relationship.
418 : *
419 : * This function is the same as the C++ method
420 : * GDALRelationship::GetType().
421 : *
422 : * @return relationship type.
423 : *
424 : * @see GDALRelationshipSetType
425 : */
426 47 : GDALRelationshipType GDALRelationshipGetType(GDALRelationshipH hRelationship)
427 : {
428 47 : return GDALRelationship::FromHandle(hRelationship)->GetType();
429 : }
430 :
431 : /************************************************************************/
432 : /* GDALRelationshipSetType() */
433 : /************************************************************************/
434 :
435 : /**
436 : * \brief Sets the type of the relationship.
437 : *
438 : * This function is the same as the C++ method
439 : * GDALRelationship::SetType().
440 : *
441 : * @see GDALRelationshipGetType
442 : */
443 10 : void GDALRelationshipSetType(GDALRelationshipH hRelationship,
444 : GDALRelationshipType eType)
445 : {
446 10 : return GDALRelationship::FromHandle(hRelationship)->SetType(eType);
447 : }
448 :
449 : /************************************************************************/
450 : /* GDALRelationshipGetForwardPathLabel() */
451 : /************************************************************************/
452 :
453 : /**
454 : * \brief Get the label of the forward path for the relationship.
455 : *
456 : * This function is the same as the C++ method
457 : * GDALRelationship::GetForwardPathLabel().
458 : *
459 : * The forward and backward path labels are free-form, user-friendly strings
460 : * which can be used to generate descriptions of the relationship between
461 : * features from the right and left tables.
462 : *
463 : * E.g. when the left table contains buildings and the right table contains
464 : * furniture, the forward path label could be "contains" and the backward path
465 : * label could be "is located within". A client could then generate a
466 : * user friendly description string such as "fire hose 1234 is located within
467 : * building 15a".
468 : *
469 : * @return forward path label
470 : *
471 : * @see GDALRelationshipSetForwardPathLabel()
472 : * @see GDALRelationshipGetBackwardPathLabel()
473 : */
474 14 : const char *GDALRelationshipGetForwardPathLabel(GDALRelationshipH hRelationship)
475 : {
476 14 : VALIDATE_POINTER1(hRelationship, "GDALRelationshipGetForwardPathLabel",
477 : nullptr);
478 :
479 : return GDALRelationship::FromHandle(hRelationship)
480 14 : ->GetForwardPathLabel()
481 14 : .c_str();
482 : }
483 :
484 : /************************************************************************/
485 : /* GDALRelationshipSetForwardPathLabel() */
486 : /************************************************************************/
487 : /**
488 : * \brief Sets the label of the forward path for the relationship.
489 : *
490 : * This function is the same as the CPP method
491 : * GDALRelationship::SetForwardPathLabel().
492 : *
493 : * The forward and backward path labels are free-form, user-friendly strings
494 : * which can be used to generate descriptions of the relationship between
495 : * features from the right and left tables.
496 : *
497 : * E.g. when the left table contains buildings and the right table contains
498 : * furniture, the forward path label could be "contains" and the backward path
499 : * label could be "is located within". A client could then generate a
500 : * user friendly description string such as "fire hose 1234 is located within
501 : * building 15a".
502 : *
503 : * @param hRelationship handle to the relationship to apply the new label to.
504 : * @param pszLabel the label to set.
505 : *
506 : * @see GDALRelationshipGetForwardPathLabel
507 : * @see GDALRelationshipSetBackwardPathLabel
508 : */
509 9 : void GDALRelationshipSetForwardPathLabel(GDALRelationshipH hRelationship,
510 : const char *pszLabel)
511 :
512 : {
513 9 : GDALRelationship::FromHandle(hRelationship)->SetForwardPathLabel(pszLabel);
514 9 : }
515 :
516 : /************************************************************************/
517 : /* GDALRelationshipGetForwardPathLabel() */
518 : /************************************************************************/
519 :
520 : /**
521 : * \brief Get the label of the backward path for the relationship.
522 : *
523 : * This function is the same as the C++ method
524 : * GDALRelationship::GetBackwardPathLabel().
525 : *
526 : * The forward and backward path labels are free-form, user-friendly strings
527 : * which can be used to generate descriptions of the relationship between
528 : * features from the right and left tables.
529 : *
530 : * E.g. when the left table contains buildings and the right table contains
531 : * furniture, the forward path label could be "contains" and the backward path
532 : * label could be "is located within". A client could then generate a
533 : * user friendly description string such as "fire hose 1234 is located within
534 : * building 15a".
535 : *
536 : * @return backward path label
537 : *
538 : * @see GDALRelationshipSetBackwardPathLabel()
539 : * @see GDALRelationshipGetForwardPathLabel()
540 : */
541 : const char *
542 14 : GDALRelationshipGetBackwardPathLabel(GDALRelationshipH hRelationship)
543 : {
544 14 : VALIDATE_POINTER1(hRelationship, "GDALRelationshipGetBackwardPathLabel",
545 : nullptr);
546 :
547 : return GDALRelationship::FromHandle(hRelationship)
548 14 : ->GetBackwardPathLabel()
549 14 : .c_str();
550 : }
551 :
552 : /************************************************************************/
553 : /* GDALRelationshipSetBackwardPathLabel() */
554 : /************************************************************************/
555 : /**
556 : * \brief Sets the label of the backward path for the relationship.
557 : *
558 : * This function is the same as the CPP method
559 : * GDALRelationship::SetBackwardPathLabel().
560 : *
561 : * The forward and backward path labels are free-form, user-friendly strings
562 : * which can be used to generate descriptions of the relationship between
563 : * features from the right and left tables.
564 : *
565 : * E.g. when the left table contains buildings and the right table contains
566 : * furniture, the forward path label could be "contains" and the backward path
567 : * label could be "is located within". A client could then generate a
568 : * user friendly description string such as "fire hose 1234 is located within
569 : * building 15a".
570 : *
571 : * @param hRelationship handle to the relationship to apply the new label to.
572 : * @param pszLabel the label to set.
573 : *
574 : * @see GDALRelationshipGetBackwardPathLabel
575 : * @see GDALRelationshipSetForwardPathLabel
576 : */
577 9 : void GDALRelationshipSetBackwardPathLabel(GDALRelationshipH hRelationship,
578 : const char *pszLabel)
579 : {
580 9 : GDALRelationship::FromHandle(hRelationship)->SetBackwardPathLabel(pszLabel);
581 9 : }
582 :
583 : /************************************************************************/
584 : /* GDALRelationshipGetRelatedTableType() */
585 : /************************************************************************/
586 :
587 : /**
588 : * \brief Get the type string of the related table.
589 : *
590 : * This function is the same as the C++ method
591 : * GDALRelationship::GetRelatedTableType().
592 : *
593 : * This a free-form string representing the type of related features, where the
594 : * exact interpretation is format dependent. For instance, table types from
595 : * GeoPackage relationships will directly reflect the categories from the
596 : * GeoPackage related tables extension (i.e. "media", "simple attributes",
597 : * "features", "attributes" and "tiles").
598 : *
599 : * @return related table type
600 : *
601 : * @see GDALRelationshipSetRelatedTableType
602 : */
603 44 : const char *GDALRelationshipGetRelatedTableType(GDALRelationshipH hRelationship)
604 : {
605 44 : VALIDATE_POINTER1(hRelationship, "GDALRelationshipGetRelatedTableType",
606 : nullptr);
607 :
608 : return GDALRelationship::FromHandle(hRelationship)
609 44 : ->GetRelatedTableType()
610 44 : .c_str();
611 : }
612 :
613 : /************************************************************************/
614 : /* GDALRelationshipSetRelatedTableType() */
615 : /************************************************************************/
616 : /**
617 : * \brief Sets the type string of the related table.
618 : *
619 : * This function is the same as the CPP method
620 : * GDALRelationship::SetRelatedTableType().
621 : *
622 : * This a free-form string representing the type of related features, where the
623 : * exact interpretation is format dependent. For instance, table types from
624 : * GeoPackage relationships will directly reflect the categories from the
625 : * GeoPackage related tables extension (i.e. "media", "simple attributes",
626 : * "features", "attributes" and "tiles").
627 : *
628 : * @param hRelationship handle to the relationship to apply the new type to.
629 : * @param pszType the type to set.
630 : *
631 : * @see GDALRelationshipGetRelatedTableType
632 : */
633 20 : void GDALRelationshipSetRelatedTableType(GDALRelationshipH hRelationship,
634 : const char *pszType)
635 : {
636 20 : GDALRelationship::FromHandle(hRelationship)->SetRelatedTableType(pszType);
637 20 : }
|