|
28 | 28 |
|
29 | 29 | from . import ATTR_NAME |
30 | 30 | from .converters.axes import Axes, AxesMapper |
| 31 | +from .types import DataProtocol |
31 | 32 | from .version import version_tuple |
32 | 33 |
|
33 | 34 | SUPPORTED_PROTOCOLS = ("s3://", "gcs://", "azure://") |
@@ -71,6 +72,53 @@ def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None: |
71 | 72 | self.w_group.close() |
72 | 73 | self.m_group.close() |
73 | 74 |
|
| 75 | + def data_protocol(self, uri: str) -> DataProtocol: |
| 76 | + """Return the data protocol in use for this URI and context. |
| 77 | +
|
| 78 | + Return value will be a data model identifier. Currently one of: |
| 79 | + * `tiledbv2` - the legacy data model, supported on all storage platforms except Carrara |
| 80 | + * `tiledbv3` - the new, and currently Carrara-specific, data model. |
| 81 | +
|
| 82 | + Args: |
| 83 | + uri: |
| 84 | + An object URI |
| 85 | +
|
| 86 | + Returns: |
| 87 | + The protocol identifier, currently one of `tiledbv2` or `tiledbv3` |
| 88 | + --- |
| 89 | +
|
| 90 | + IMPORTANT: the API signature may change slightly in the near future |
| 91 | + to align with TileDB-Py. |
| 92 | +
|
| 93 | + In addition, the implementation will evolve to use a new Core API. |
| 94 | + """ |
| 95 | + if not uri.startswith("tiledb://"): |
| 96 | + return "tiledbv2" |
| 97 | + |
| 98 | + # The original, absolute-only, URIs had the format: |
| 99 | + # tiledb://ORG/UUID |
| 100 | + # The new URIs are: |
| 101 | + # tiledb://WORKSPACE/TEAMSPACE/optional-path-elements/ |
| 102 | + # The current methodology to distinguish between these is to look at the run-time |
| 103 | + # environment, and determine if we are running on Cloud or Carrara. |
| 104 | + # |
| 105 | + # NB: this method will change shortly to use a new Core API. |
| 106 | + |
| 107 | + CLOUD_DEPLOYMENTS = {"https://api.carrara.com", "https://api.staging.tiledb.io"} |
| 108 | + if self._ctx: |
| 109 | + if self._ctx.config()["rest.server_address"] in CLOUD_DEPLOYMENTS: |
| 110 | + return "tiledbv3" |
| 111 | + |
| 112 | + return "tiledbv2" |
| 113 | + |
| 114 | + def is_tiledbv2_uri(self, uri: str) -> bool: |
| 115 | + """Return True if the URI will use `tiledbv2` semantics.""" |
| 116 | + return self.data_protocol(uri) == "tiledbv2" |
| 117 | + |
| 118 | + def is_tiledbv3_uri(self, uri: str) -> bool: |
| 119 | + """Return True if the URI will use `tiledbv3` semantics.""" |
| 120 | + return self.data_protocol(uri) == "tiledbv3" |
| 121 | + |
74 | 122 | def get_or_create(self, name: str, schema: tiledb.ArraySchema) -> Tuple[str, bool]: |
75 | 123 | create = False |
76 | 124 | if name in self.r_group: |
@@ -100,10 +148,15 @@ def get_or_create(self, name: str, schema: tiledb.ArraySchema) -> Tuple[str, boo |
100 | 148 | # (to allow the add operation) |
101 | 149 | self.w_group.close() |
102 | 150 | self.w_group.open("w") |
103 | | - # register the uri with the given name |
104 | | - if self._is_cloud: |
| 151 | + if self.is_tiledbv3_uri(uri): |
| 152 | + self.w_group.add(uri, name=uri, relative=True) |
| 153 | + |
| 154 | + # In tiledbv3 mode, the array is created with the uri==name and relative=True and registered to the group as a member with the given name from the uri. |
| 155 | + # so we don't need to add it to the group manually. |
| 156 | + if self.is_tiledbv2_uri(uri): |
| 157 | + # register the uri with the given name |
105 | 158 | self.w_group.add(uri, name, relative=False) |
106 | | - else: |
| 159 | + if not self._is_cloud: |
107 | 160 | self.w_group.add(name, name, relative=True) |
108 | 161 | return uri, create |
109 | 162 |
|
|
0 commit comments