LCOV - code coverage report
Current view: top level - frmts/tiledb - tiledbmultidimattributeholder.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 72 111 64.9 %
Date: 2024-05-13 13:33:37 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL TileDB Driver
       4             :  * Purpose:  Implement GDAL TileDB multidimensional support based on https://www.tiledb.io
       5             :  * Author:   TileDB, Inc
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2023, TileDB, Inc
       9             :  *
      10             :  * Permission is hereby granted, free of charge, to any person obtaining a
      11             :  * copy of this software and associated documentation files (the "Software"),
      12             :  * to deal in the Software without restriction, including without limitation
      13             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      14             :  * and/or sell copies of the Software, and to permit persons to whom the
      15             :  * Software is furnished to do so, subject to the following conditions:
      16             :  *
      17             :  * The above copyright notice and this permission notice shall be included
      18             :  * in all copies or substantial portions of the Software.
      19             :  *
      20             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      21             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      22             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      23             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      24             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      25             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      26             :  * DEALINGS IN THE SOFTWARE.
      27             :  ****************************************************************************/
      28             : 
      29             : #include "tiledbmultidim.h"
      30             : 
      31             : /************************************************************************/
      32             : /*           TileDBAttributeHolder::~TileDBAttributeHolder()            */
      33             : /************************************************************************/
      34             : 
      35             : TileDBAttributeHolder::~TileDBAttributeHolder() = default;
      36             : 
      37             : /************************************************************************/
      38             : /*             TileDBAttributeHolder::CreateAttributeImpl()             */
      39             : /************************************************************************/
      40             : 
      41          17 : std::shared_ptr<GDALAttribute> TileDBAttributeHolder::CreateAttributeImpl(
      42             :     const std::string &osName, const std::vector<GUInt64> &anDimensions,
      43             :     const GDALExtendedDataType &oDataType, CSLConstList /*papszOptions*/)
      44             : {
      45          17 :     if (!IIsWritable())
      46             :     {
      47           2 :         CPLError(CE_Failure, CPLE_NotSupported,
      48             :                  "Dataset not open in update mode");
      49           2 :         return nullptr;
      50             :     }
      51             : 
      52          15 :     if (!EnsureOpenAs(TILEDB_READ))
      53           0 :         return nullptr;
      54             :     try
      55             :     {
      56             :         tiledb_datatype_t value_type;
      57          30 :         if (m_oMapAttributes.find(osName) != m_oMapAttributes.end() ||
      58          15 :             has_metadata(osName, &value_type))
      59             :         {
      60           0 :             CPLError(CE_Failure, CPLE_AppDefined,
      61             :                      "An attribute with same name already exists");
      62           0 :             return nullptr;
      63             :         }
      64             :     }
      65           0 :     catch (const std::exception &e)
      66             :     {
      67           0 :         CPLError(CE_Failure, CPLE_AppDefined, "has_metadata() failed with: %s",
      68           0 :                  e.what());
      69           0 :         return nullptr;
      70             :     }
      71          15 :     if (!EnsureOpenAs(TILEDB_WRITE))
      72           0 :         return nullptr;
      73             : 
      74          15 :     auto poAttr = TileDBAttribute::Create(AsAttributeHolderSharedPtr(), osName,
      75          30 :                                           anDimensions, oDataType);
      76          15 :     if (poAttr)
      77          15 :         m_oMapAttributes[osName] = poAttr;
      78          15 :     return poAttr;
      79             : }
      80             : 
      81             : /************************************************************************/
      82             : /*                TileDBAttributeHolder::CreateAttribute()              */
      83             : /************************************************************************/
      84             : 
      85             : /* static */ std::shared_ptr<GDALAttribute>
      86          58 : TileDBAttributeHolder::CreateAttribute(
      87             :     const std::shared_ptr<TileDBAttributeHolder> &poSelf,
      88             :     const std::string &osName, tiledb_datatype_t value_type, uint32_t value_num,
      89             :     const void *value)
      90             : {
      91          76 :     if (value_type == TILEDB_STRING_ASCII || value_type == TILEDB_STRING_UTF8 ||
      92          18 :         (osName == "_gdal" && value_type == TILEDB_UINT8 && value &&
      93           0 :          CPLIsUTF8(static_cast<const char *>(value), value_num)))
      94             :     {
      95             :         return TileDBAttribute::Create(poSelf, osName, {},
      96          40 :                                        GDALExtendedDataType::CreateString());
      97             :     }
      98             :     else
      99             :     {
     100             :         GDALDataType eDT =
     101          18 :             TileDBArray::TileDBDataTypeToGDALDataType(value_type);
     102          18 :         if (eDT == GDT_Unknown)
     103             :         {
     104           0 :             const char *pszTypeName = "";
     105           0 :             tiledb_datatype_to_str(value_type, &pszTypeName);
     106           0 :             CPLDebug("TILEDB",
     107             :                      "Metadata item %s ignored because of unsupported "
     108             :                      "type %s",
     109             :                      osName.c_str(), pszTypeName);
     110             :         }
     111             :         else
     112             :         {
     113          18 :             return TileDBAttribute::Create(poSelf, osName, {value_num},
     114          18 :                                            GDALExtendedDataType::Create(eDT));
     115             :         }
     116             :     }
     117           0 :     return nullptr;
     118             : }
     119             : 
     120             : /************************************************************************/
     121             : /*                TileDBAttributeHolder::GetAttributeImpl()             */
     122             : /************************************************************************/
     123             : 
     124             : std::shared_ptr<GDALAttribute>
     125          43 : TileDBAttributeHolder::GetAttributeImpl(const std::string &osName) const
     126             : {
     127          43 :     if (!EnsureOpenAs(TILEDB_READ))
     128           0 :         return nullptr;
     129             : 
     130          43 :     auto oIter = m_oMapAttributes.find(osName);
     131          43 :     if (oIter != m_oMapAttributes.end())
     132           7 :         return oIter->second;
     133             : 
     134             :     try
     135             :     {
     136             :         tiledb_datatype_t value_type;
     137             :         uint32_t value_num;
     138             :         const void *value;
     139          36 :         get_metadata(osName, &value_type, &value_num, &value);
     140          36 :         if (value == nullptr)
     141          26 :             return nullptr;
     142             : 
     143           0 :         auto poAttr = CreateAttribute(AsAttributeHolderSharedPtr(), osName,
     144          20 :                                       value_type, value_num, value);
     145          10 :         if (poAttr)
     146             :         {
     147          10 :             m_oMapAttributes[osName] = poAttr;
     148             :         }
     149          10 :         return poAttr;
     150             :     }
     151           0 :     catch (const std::exception &e)
     152             :     {
     153           0 :         CPLError(CE_Failure, CPLE_AppDefined, "GetAttribute() failed with: %s",
     154           0 :                  e.what());
     155           0 :         return nullptr;
     156             :     }
     157             : }
     158             : 
     159             : /************************************************************************/
     160             : /*                       IsSpecialAttribute()                           */
     161             : /************************************************************************/
     162             : 
     163          48 : static bool IsSpecialAttribute(const std::string &osName)
     164             : {
     165         138 :     return osName == CRS_ATTRIBUTE_NAME || osName == UNIT_ATTRIBUTE_NAME ||
     166          84 :            osName == DIM_TYPE_ATTRIBUTE_NAME ||
     167         138 :            osName == DIM_DIRECTION_ATTRIBUTE_NAME ||
     168          90 :            osName == GDAL_ATTRIBUTE_NAME;
     169             : }
     170             : 
     171             : /************************************************************************/
     172             : /*                TileDBAttributeHolder::GetAttributesImpl()            */
     173             : /************************************************************************/
     174             : 
     175             : std::vector<std::shared_ptr<GDALAttribute>>
     176          44 : TileDBAttributeHolder::GetAttributesImpl(CSLConstList papszOptions) const
     177             : {
     178          44 :     if (!EnsureOpenAs(TILEDB_READ))
     179           0 :         return {};
     180             : 
     181             :     const bool bShowAll =
     182          44 :         CPLTestBool(CSLFetchNameValueDef(papszOptions, "SHOW_ALL", "NO"));
     183             : 
     184             :     try
     185             :     {
     186          88 :         std::vector<std::shared_ptr<GDALAttribute>> apoAttributes;
     187          44 :         const uint64_t nAttributes = metadata_num();
     188          88 :         auto poSelf = AsAttributeHolderSharedPtr();
     189          98 :         for (uint64_t i = 0; i < nAttributes; ++i)
     190             :         {
     191         108 :             std::string key;
     192             :             tiledb_datatype_t value_type;
     193             :             uint32_t value_num;
     194             :             const void *value;
     195          54 :             get_metadata_from_index(i, &key, &value_type, &value_num, &value);
     196          54 :             if (bShowAll || !IsSpecialAttribute(key))
     197             :             {
     198             :                 auto poAttr =
     199          96 :                     CreateAttribute(poSelf, key, value_type, value_num, value);
     200          48 :                 if (poAttr)
     201             :                 {
     202          48 :                     apoAttributes.emplace_back(std::move(poAttr));
     203          48 :                     m_oMapAttributes[key] = apoAttributes.back();
     204             :                 }
     205             :             }
     206             :         }
     207          44 :         return apoAttributes;
     208             :     }
     209           0 :     catch (const std::exception &e)
     210             :     {
     211           0 :         CPLError(CE_Failure, CPLE_AppDefined, "GetAttributes() failed with: %s",
     212           0 :                  e.what());
     213           0 :         return {};
     214             :     }
     215             : }
     216             : 
     217             : /************************************************************************/
     218             : /*             TileDBAttributeHolder::DeleteAttributeImpl()             */
     219             : /************************************************************************/
     220             : 
     221           3 : bool TileDBAttributeHolder::DeleteAttributeImpl(const std::string &osName,
     222             :                                                 CSLConstList /*papszOptions*/)
     223             : {
     224           3 :     if (!IIsWritable())
     225             :     {
     226           1 :         CPLError(CE_Failure, CPLE_NotSupported,
     227             :                  "Dataset not open in update mode");
     228           1 :         return false;
     229             :     }
     230             : 
     231           2 :     if (!EnsureOpenAs(TILEDB_WRITE))
     232           0 :         return false;
     233             : 
     234           2 :     auto oIter = m_oMapAttributes.find(osName);
     235             : 
     236             :     try
     237             :     {
     238           2 :         delete_metadata(osName);
     239             : 
     240           2 :         if (oIter != m_oMapAttributes.end())
     241             :         {
     242           1 :             oIter->second->Deleted();
     243           1 :             m_oMapAttributes.erase(oIter);
     244             :         }
     245           2 :         return true;
     246             :     }
     247           0 :     catch (const std::exception &e)
     248             :     {
     249           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     250           0 :                  "DeleteAttribute() failed with: %s", e.what());
     251           0 :         return false;
     252             :     }
     253             : }
     254             : 
     255             : /************************************************************************/
     256             : /*                TileDBAttributeHolder::GetMetadata()                  */
     257             : /************************************************************************/
     258             : 
     259          32 : bool TileDBAttributeHolder::GetMetadata(const std::string &key,
     260             :                                         tiledb_datatype_t *value_type,
     261             :                                         uint32_t *value_num,
     262             :                                         const void **value) const
     263             : {
     264          32 :     if (!EnsureOpenAs(TILEDB_READ))
     265           0 :         return false;
     266             :     try
     267             :     {
     268          32 :         get_metadata(key, value_type, value_num, value);
     269          32 :         return *value != nullptr;
     270             :     }
     271           0 :     catch (const std::exception &e)
     272             :     {
     273           0 :         CPLError(CE_Failure, CPLE_AppDefined, "GetMetadata() failed with: %s",
     274           0 :                  e.what());
     275           0 :         return false;
     276             :     }
     277             : }
     278             : 
     279             : /************************************************************************/
     280             : /*                TileDBAttributeHolder::PutMetadata()                  */
     281             : /************************************************************************/
     282             : 
     283          13 : bool TileDBAttributeHolder::PutMetadata(const std::string &key,
     284             :                                         tiledb_datatype_t value_type,
     285             :                                         uint32_t value_num, const void *value)
     286             : {
     287          13 :     if (!EnsureOpenAs(TILEDB_WRITE))
     288           0 :         return false;
     289             :     try
     290             :     {
     291          13 :         put_metadata(key, value_type, value_num, value);
     292          13 :         return true;
     293             :     }
     294           0 :     catch (const std::exception &e)
     295             :     {
     296           0 :         CPLError(CE_Failure, CPLE_AppDefined, "PutMetadata() failed with: %s",
     297           0 :                  e.what());
     298           0 :         return false;
     299             :     }
     300             : }

Generated by: LCOV version 1.14