mirror of
https://github.com/apache/superset.git
synced 2026-05-12 19:35:17 +00:00
feat: add permalink to dashboard and explore (#19078)
* rename key_value to temporary_cache * add migration * create new key_value package * add commands * lots of new stuff * fix schema reference * remove redundant filter state from bootstrap data * add missing license headers * fix pylint * fix dashboard permalink access * use valid json mocks for filter state tests * fix temporary cache tests * add anchors to dashboard state * lint * fix util test * fix url shortlink button tests * remove legacy shortner * remove unused imports * fix js tests * fix test * add native filter state to anchor link * add UPDATING.md section * address comments * address comments * lint * fix test * add utils tests + other test stubs * add key_value integration tests * add filter box state to permalink state * fully support persisting url parameters * lint, add redirects and a few integration tests * fix test + clean up trailing comma * fix anchor bug * change value to LargeBinary to support persisting binary values * fix urlParams type and simplify urlencode * lint * add optional entry expiration * fix incorrect chart id + add test
This commit is contained in:
@@ -14,28 +14,62 @@
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import logging
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Optional
|
||||
|
||||
import logging
|
||||
import pickle
|
||||
from datetime import datetime
|
||||
from typing import Any, Optional
|
||||
|
||||
from flask_appbuilder.security.sqla.models import User
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
from superset import db
|
||||
from superset.commands.base import BaseCommand
|
||||
from superset.key_value.commands.exceptions import KeyValueUpdateFailedError
|
||||
from superset.key_value.commands.parameters import CommandParameters
|
||||
from superset.key_value.exceptions import KeyValueUpdateFailedError
|
||||
from superset.key_value.models import KeyValueEntry
|
||||
from superset.key_value.types import KeyType
|
||||
from superset.key_value.utils import extract_key, get_filter
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class UpdateKeyValueCommand(BaseCommand, ABC):
|
||||
class UpdateKeyValueCommand(BaseCommand):
|
||||
actor: User
|
||||
resource: str
|
||||
value: Any
|
||||
key: str
|
||||
key_type: KeyType
|
||||
expires_on: Optional[datetime]
|
||||
|
||||
def __init__(
|
||||
self, cmd_params: CommandParameters,
|
||||
self,
|
||||
actor: User,
|
||||
resource: str,
|
||||
key: str,
|
||||
value: Any,
|
||||
key_type: KeyType = "uuid",
|
||||
expires_on: Optional[datetime] = None,
|
||||
):
|
||||
self._parameters = cmd_params
|
||||
"""
|
||||
Update a key value entry
|
||||
|
||||
:param resource: the resource (dashboard, chart etc)
|
||||
:param key: the key to update
|
||||
:param value: the value to persist in the key-value store
|
||||
:param key_type: the type of the key to update
|
||||
:param expires_on: entry expiration time
|
||||
:return: the key associated with the updated value
|
||||
"""
|
||||
self.actor = actor
|
||||
self.resource = resource
|
||||
self.key = key
|
||||
self.value = value
|
||||
self.key_type = key_type
|
||||
self.expires_on = expires_on
|
||||
|
||||
def run(self) -> Optional[str]:
|
||||
try:
|
||||
return self.update(self._parameters)
|
||||
return self.update()
|
||||
except SQLAlchemyError as ex:
|
||||
logger.exception("Error running update command")
|
||||
raise KeyValueUpdateFailedError() from ex
|
||||
@@ -43,6 +77,20 @@ class UpdateKeyValueCommand(BaseCommand, ABC):
|
||||
def validate(self) -> None:
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def update(self, cmd_params: CommandParameters) -> Optional[str]:
|
||||
...
|
||||
def update(self) -> Optional[str]:
|
||||
filter_ = get_filter(self.resource, self.key, self.key_type)
|
||||
entry: KeyValueEntry = (
|
||||
db.session.query(KeyValueEntry)
|
||||
.filter_by(**filter_)
|
||||
.autoflush(False)
|
||||
.first()
|
||||
)
|
||||
if entry:
|
||||
entry.value = pickle.dumps(self.value)
|
||||
entry.expires_on = self.expires_on
|
||||
entry.changed_on = datetime.now()
|
||||
entry.changed_by_fk = None if self.actor.is_anonymous else self.actor.id
|
||||
db.session.merge(entry)
|
||||
db.session.commit()
|
||||
return extract_key(entry, self.key_type)
|
||||
return None
|
||||
|
||||
Reference in New Issue
Block a user