Skip to content

Commit

Permalink
multiple case and fix viur
Browse files Browse the repository at this point in the history
  • Loading branch information
sveneberth committed Jan 23, 2025
1 parent c2c4af3 commit 680e006
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 12 deletions.
30 changes: 18 additions & 12 deletions src/viur/core/bones/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
import hashlib
import inspect
import logging
from dataclasses import dataclass, field
from datetime import datetime, timedelta
import typing as t
from collections.abc import Iterable
from dataclasses import dataclass, field
from datetime import timedelta
from enum import Enum
import typing as t
from viur.core import db, utils, i18n

from viur.core import db, i18n, utils
from viur.core.config import conf

if t.TYPE_CHECKING:
Expand Down Expand Up @@ -388,7 +389,7 @@ def __setattr__(self, key, value):
assignment.
"""
if not self.isClonedInstance and getSystemInitialized() and key != "isClonedInstance" and not key.startswith(
"_"):
"_"):

Check failure on line 392 in src/viur/core/bones/base.py

View workflow job for this annotation

GitHub Actions / linter (3.12)

E125: continuation line with same indent as next logical line
raise AttributeError("You cannot modify this Skeleton. Grab a copy using .clone() first")
super().__setattr__(key, value)

Expand Down Expand Up @@ -1013,24 +1014,28 @@ def buildDBSort(self,
dbFilter.order(order)
return dbFilter

def _hashValueForUniquePropertyIndex(self, value: str | int) -> list[str]:
def _hashValueForUniquePropertyIndex(
self,
value: str | int | float | db.Key | list[str | int | float | db.Key],
) -> list[str]:
"""
Generates a hash of the given value for creating unique property indexes.
This method is called by the framework to create a consistent hash representation of a value
for constructing unique property indexes. Derived bone classes should overwrite this method to
implement their own logic for hashing values.
:param value: The value to be hashed, which can be a string, integer, or a float.
:param value: The value(s) to be hashed.
:return: A list containing a string representation of the hashed value. If the bone is multiple,
the list may contain more than one hashed value.
"""
def hashValue(value: str | int) -> str:

def hashValue(value: str | int | float | db.Key) -> str:
h = hashlib.sha256()
h.update(str(value).encode("UTF-8"))
res = h.hexdigest()
if isinstance(value, int) or isinstance(value, float):
if isinstance(value, int | float):
return f"I-{res}"
elif isinstance(value, str):
return f"S-{res}"
Expand All @@ -1047,9 +1052,9 @@ def keyHash(key):

if not value and not self.unique.lockEmpty:
return [] # We are zero/empty string and these should not be locked
if not self.multiple:
if not self.multiple and not isinstance(value, list):
return [hashValue(value)]
# We have an multiple bone here
# We have a multiple bone or multiple values here
if not isinstance(value, list):
value = [value]
tmpList = [hashValue(x) for x in value]
Expand Down Expand Up @@ -1268,7 +1273,8 @@ def _compute(self, skel: 'viur.core.skeleton.SkeletonInstance', bone_name: str):
compute_fn_parameters = inspect.signature(self.compute.fn).parameters
compute_fn_args = {}
if "skel" in compute_fn_parameters:
from viur.core.skeleton import skeletonByKind, RefSkel # noqa: E402 # import works only here because circular imports
from viur.core.skeleton import skeletonByKind, \
RefSkel # noqa: E402 # import works only here because circular imports

if issubclass(skel.skeletonCls, RefSkel): # we have a ref skel we must load the complete skeleton
cloned_skel = skeletonByKind(skel.kindName)()
Expand Down
2 changes: 2 additions & 0 deletions src/viur/core/bones/string.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,8 @@ def getUniquePropertyIndexValues(self, skel: "SkeletonInstance", name: str) -> l
raise NotImplementedError()

if not self.caseSensitive and (val := skel[name]) is not None:
if self.multiple:
val = [v.lower() for v in val]
return self._hashValueForUniquePropertyIndex(val.lower())

return super().getUniquePropertyIndexValues(skel, name)
Expand Down

0 comments on commit 680e006

Please sign in to comment.